[BACK]Return to alloc.c CVS log [TXT][DIR] Up to [local] / sys / lib / libsa

Annotation of sys/lib/libsa/alloc.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: alloc.c,v 1.9 2003/08/11 06:23:09 deraadt Exp $       */
                      2: /*     $NetBSD: alloc.c,v 1.6 1997/02/04 18:36:33 thorpej Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (c) 1997 Christopher G. Demetriou.  All rights reserved.
                      6:  * Copyright (c) 1996
                      7:  *     Matthias Drochner.  All rights reserved.
                      8:  * Copyright (c) 1993
                      9:  *     The Regents of the University of California.  All rights reserved.
                     10:  *
                     11:  * This code is derived from software contributed to Berkeley by
                     12:  * The Mach Operating System project at Carnegie-Mellon University.
                     13:  *
                     14:  * Redistribution and use in source and binary forms, with or without
                     15:  * modification, are permitted provided that the following conditions
                     16:  * are met:
                     17:  * 1. Redistributions of source code must retain the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer.
                     19:  * 2. Redistributions in binary form must reproduce the above copyright
                     20:  *    notice, this list of conditions and the following disclaimer in the
                     21:  *    documentation and/or other materials provided with the distribution.
                     22:  * 3. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  *
                     38:  *     @(#)alloc.c     8.1 (Berkeley) 6/11/93
                     39:  *
                     40:  *
                     41:  * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
                     42:  * All Rights Reserved.
                     43:  *
                     44:  * Author: Alessandro Forin
                     45:  *
                     46:  * Permission to use, copy, modify and distribute this software and its
                     47:  * documentation is hereby granted, provided that both the copyright
                     48:  * notice and this permission notice appear in all copies of the
                     49:  * software, derivative works or modified versions, and any portions
                     50:  * thereof, and that both notices appear in supporting documentation.
                     51:  *
                     52:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     53:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     54:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     55:  *
                     56:  * Carnegie Mellon requests users of this software to return to
                     57:  *
                     58:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     59:  *  School of Computer Science
                     60:  *  Carnegie Mellon University
                     61:  *  Pittsburgh PA 15213-3890
                     62:  *
                     63:  * any improvements or extensions that they make and grant Carnegie the
                     64:  * rights to redistribute these changes.
                     65:  */
                     66:
                     67: /*
                     68:  * Dynamic memory allocator.
                     69:  *
                     70:  * Compile options:
                     71:  *
                     72:  *     ALLOC_TRACE     enable tracing of allocations/deallocations
                     73:  *
                     74:  *     ALLOC_FIRST_FIT use a first-fit allocation algorithm, rather than
                     75:  *                     the default best-fit algorithm.
                     76:  *
                     77:  *     HEAP_LIMIT      heap limit address (defaults to "no limit").
                     78:  *
                     79:  *     HEAP_START      start address of heap (defaults to '&end').
                     80:  *
                     81:  *     DEBUG           enable debugging sanity checks.
                     82:  */
                     83:
                     84: #include <sys/param.h>
                     85:
                     86: /*
                     87:  * Each block actually has ALIGN(unsigned) + ALIGN(size) bytes allocated
                     88:  * to it, as follows:
                     89:  *
                     90:  * 0 ... (sizeof(unsigned) - 1)
                     91:  *     allocated or unallocated: holds size of user-data part of block.
                     92:  *
                     93:  * sizeof(unsigned) ... (ALIGN(sizeof(unsigned)) - 1)
                     94:  *     allocated: unused
                     95:  *     unallocated: depends on packing of struct fl
                     96:  *
                     97:  * ALIGN(sizeof(unsigned)) ... (ALIGN(sizeof(unsigned)) + ALIGN(data size) - 1)
                     98:  *     allocated: user data
                     99:  *     unallocated: depends on packing of struct fl
                    100:  *
                    101:  * 'next' is only used when the block is unallocated (i.e. on the free list).
                    102:  * However, note that ALIGN(sizeof(unsigned)) + ALIGN(data size) must
                    103:  * be at least 'sizeof(struct fl)', so that blocks can be used as structures
                    104:  * when on the free list.
                    105:  */
                    106:
                    107: #include "stand.h"
                    108:
                    109: struct fl {
                    110:        unsigned        size;
                    111:        struct fl       *next;
                    112: } *freelist = (struct fl *)0;
                    113:
                    114: #ifdef HEAP_START
                    115: static char *top = (char *)HEAP_START;
                    116: #else
                    117: extern char end[];
                    118: static char *top = end;
                    119: #endif
                    120:
                    121: void *
                    122: alloc(unsigned int size)
                    123: {
                    124:        struct fl **f = &freelist, **bestf = NULL;
                    125: #ifndef ALLOC_FIRST_FIT
                    126:        unsigned bestsize = 0xffffffff; /* greater than any real size */
                    127: #endif
                    128:        char *help;
                    129:        int failed;
                    130:
                    131: #ifdef ALLOC_TRACE
                    132:        printf("alloc(%u)", size);
                    133: #endif
                    134:
                    135: #ifdef ALLOC_FIRST_FIT
                    136:        while (*f != (struct fl *)0 && (*f)->size < size)
                    137:                f = &((*f)->next);
                    138:        bestf = f;
                    139:        failed = (*bestf == (struct fl *)0);
                    140: #else
                    141:        /* scan freelist */
                    142:        while (*f) {
                    143:                if ((*f)->size >= size) {
                    144:                        if ((*f)->size == size) /* exact match */
                    145:                                goto found;
                    146:
                    147:                        if ((*f)->size < bestsize) {
                    148:                                /* keep best fit */
                    149:                                bestf = f;
                    150:                                bestsize = (*f)->size;
                    151:                        }
                    152:                }
                    153:                f = &((*f)->next);
                    154:        }
                    155:
                    156:        /* no match in freelist if bestsize unchanged */
                    157:        failed = (bestsize == 0xffffffff);
                    158: #endif
                    159:
                    160:        if (failed) { /* nothing found */
                    161:                /*
                    162:                 * allocate from heap, keep chunk len in
                    163:                 * first word
                    164:                 */
                    165:                help = top;
                    166:
                    167:                /* make _sure_ the region can hold a struct fl. */
                    168:                if (size < ALIGN(sizeof (struct fl *)))
                    169:                        size = ALIGN(sizeof (struct fl *));
                    170:                top += ALIGN(sizeof(unsigned)) + ALIGN(size);
                    171: #ifdef HEAP_LIMIT
                    172:                if (top > (char *)HEAP_LIMIT)
                    173:                        panic("heap full (0x%lx+%u)", help, size);
                    174: #endif
                    175:                *(unsigned *)help = ALIGN(size);
                    176: #ifdef ALLOC_TRACE
                    177:                printf("=%p\n", help + ALIGN(sizeof(unsigned)));
                    178: #endif
                    179:                return(help + ALIGN(sizeof(unsigned)));
                    180:        }
                    181:
                    182:        /* we take the best fit */
                    183:        f = bestf;
                    184:
                    185: #ifndef ALLOC_FIRST_FIT
                    186: found:
                    187: #endif
                    188:        /* remove from freelist */
                    189:        help = (char *)*f;
                    190:        *f = (*f)->next;
                    191: #ifdef ALLOC_TRACE
                    192:        printf("=%p (origsize %u)\n", help + ALIGN(sizeof(unsigned)),
                    193:            *(unsigned *)help);
                    194: #endif
                    195:        return(help + ALIGN(sizeof(unsigned)));
                    196: }
                    197:
                    198: void
                    199: free(void *ptr, unsigned int size)
                    200: {
                    201:        struct fl *f = (struct fl *)((char *)ptr -
                    202:            ALIGN(sizeof(unsigned)));
                    203:
                    204: #ifdef ALLOC_TRACE
                    205:        printf("free(%p, %u) (origsize %u)\n", ptr, size, f->size);
                    206: #endif
                    207: #ifdef DEBUG
                    208:        if (size > f->size)
                    209:                printf("free %u bytes @%p, should be <=%u\n",
                    210:                    size, ptr, f->size);
                    211: #ifdef HEAP_START
                    212:        if (ptr < (void *)HEAP_START)
                    213: #else
                    214:        if (ptr < (void *)end)
                    215: #endif
                    216:                printf("free: %lx before start of heap.\n", (u_long)ptr);
                    217:
                    218: #ifdef HEAP_LIMIT
                    219:        if (ptr > (void *)HEAP_LIMIT)
                    220:                printf("free: %lx beyond end of heap.\n", (u_long)ptr);
                    221: #endif
                    222: #endif /* DEBUG */
                    223:        /* put into freelist */
                    224:        f->next = freelist;
                    225:        freelist = f;
                    226: }

CVSweb