da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
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***********************************************************************/
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerstatic char* Version = "\n@(#)$Id: Vmalloc (AT&T Research) 2010-01-01 $\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 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 { /* 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 */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(less > 0 && size > (size_t)less && (size-(size_t)less) < sizeof(Block_t) )
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner less = (size_t)less <= vd->incr ? 0 : (size_t)less - vd->incr;
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 */