|
|
1.1 ! root 1: #include "sam.h" ! 2: /* ! 3: * Allocator. Manages arena between initial bss and garbage-compacted ! 4: * arena. Uses shiftgcarena() when it needs to expand its dominion. ! 5: */ ! 6: ! 7: #define BRKINCR 4096 ! 8: #define LBRKINCR (BRKINCR/sizeof(long)) ! 9: ! 10: #define FREE 1 ! 11: typedef struct hdr{ ! 12: union{ ! 13: long *Unext; /* pointer to next object */ ! 14: long Uinext; /* integer next; odd if deallocated */ ! 15: }uu; ! 16: long nlongs; ! 17: }hdr; ! 18: #define inext uu.Uinext ! 19: #define next uu.Unext ! 20: #define hp ((struct hdr *)p) ! 21: ! 22: #define HEADERSIZE (sizeof(struct hdr)/sizeof(long)) ! 23: ! 24: static long *basep; /* beginning of arena; only set once */ ! 25: static long *endp; /* end of arena */ ! 26: static long *nextp; /* next one to be used */ ! 27: ! 28: allocinit(){ ! 29: basep=(long *)sbrk(0); ! 30: if(brk((char *)(basep+LBRKINCR))!=0) ! 31: error(Ealloc); ! 32: nextp=basep; ! 33: endp=basep+LBRKINCR; ! 34: } ! 35: uchar * ! 36: alloc(nbytes) ! 37: register ulong nbytes; ! 38: { ! 39: register long *p, *q; ! 40: register ulong nl; ! 41: nbytes+=sizeof(long)-1; ! 42: nbytes/=sizeof(long); /* convert bytes to longs */ ! 43: #define Nlongs nbytes ! 44: Nlongs+=HEADERSIZE; ! 45: /* look for exact match */ ! 46: for(p=basep; p<nextp; p=(long *)(hp->inext&~FREE)) ! 47: if((hp->inext&FREE) && hp->nlongs==Nlongs){ ! 48: hp->inext&=~FREE; ! 49: goto Return; ! 50: } ! 51: /* try off the end */ ! 52: if(endp-nextp < Nlongs){ ! 53: nl=(nextp+Nlongs)-basep; /* number we need */ ! 54: nl=((nl+LBRKINCR-1)/LBRKINCR)*LBRKINCR; /* rounded up */ ! 55: nl-=(endp-basep); /* minus number we have */ ! 56: if((int)sbrk((int)(nl*sizeof(long)))==-1) ! 57: error(Ealloc); ! 58: shiftgcarena(nl); ! 59: endp+=nl; ! 60: } ! 61: p=nextp; ! 62: nextp+=Nlongs; ! 63: hp->nlongs=Nlongs; ! 64: hp->next=nextp; ! 65: Return: ! 66: for(q=p+HEADERSIZE, Nlongs-=HEADERSIZE; Nlongs-->0; ) ! 67: *q++=0; ! 68: return (uchar *)(p+HEADERSIZE); ! 69: } ! 70: free(cp) ! 71: uchar *cp; ! 72: { ! 73: register long *p=(long *)cp; ! 74: if(p<=basep || nextp<=p) ! 75: panic("free"); ! 76: p-=HEADERSIZE; ! 77: hp->inext|=FREE; ! 78: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.