[BACK]Return to alloc.c CVS log [TXT][DIR] Up to [local] / sys / arch / macppc / stand

Annotation of sys/arch/macppc/stand/alloc.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: alloc.c,v 1.5 2007/05/28 22:17:21 pyr Exp $   */
                      2: /*     $NetBSD: alloc.c,v 1.1 1997/04/16 20:29:16 thorpej Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (c) 1997 Jason R. Thorpe.  All rights reserved.
                      6:  * Copyright (c) 1997 Christopher G. Demetriou.  All rights reserved.
                      7:  * Copyright (c) 1996
                      8:  *     Matthias Drochner.  All rights reserved.
                      9:  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
                     10:  * Copyright (C) 1995, 1996 TooLs GmbH.
                     11:  * All rights reserved.
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. All advertising materials mentioning features or use of this software
                     22:  *    must display the following acknowledgement:
                     23:  *     This product includes software developed by TooLs GmbH.
                     24:  * 4. The name of TooLs GmbH may not be used to endorse or promote products
                     25:  *    derived from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
                     28:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     29:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     30:  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     31:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     32:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     33:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     34:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     35:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     36:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * Dynamic memory allocator suitable for use with OpenFirmware.
                     41:  *
                     42:  * Compile options:
                     43:  *
                     44:  *     ALLOC_TRACE     enable tracing of allocations/deallocations
                     45:  *
                     46:  *     ALLOC_FIRST_FIT use a first-fit allocation algorithm, rather than
                     47:  *                     the default best-fit algorithm.
                     48:  *
                     49:  *     DEBUG           enable debugging sanity checks.
                     50:  */
                     51:
                     52: #include <sys/param.h>
                     53: #include <sys/queue.h>
                     54:
                     55: #include <lib/libsa/stand.h>
                     56:
                     57: #include <macppc/stand/openfirm.h>
                     58:
                     59: /*
                     60:  * Each block actually has ALIGN(struct ml) + ALIGN(size) bytes allocated
                     61:  * to it, as follows:
                     62:  *
                     63:  * 0 ... (sizeof(struct ml) - 1)
                     64:  *     allocated or unallocated: holds size of user-data part of block.
                     65:  *
                     66:  * sizeof(struct ml) ... (ALIGN(sizeof(struct ml)) - 1)
                     67:  *     allocated: unused
                     68:  *     unallocated: depends on packing of struct fl
                     69:  *
                     70:  * ALIGN(sizeof(struct ml)) ... (ALIGN(sizeof(struct ml)) +
                     71:  *   ALIGN(data size) - 1)
                     72:  *     allocated: user data
                     73:  *     unallocated: depends on packing of struct fl
                     74:  *
                     75:  * 'next' is only used when the block is unallocated (i.e. on the free list).
                     76:  * However, note that ALIGN(sizeof(struct ml)) + ALIGN(data size) must
                     77:  * be at least 'sizeof(struct fl)', so that blocks can be used as structures
                     78:  * when on the free list.
                     79:  */
                     80:
                     81: /*
                     82:  * Memory lists.
                     83:  */
                     84: struct ml {
                     85:        unsigned        size;
                     86:        LIST_ENTRY(ml)  list;
                     87: };
                     88:
                     89: /* XXX - this is from NetBSD  */
                     90: #define LIST_HEAD_INITIALIZER(head) { NULL }
                     91:
                     92: LIST_HEAD(, ml) freelist = LIST_HEAD_INITIALIZER(freelist);
                     93: LIST_HEAD(, ml) allocatedlist = LIST_HEAD_INITIALIZER(allocatedlist);
                     94:
                     95: #define        OVERHEAD        ALIGN(sizeof (struct ml))       /* shorthand */
                     96:
                     97: void *
                     98: alloc(unsigned size)
                     99: {
                    100:        struct ml *f, *bestf;
                    101:        unsigned bestsize = 0xffffffff; /* greater than any real size */
                    102:        char *help;
                    103:        int failed;
                    104:
                    105: #ifdef ALLOC_TRACE
                    106:        printf("alloc(%u)", size);
                    107: #endif
                    108:
                    109:        /*
                    110:         * Account for overhead now, so that we don't get an
                    111:         * "exact fit" which doesn't have enough space.
                    112:         */
                    113:        size = ALIGN(size) + OVERHEAD;
                    114:
                    115: #ifdef ALLOC_FIRST_FIT
                    116:        /* scan freelist */
                    117:        LIST_FOREACH(f, &freelist, list)
                    118:                if (f->size >= size)
                    119:                        break;
                    120:        bestf = f;
                    121:        failed = (bestf == (struct fl *)0);
                    122: #else
                    123:        /* scan freelist */
                    124:        LIST_FOREACH(f, &freelist, list) {
                    125:                if (f->size >= size) {
                    126:                        if (f->size == size)    /* exact match */
                    127:                                goto found;
                    128:
                    129:                        if (f->size < bestsize) {
                    130:                                /* keep best fit */
                    131:                                bestf = f;
                    132:                                bestsize = f->size;
                    133:                        }
                    134:                }
                    135:        }
                    136:
                    137:        /* no match in freelist if bestsize unchanged */
                    138:        failed = (bestsize == 0xffffffff);
                    139: #endif
                    140:
                    141:        if (failed) {   /* nothing found */
                    142:                /*
                    143:                 * Allocate memory from the OpenFirmware, rounded
                    144:                 * to page size, and record the chunk size.
                    145:                 */
                    146:                size = roundup(size, NBPG);
                    147:                help = OF_claim(0, size, NBPG);
                    148:                if (help == (char *)-1)
                    149:                        panic("alloc: out of memory");
                    150:
                    151:                f = (struct ml *)help;
                    152:                f->size = size;
                    153: #ifdef ALLOC_TRACE
                    154:                printf("=%lx (new chunk size %u)\n",
                    155:                    (u_long)(help + OVERHEAD), f->size);
                    156: #endif
                    157:                goto out;
                    158:        }
                    159:
                    160:        /* we take the best fit */
                    161:        f = bestf;
                    162:
                    163: found:
                    164:        /* remove from freelist */
                    165:        LIST_REMOVE(f, list);
                    166:        help = (char *)f;
                    167: #ifdef ALLOC_TRACE
                    168:        printf("=%lx (origsize %u)\n", (u_long)(help + OVERHEAD), f->size);
                    169: #endif
                    170: out:
                    171:        /* place on allocated list */
                    172:        LIST_INSERT_HEAD(&allocatedlist, f, list);
                    173:        return (help + OVERHEAD);
                    174: }
                    175:
                    176: void
                    177: free(void *ptr, unsigned size)
                    178: {
                    179:        register struct ml *a = (struct ml *)((char *)ptr - OVERHEAD);
                    180:
                    181: #ifdef ALLOC_TRACE
                    182:        printf("free(%lx, %u) (origsize %u)\n", (u_long)ptr, size, a->size);
                    183: #endif
                    184: #ifdef DEBUG
                    185:        if (size > a->size)
                    186:                printf("free %u bytes @%lx, should be <=%u\n",
                    187:                    size, (u_long)ptr, a->size);
                    188: #endif
                    189:
                    190:        /* Remove from allocated list, place on freelist. */
                    191:        LIST_REMOVE(a, list);
                    192:        LIST_INSERT_HEAD(&freelist, a, list);
                    193: }
                    194:
                    195: void
                    196: freeall()
                    197: {
                    198: #ifdef __notyet__              /* Firmware bug ?! */
                    199:        struct ml *m;
                    200:
                    201:        /* Release chunks on freelist... */
                    202:        while ((m = LIST_FIRST(&freelist)) != NULL) {
                    203:                LIST_REMOVE(m, list);
                    204:                OF_release(m, m->size);
                    205:        }
                    206:
                    207:        /* ...and allocated list. */
                    208:        while ((m = LIST_FIRST(&allocated)) != NULL)) {
                    209:                LIST_REMOVE(m, list);
                    210:                OF_release(m, m->size);
                    211:        }
                    212: #endif /* __notyet__ */
                    213: }

CVSweb