da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
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* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(_UWIN) && defined(_BLD_ast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid _STUB_vmpool(){}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "vmhdr.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define POOLFREE 0x55555555L /* block free indicator */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Method for pool allocation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** All elements in a pool have the same size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** The following fields of Vmdata_t are used as:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** pool: size of a block.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** free: list of free blocks.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin**
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* poolalloc(Vmalloc_t* vm, reg size_t size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* poolalloc(vm, size )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinreg size_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmdata_t* vd = vm->data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Block_t *tp, *next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg size_t s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Seg_t* seg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin reg int local, inuse;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(size != vd->pool)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(vd->pool <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vd->pool = size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SETINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(local = vd->mode&VM_TRUST) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { GETLOCAL(vd,local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ISLOCK(vd, local))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin { CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SETLOCK(vd, local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tp = vd->free) ) /* there is a ready free block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { vd->free = SEGLINK(tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = ROUND(size,ALIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* look thru all segments for a suitable free block */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(tp = NIL(Block_t*), seg = vd->seg; seg; seg = seg->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((tp = seg->free) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (s = (SIZE(tp) & ~BITS) + sizeof(Head_t)) >= size )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto has_blk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;;) /* must extend region */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((tp = (*_Vmextend)(vm,ROUND(size,vd->incr),NIL(Vmsearch_f))) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { s = (SIZE(tp) & ~BITS) + sizeof(Head_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin seg = SEG(tp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto has_blk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(vd->mode&VM_AGAIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vd->mode &= ~VM_AGAIN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhas_blk: /* if get here, (tp, s, seg) must be well-defined */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = (Block_t*)((Vmuchar_t*)tp+size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((s -= size) <= (size + sizeof(Head_t)) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { for(; s >= size; s -= size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { SIZE(next) = POOLFREE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SEGLINK(next) = vd->free;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vd->free = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = (Block_t*)((Vmuchar_t*)next + size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin seg->free = NIL(Block_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { SIZE(next) = s - sizeof(Head_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SEG(next) = seg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin seg->free = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!local && (vd->mode&VM_TRACE) && _Vmtrace && tp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)tp,vd->pool,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CLRLOCK(vd, local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ANNOUNCE(local, vm, VM_ALLOC, (Void_t*)tp, vm->disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (Void_t*)tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic long pooladdr(Vmalloc_t* vm, reg Void_t* addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic long pooladdr(vm, addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinreg Void_t* addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Block_t *bp, *tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmuchar_t *laddr, *baddr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg size_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Seg_t* seg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg long offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmdata_t* vd = vm->data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin reg int local, inuse;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SETINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(local = vd->mode&VM_TRUST))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { GETLOCAL(vd,local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ISLOCK(vd,local))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin { CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1L;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SETLOCK(vd,local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = -1L;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(seg = vd->seg; seg; seg = seg->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { laddr = (Vmuchar_t*)SEGBLOCK(seg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin baddr = seg->baddr-sizeof(Head_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((Vmuchar_t*)addr < laddr || (Vmuchar_t*)addr >= baddr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* the block that has this address */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = ROUND(vd->pool,ALIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = (Block_t*)(laddr + (((Vmuchar_t*)addr-laddr)/size)*size );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if this block has been freed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(SIZE(tp) == POOLFREE) /* may be a coincidence - make sure */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(bp = vd->free; bp; bp = SEGLINK(bp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bp == tp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset = (Vmuchar_t*)addr - (Vmuchar_t*)tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone :
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CLRLOCK(vd,local);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int poolfree(reg Vmalloc_t* vm, reg Void_t* data )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int poolfree(vm, data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinreg Vmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinreg Void_t* data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Block_t* bp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmdata_t* vd = vm->data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin reg int local, inuse;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SETINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(local = vd->mode&VM_TRUST))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { GETLOCAL(vd, local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ISLOCK(vd, local) || vd->pool <= 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin { CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(KPVADDR(vm,data,pooladdr) != 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(vm->disc->exceptf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SETLOCK(vd, local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = (Block_t*)data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SIZE(bp) = POOLFREE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SEGLINK(bp) = vd->free;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vd->free = bp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm, (Vmuchar_t*)data, NIL(Vmuchar_t*), vd->pool, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CLRLOCK(vd,local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ANNOUNCE(local, vm, VM_FREE, data, vm->disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* poolresize(Vmalloc_t* vm, Void_t* data, size_t size, int type )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* poolresize(vm, data, size, type )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int local, inuse;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmdata_t* vd = vm->data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOTUSED(type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SETINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((data = poolalloc(vm,size)) && (type&VM_RSZERO) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { reg int *d = (int*)data, *ed = (int*)((char*)data+size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do { *d++ = 0;} while(d < ed);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { (void)poolfree(vm,data);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(local = vd->mode&VM_TRUST) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { GETLOCAL(vd, local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ISLOCK(vd, local) )
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin { CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size != vd->pool || KPVADDR(vm,data,pooladdr) != 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(vm->disc->exceptf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)(*vm->disc->exceptf)(vm,VM_BADADDR,data,vm->disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((vd->mode&VM_TRACE) && _Vmtrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm, (Vmuchar_t*)data, (Vmuchar_t*)data, size, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ANNOUNCE(local, vm, VM_RESIZE, data, vm->disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic long poolsize(Vmalloc_t* vm, Void_t* addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic long poolsize(vm, addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return pooladdr(vm,addr) == 0 ? (long)vm->data->pool : -1L;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int poolcompact(Vmalloc_t* vm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int poolcompact(vm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Block_t* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Seg_t *seg, *next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg size_t s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Vmdata_t* vd = vm->data;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin reg int inuse;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SETINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(vd->mode&VM_TRUST))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(ISLOCK(vd,0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin { CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SETLOCK(vd,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(seg = vd->seg; seg; seg = next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { next = seg->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(fp = seg->free))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin seg->free = NIL(Block_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(seg->size == (s = SIZE(fp)&~BITS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = seg->extent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else s += sizeof(Head_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((*_Vmtruncate)(vm,seg,s,1) == s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin seg->free = fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((vd->mode&VM_TRACE) && _Vmtrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*_Vmtrace)(vm, (Vmuchar_t*)0, (Vmuchar_t*)0, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin CLRLOCK(vd,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin CLRINUSE(vd, inuse);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* poolalign(Vmalloc_t* vm, size_t size, size_t align)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Void_t* poolalign(vm, size, align)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVmalloc_t* vm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t align;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOTUSED(vm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOTUSED(size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOTUSED(align);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return NIL(Void_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Public interface */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Vmethod_t _Vmpool =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poolalloc,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poolresize,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poolfree,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pooladdr,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poolsize,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poolcompact,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin poolalign,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin VM_MTPOOL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin__DEFINE__(Vmethod_t*,Vmpool,&_Vmpool);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef NoF
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNoF(vmpool)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif