Annotation of coherent/a/usr/bob/korn/alloc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * area-based allocation built on malloc/free
                      3:  */
                      4: 
                      5: static char *RCSid = "$Header";
                      6: 
                      7: #include <stddef.h>
                      8: #include <stdlib.h>
                      9: #include <setjmp.h>
                     10: #include "sh.h"
                     11: 
                     12: #define        ICELLS  100             /* number of Cells in small Block */
                     13: 
                     14: typedef union Cell Cell;
                     15: typedef struct Block Block;
                     16: 
                     17: /*
                     18:  * The Cells in a Block are organized as a set of objects.
                     19:  * Each object (pointed to by dp) begins with a size in (dp-1)->size,
                     20:  * followed with "size" data Cells.  Free objects are
                     21:  * linked together via dp->next.
                     22:  */
                     23: 
                     24: union Cell {
                     25:        size_t  size;
                     26:        Cell   *next;
                     27:        struct {int _;} junk;   /* alignment */
                     28: };
                     29: 
                     30: struct Block {
                     31:        Block  *next;           /* list of Blocks in Area */
                     32:        Cell   *free;           /* object free list */
                     33:        Cell   *last;           /* &b.cell[size] */
                     34:        Cell    cell [1];       /* [size] Cells for allocation */
                     35: };
                     36: 
                     37: Block aempty = {&aempty, aempty.cell, aempty.cell};
                     38: 
                     39: /* create empty Area */
                     40: Area *
                     41: ainit(ap)
                     42:        register Area *ap;
                     43: {
                     44:        ap->free = &aempty;
                     45:        return ap;
                     46: }
                     47: 
                     48: /* free all object in Area */
                     49: void
                     50: afreeall(ap)
                     51:        register Area *ap;
                     52: {
                     53:        register Block *bp;
                     54: 
                     55:        if (ap->free == NULL || ap->free == &aempty)
                     56:                return;
                     57:        for (bp = ap->free; ; bp = bp->next) {
                     58:                free((Void*)bp);
                     59:                if (bp->next == ap->free)
                     60:                        break;
                     61:        }
                     62:        ap->free = &aempty;
                     63: }
                     64: 
                     65: /* allocate object from Area */
                     66: Void *
                     67: alloc(size, ap)
                     68:        size_t size;
                     69:        register Area *ap;
                     70: {
                     71:        int cells, split;
                     72:        register Block *bp;
                     73:        register Cell *dp, *fp, *fpp;
                     74: #if 0
                     75:        mypr("alloc: size %d area x%x\n", size, ap);
                     76: #endif
                     77:        if (size <= 0) {
                     78:                aerror(ap, "allocate bad size");
                     79:                return NULL;
                     80:        }
                     81:        cells = (unsigned)(size - 1) / sizeof(Cell) + 1;
                     82: 
                     83:        /* find Cell large enough */
                     84:        for (bp = ap->free; ; bp = bp->next) {
                     85:                for (fpp = NULL, fp = bp->free;
                     86:                     fp != bp->last; fpp = fp, fp = fpp->next)
                     87:                        if ((fp-1)->size >= cells)
                     88:                                goto Found;
                     89: 
                     90:                /* wrapped around Block list, create new Block */
                     91:                if (bp == ap->free) {
                     92:                        bp = malloc(offsetof(Block, cell[ICELLS + cells]));
                     93:                        if (bp == NULL) {
                     94:                                aerror(ap, "cannot allocate");
                     95:                                return NULL;
                     96:                        }
                     97:                        if (ap->free == &aempty)
                     98:                                bp->next = bp;
                     99:                        else {
                    100:                                bp->next = ap->free->next;
                    101:                                ap->free->next = bp;
                    102:                        }
                    103:                        bp->last = bp->cell + ICELLS + cells;
                    104:                        fp = bp->free = bp->cell + 1; /* initial free list */
                    105:                        (fp-1)->size = ICELLS + cells - 1;
                    106:                        fp->next = bp->last;
                    107:                        fpp = NULL;
                    108:                        break;
                    109:                }
                    110:        }
                    111:   Found:
                    112:        ap->free = bp;
                    113:        dp = fp;                /* allocated object */
                    114:        split = (dp-1)->size - cells;
                    115:        if (split < 0)
                    116:                aerror(ap, "allocated object too small");
                    117:        if (--split <= 0) {     /* allocate all */
                    118:                fp = fp->next;
                    119:        } else {                /* allocate head, free tail */
                    120:                (fp-1)->size = cells;
                    121:                fp += cells + 1;
                    122:                (fp-1)->size = split;
                    123:                fp->next = dp->next;
                    124:        }
                    125:        if (fpp == NULL)
                    126:                bp->free = fp;
                    127:        else
                    128:                fpp->next = fp;
                    129:        return (Void*) dp;
                    130: }
                    131: 
                    132: /* change size of object */
                    133: /* todo: allow expansion */
                    134: Void *
                    135: aresize(ptr, size, ap)
                    136:        register Void *ptr;
                    137:        size_t size;
                    138:        register Area *ap;
                    139: {
                    140:        int cells, split;
                    141:        register Cell *dp = (Cell*)ptr;
                    142: 
                    143: #if 0
                    144:        mypr("aresize: size %d area x%x ptr x%x\n", size, ap, ptr);
                    145: #endif
                    146:        if (size <= 0) {
                    147:                aerror(ap, "allocate bad size");
                    148:                return NULL;
                    149:        }
                    150:        cells = (unsigned)(size - 1) / sizeof(Cell) + 1;
                    151: 
                    152:        split = (dp-1)->size - cells;
                    153:        if (split < 0)
                    154:                aerror(ap, "cannot resize larger");
                    155:        if (--split <= 0)       /* cannot split */
                    156:                ;
                    157:        else {                  /* shrink head, free tail */
                    158:                (dp-1)->size = cells;
                    159:                dp += cells + 1;
                    160:                (dp-1)->size = split;
                    161:                afree((Void*)dp, ap);
                    162:        }
                    163: 
                    164:        return (Void*) ptr;
                    165: }
                    166: 
                    167: void
                    168: afree(ptr, ap)
                    169:        Void *ptr;
                    170:        register Area *ap;
                    171: {
                    172:        register Block *bp;
                    173:        register Cell *fp, *fpp;
                    174:        register Cell *dp = (Cell*)ptr;
                    175: 
                    176: #if 0
                    177:        mypr("afree: area x%x ptr x%x\n", ap, ptr);
                    178: #endif
                    179:        /* find Block containing Cell */
                    180:        for (bp = ap->free; ; bp = bp->next) {
                    181:                if (bp->cell <= dp && dp < bp->last)
                    182:                        break;
                    183:                if (bp->next == ap->free) {
                    184:                        aerror(ap, "freeing with invalid area");
                    185:                        return;
                    186:                }
                    187:        }
                    188: 
                    189:        /* find position in free list */
                    190:        for (fpp = NULL, fp = bp->free; fp < dp; fpp = fp, fp = fpp->next)
                    191:                ;
                    192: 
                    193:        if (fp == dp) {
                    194:                aerror(ap, "freeing free object");
                    195:                return;
                    196:        }
                    197: 
                    198:        /* join object with next */
                    199:        if (dp + (dp-1)->size == fp-1) { /* adjacent */
                    200:                (dp-1)->size += (fp-1)->size + 1;
                    201:                dp->next = fp->next;
                    202:        } else                  /* non-adjacent */
                    203:                dp->next = fp;
                    204: 
                    205:        /* join previous with object */
                    206:        if (fpp == NULL)
                    207:                bp->free = dp;
                    208:        else if (fpp + (fpp-1)->size == dp-1) { /* adjacent */
                    209:                (fpp-1)->size += (dp-1)->size + 1;
                    210:                fpp->next = dp->next;
                    211:        } else                  /* non-adjacent */
                    212:                fpp->next = dp;
                    213: }
                    214: 
                    215: 
                    216: #if TEST_ALLOC
                    217: 
                    218: Area a;
                    219: 
                    220: main(argc, argv)
                    221: int argc;
                    222: char **argv;
                    223: {
                    224:        int i;
                    225:        char *p [9];
                    226: 
                    227:        ainit(&a);
                    228:        for (i = 0; i < 9; i++) {
                    229:                p[i] = alloc(124, &a);
                    230:                printf("alloc: %x\n", p[i]);
                    231:        }
                    232:        for (i = 1; i < argc; i++)
                    233:                afree(p[atoi(argv[i])], &a);
                    234:        afreeall(&a);
                    235:        return 0;
                    236: }
                    237: 
                    238: void aerror(ap, msg)
                    239: Area *ap;
                    240: char *msg;
                    241: {
                    242:        printf("%r\n", &msg);
                    243:        sleep(1);
                    244:        abort();
                    245: }
                    246: 
                    247: #endif
                    248: 

unix.superglobalmegacorp.com

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