vmprivate.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Copyright (c) 1985-2007 AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* by AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* Version = "\n@(#)$Id: Vmalloc (AT&T Research) 2005-09-28 $\0\n";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Private code used in the vmalloc library
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Get more memory for a region */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Block_t* vmextend(reg Vmalloc_t* vm, size_t size, Vmsearch_f searchf )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmuchar_t* addr = (Vmuchar_t*)Version; /* shut compiler warning */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if DEBUG /* trace all allocation calls through the heap */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((env = getenv("VMTRACE")) && (fd = creat(env, CREAT_MODE)) >= 0 ) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vd->incr <= 0) /* this is just _Vmheap on the first call */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Get slightly more for administrative data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = size + sizeof(Seg_t) + sizeof(Block_t) + sizeof(Head_t) + 2*ALIGN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(s <= size) /* size was too large and we have wrapped around */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* increase the rounding factor to reduce # of future extensions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if we can extend the current segment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addr = (Vmuchar_t*)(*memoryf)(vm,seg->addr,seg->extent,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((addr = (Vmuchar_t*)(*memoryf)(vm,NIL(Void_t*),0,size,vm->disc)) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check with exception handler to see if we should continue */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(rv == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* extending current segment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = BLOCK(seg->baddr); /**/ ASSERT((SIZE(bp)&~BITS) == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* creating a new segment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SIZE(bp) = seg->baddr - (Vmuchar_t*)bp - 2*sizeof(Head_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* NOTE: for Vmbest, Vmdebug and Vmprofile the region's segment list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin is reversely ordered by addresses. This is so that we can easily
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin check for the wild block.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make a fake header for possible segmented memory */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if the wild block is still wild */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Truncate a segment if possible */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t vmtruncate(Vmalloc_t* vm, Seg_t* seg, size_t size, int exact)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else /* keep truncated amount to discipline requirements */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(less > 0 && size > less && (size-less) < sizeof(Block_t) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(less <= 0 ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*memoryf)(vm,caddr,seg->extent,seg->extent-less,vm->disc) != caddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* unlink segment from region */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { for(last = vd->seg; last->next != seg; last = last->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* now delete it */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((*memoryf)(vm,caddr,seg->extent,0,vm->disc) == caddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* space reduction failed, reinsert segment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Externally visible names but local to library */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, /* _Vmpagesize */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NIL(char*(*)_ARG_((char*,const char*,int))), /* _Vmstrcpy */