Annotation of 43BSD/contrib/apl/src/aq.c, revision 1.1

1.1     ! root        1: static char Sccsid[] = "aq.c @(#)aq.c  1.1     10/1/82 Berkeley ";
        !             2: /*
        !             3:  *      malloc/free/afreset -- dynamic memory allocation
        !             4:  *
        !             5:  *
        !             6:  * This source file is a slight modificattion of the alloc/free system
        !             7:  * described by Kernighan and Ritchie in "The C Programming Language",
        !             8:  * pp. 174-177.
        !             9:  *
        !            10:  * The modifications include allocation by a bestfit (rather than
        !            11:  * firstfit) strategy, and ability to reset memory completely.
        !            12:  */
        !            13: 
        !            14: /* NOTE: the "afnfree" and "afnused" values are not precise.  They
        !            15:  * do not currently refect the allocation and release of headers.
        !            16:  * This will be changed soon (I hope).
        !            17:  * --J. Bruner
        !            18:  */
        !            19: 
        !            20: 
        !            21: #define NULL    0               /* null value */
        !            22: #ifndef vax
        !            23: #define NALLOC  128             /* # of units requested on each "sbrk" */
        !            24: #else
        !            25: #define        NALLOC  1024            /* lots of memory each time for vaxes */
        !            26: #endif
        !            27: 
        !            28: typedef int     ALIGN;          /* force alignment on PDP-11 and VAX */
        !            29: 
        !            30: union header {                          /* free block header structure */
        !            31:        struct {
        !            32:                union header *ptr;      /* next free block */
        !            33:                unsigned size;          /* size of this free block */
        !            34:        } s;
        !            35:        ALIGN x;                        /* force alignment of blocks */
        !            36: };
        !            37: 
        !            38: 
        !            39: typedef union header HEADER;
        !            40: 
        !            41: 
        !            42: static HEADER base;                     /* empty list to get started */
        !            43: static HEADER *allocp = NULL;           /* last allocated block */
        !            44: 
        !            45: int aftrace = 0;
        !            46: int afnfree, afnused;
        !            47: 
        !            48: 
        !            49: char *
        !            50: malloc(nbytes)
        !            51: unsigned nbytes;
        !            52: {
        !            53:        HEADER *morecore();
        !            54:        register HEADER *p, *q;
        !            55:        register HEADER *rp;
        !            56:        HEADER *rq;
        !            57:        register unsigned nunits;
        !            58: 
        !            59:        /* malloc is a general-purpose memory allocator.  It is called
        !            60:         * with the desired number of bytes, expressed as an unsigned
        !            61:         * integer, and it returns the address of the allocated memory.
        !            62:         * If "aftrace" is non-zero, a trace of the allocation will
        !            63:         * be printed.  If it is not possible to alloate what is
        !            64:         * requested, the error "workspace exceeded" will result.
        !            65:         *
        !            66:         * This routine was originally called "alloc" but was changed
        !            67:         * to "malloc" because an increasing number of library routines
        !            68:         * perform dynamic memory allocation.  A macro in "apl.h"
        !            69:         * converts calls on "alloc" to calls on "malloc".
        !            70:         */
        !            71: 
        !            72:        nunits = 1+(nbytes+sizeof(HEADER)-1)/sizeof(HEADER);
        !            73:        if ((q=allocp) == NULL){
        !            74:                base.s.ptr = allocp = q = &base;        /* start list */
        !            75:                base.s.size = 0;
        !            76:        }
        !            77: 
        !            78: 
        !            79:        /* Search list for smallest free block */
        !            80: 
        !            81:        rp = NULL;
        !            82:        for(p=q->s.ptr;;q=p, p=p->s.ptr){
        !            83:                while(1){
        !            84:                        if (p->s.size >= nunits){
        !            85:                                if ((!rp) || p->s.size < rp->s.size){
        !            86:                                        rp = p;
        !            87:                                        rq = q;
        !            88:                                }
        !            89:                                if (p->s.size == nunits) break;
        !            90:                        }
        !            91: 
        !            92:                        if (p == allocp)
        !            93:                                break;
        !            94: 
        !            95:                        q = p;
        !            96:                        p = p->s.ptr;
        !            97:                }
        !            98: 
        !            99:                if (rp) break;
        !           100:                if ((p=morecore(nunits)) == NULL)
        !           101:                        error("workspace exceeded");
        !           102:        }
        !           103: 
        !           104: 
        !           105: 
        !           106:        /* Allocate memory as needed */
        !           107: 
        !           108:        if (rp->s.size == nunits)
        !           109:                rq->s.ptr = rp->s.ptr;
        !           110:        else {
        !           111:                rp->s.size -= nunits;
        !           112:                rp += rp->s.size;
        !           113:                rp->s.size = nunits;
        !           114:        }
        !           115:        allocp = rq;
        !           116: 
        !           117:        if (aftrace)
        !           118:                printf("[alloc: %d at %o]\n",
        !           119:                        (int)nunits*sizeof(HEADER), rp);
        !           120: 
        !           121:        afnfree -= nunits;
        !           122:        afnused += nunits;
        !           123:        return((char *)(rp+1));
        !           124: }
        !           125: 
        !           126: 
        !           127: static HEADER *
        !           128: morecore(nu)
        !           129: unsigned nu;
        !           130: {
        !           131:        char *sbrk();
        !           132:        register char *cp;
        !           133:        register HEADER *up;
        !           134:        register int rnu;
        !           135: 
        !           136:        /* Ask system for more memory.  Requests are made in blocks
        !           137:         * of NALLOC header units.  Returns NULL if request fails,
        !           138:         * "allocp" on success.
        !           139:         */
        !           140: 
        !           141:        rnu = NALLOC * ((nu+NALLOC-1) / NALLOC);
        !           142:        cp = sbrk(rnu * sizeof(HEADER));
        !           143:        if ((int)cp == -1)
        !           144:                return(NULL);                   /* no more space */
        !           145: 
        !           146:        if (aftrace)
        !           147:                printf("[morecore: %d at %o]\n", rnu*sizeof(HEADER),
        !           148:                        cp);
        !           149: 
        !           150:        up = (HEADER *)cp;
        !           151:        up->s.size = rnu;
        !           152:        free((char *)(up+1));
        !           153:        return(allocp);
        !           154: }
        !           155: 
        !           156: 
        !           157: free(ap)
        !           158: char *ap;
        !           159: {
        !           160:        register HEADER *p, *q;
        !           161:        register unsigned fsize;
        !           162: 
        !           163: 
        !           164:        /* Put block into free list.  Used by "morecore" to put a newly-
        !           165:         * allocated block of memory into the freelist -- also used to
        !           166:         * return a previously allocated block to the freelist.
        !           167:         */
        !           168: 
        !           169:        p = (HEADER *)ap - 1;           /* point to header */
        !           170:        fsize = p->s.size;
        !           171: 
        !           172:        for (q=allocp; !(p > q && p < q->s.ptr); q=q->s.ptr)
        !           173:                if (q >= q->s.ptr && (p > q || p < q->s.ptr))
        !           174:                        break;
        !           175: 
        !           176:        if (p+p->s.size == q->s.ptr){   /* join to upper nbr */
        !           177:                p->s.size += q->s.ptr->s.size;
        !           178:                p->s.ptr = q->s.ptr->s.ptr;
        !           179:        } else
        !           180:                p->s.ptr = q->s.ptr;
        !           181: 
        !           182:        if (q+q->s.size == p){          /* join to lower nbr */
        !           183:                q->s.size += p->s.size;
        !           184:                q->s.ptr = p->s.ptr;
        !           185:        } else
        !           186:                q->s.ptr = p;
        !           187: 
        !           188:        allocp = q;
        !           189: 
        !           190:        afnfree += fsize;
        !           191:        afnused -= fsize;
        !           192:        if (aftrace)
        !           193:                printf("[free: %d at %o]\n", fsize*sizeof(HEADER),  ap);
        !           194: 
        !           195: }
        !           196: 
        !           197: 
        !           198: afreset(){
        !           199: 
        !           200:        extern end;
        !           201: 
        !           202:        /* Zap all dynamic allocation by resettting the lists and
        !           203:         * releasing all additional memory.
        !           204:         */
        !           205: 
        !           206:        allocp = NULL;
        !           207:        brk((char *)&end);
        !           208:        afnfree = afnused = 0;
        !           209:        if (aftrace)
        !           210:                printf("[afreset: dynamic allocation released]\n");
        !           211: 
        !           212: }

unix.superglobalmegacorp.com

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