Annotation of researchv9/jtools/src/sam/gcalloc.c, revision 1.1.1.1

1.1       root        1: #include "sam.h"
                      2: /*
                      3:  * Garbage-compacting allocator
                      4:  *
                      5:  * called as:  gcalloc(nbytes, where)
                      6:  *             gcrealloc(p, nbytes)
                      7:  *             gcfree(p)
                      8:  *     nbytes is unsigned long
                      9:  *     where is a pointer to the location which will point to the area
                     10:  *     (e.g. base in a Bitmap), to be updated when necessary.
                     11:  *     The return values  for the allocators are the new address,
                     12:  *     but since they update *where, the value isn't too useful.
                     13:  *     They panic if they fail.
                     14:  */
                     15: 
                     16: /*
                     17:  * The arena is allocated in longs, to speed up compaction
                     18:  * Garbage is compacted towards the bottom (low address end) of the arena.
                     19:  * A block has a struct header as its bottom HEADERSIZE longs for use by gcfree.
                     20:  * header.pval points to the USER location where the pointer to the block
                     21:  * is stored; this cell must be updated after a compaction.
                     22:  * Deallocated blocks have header.pval odd.
                     23:  */
                     24: 
                     25: #define        BRKINCR         (16*1024)       /* bytes to add to arena each time */
                     26: #define LBRKINCR       (BRKINCR/sizeof(long))
                     27: #define        FREE            1
                     28: #define        HEADERSIZE      sizeof(struct header)/sizeof(long)
                     29: 
                     30: static long    *nextlong;
                     31: static long    *startarena;
                     32: static long    *endarena;
                     33: static         compact();
                     34: int            dontcompact;
                     35: 
                     36: extern char    *brk();
                     37: extern char    *sbrk();
                     38: 
                     39: struct header{
                     40:        union uuu{
                     41:                long    Uival;          /* integer value of where */
                     42:                long    **Upval;        /* where */
                     43:        }u;
                     44:        ulong nlongs;                   /* # of longs in the user's data */
                     45: };
                     46: #define        ival    u.Uival
                     47: #define        pval    u.Upval
                     48: #define        hp      ((struct header *)p)
                     49: 
                     50: uchar *
                     51: gcalloc(nbytes, where)
                     52:        register ulong nbytes;
                     53:        long **where;
                     54: {
                     55:        register long *p;
                     56:        register ulong nl;
                     57:        if(nextlong>endarena)
                     58:                panic("nextlong>endarena");
                     59:        if((long)where&FREE)    /* head off a possible disaster */
                     60:                panic("where&FREE");
                     61:        if(startarena==0){
                     62:                if((int)(startarena=(long *)sbrk(BRKINCR))==-1)
                     63:                        error(Ealloc);
                     64:                endarena=startarena+(BRKINCR/sizeof(long));
                     65:                nextlong=startarena;
                     66:        }
                     67:        nbytes+=sizeof(long)-1;
                     68:        nbytes/=sizeof(long);   /* convert bytes to longs */
                     69: #define        Nlongs  nbytes
                     70:        Nlongs+=HEADERSIZE;
                     71:        if(endarena-nextlong < Nlongs){
                     72:                if(!dontcompact)
                     73:                        compact();
                     74:                if(endarena-nextlong < Nlongs){
                     75:                        nl=(nextlong+Nlongs)-startarena;
                     76:                        /* if !compacting, avoid greed */
                     77:                        if(!dontcompact)
                     78:                                nl=((nl+LBRKINCR-1)/LBRKINCR)*LBRKINCR;
                     79:                        if(brk((char *)(startarena+nl))!=0)
                     80:                                error(Ealloc);
                     81:                        endarena=startarena+nl;
                     82:                }
                     83:        }                       
                     84:        p=nextlong;
                     85:        hp->pval=where;
                     86:        hp->nlongs=Nlongs;
                     87:        nextlong+=Nlongs;
                     88:        return (uchar *)(*(hp->pval)=p+HEADERSIZE);
                     89: }
                     90: uchar *
                     91: gcrealloc(cp, nbytes)
                     92:        uchar *cp;
                     93:        register ulong nbytes;
                     94: {
                     95:        register long *p=(long *)cp, *q;
                     96:        register long *newp;
                     97:        register long **ptrold;
                     98:        register n;
                     99:        long *x;
                    100:        p-=HEADERSIZE;  /* the header */
                    101:        n=hp->nlongs;
                    102:        nbytes+=sizeof(long)-1;
                    103:        nbytes/=sizeof(long);   /* convert bytes to longs; nbytes is now Nlongs */
                    104:        ptrold=hp->pval; /* location that will be updated if compaction occurs */
                    105:        /* we give where==x to gcalloc to avoid collision with old header */
                    106:        newp=(long *)gcalloc((ulong)(Nlongs*sizeof(long)), &x);
                    107:        /* now it's safe to have both headers point to the same place */
                    108:        ((struct header *)(newp-HEADERSIZE))->pval=ptrold;
                    109:        p= *ptrold;
                    110:        q=newp;
                    111:        if(n>Nlongs)
                    112:                n=Nlongs;
                    113:        if(n>0) do
                    114:                *q++= *p++;
                    115:        while(--n);
                    116:        (void)gcfree((uchar *)*ptrold);
                    117:        return (uchar *)(*ptrold=newp);
                    118: }
                    119: shiftgcarena(nl)
                    120:        ulong nl;
                    121: {
                    122:        register long *p;
                    123:        if(startarena==0 || dontcompact)
                    124:                return;
                    125:        if(nl<0)
                    126:                panic("shiftgcarena");
                    127:        bcopy((uchar *)startarena, (uchar *)nextlong, (uchar *)(startarena+nl), -1);
                    128:        nextlong+=nl;
                    129:        startarena+=nl;
                    130:        endarena+=nl;
                    131:        for(p=startarena; p<nextlong; p+=hp->nlongs){
                    132:                if((hp->ival&FREE)==0)
                    133:                        *(hp->pval)+=nl;
                    134:        }
                    135: }
                    136: gcfree(cp)
                    137:        uchar *cp;
                    138: {
                    139:        register long *p=(long *)cp;
                    140:        if(p==0)
                    141:                return;
                    142:        p-=HEADERSIZE;
                    143:        if(p<startarena || nextlong<=p)
                    144:                panic("gcfree");
                    145:        hp->ival|=FREE;
                    146: }
                    147: static
                    148: compact()
                    149: {
                    150:        register long *w, *p;
                    151:        register ulong n;
                    152: 
                    153:        w=p=startarena;
                    154:        while(p<nextlong){
                    155:                if(hp->ival&FREE){
                    156:                        p+=hp->nlongs;
                    157:                        continue;
                    158:                }
                    159:                if(w==p){
                    160:                        w+=hp->nlongs;
                    161:                        p+=hp->nlongs;
                    162:                        continue;
                    163:                }
                    164:                *(hp->pval)=w+HEADERSIZE; /* update *where */
                    165:                *w++=hp->ival;
                    166:                *w++=n=hp->nlongs;
                    167:                p+=HEADERSIZE;
                    168:                if((n-=HEADERSIZE)>0) do
                    169:                        *w++ = *p++;
                    170:                while(--n);
                    171:        }
                    172:        nextlong=w;
                    173: }
                    174: gcchk()
                    175: {
                    176:        register long *p;
                    177:        if(startarena==0)
                    178:                return;
                    179:        for(p=startarena; p<nextlong; p+=hp->nlongs)
                    180:                if((hp->ival&FREE)==0){
                    181:                        if(hp->pval==0 || ((long *)hp->pval>=startarena && ((int)(hp->pval)&0x70000000L)==0))
                    182:                                panic("gcchk 1");
                    183:                        if(p+hp->nlongs>nextlong)
                    184:                                panic("gcchk 2");
                    185:                }
                    186: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.