Annotation of OSKit-Mach/kern/kalloc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University.
                      4:  * Copyright (c) 1993,1994 The University of Utah and
                      5:  * the Computer Systems Laboratory (CSL).
                      6:  * All rights reserved.
                      7:  *
                      8:  * Permission to use, copy, modify and distribute this software and its
                      9:  * documentation is hereby granted, provided that both the copyright
                     10:  * notice and this permission notice appear in all copies of the
                     11:  * software, derivative works or modified versions, and any portions
                     12:  * thereof, and that both notices appear in supporting documentation.
                     13:  *
                     14:  * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
                     15:  * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
                     16:  * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
                     17:  * THIS SOFTWARE.
                     18:  *
                     19:  * Carnegie Mellon requests users of this software to return to
                     20:  *
                     21:  *  Software Distribution Coordinator  or  [email protected]
                     22:  *  School of Computer Science
                     23:  *  Carnegie Mellon University
                     24:  *  Pittsburgh PA 15213-3890
                     25:  *
                     26:  * any improvements or extensions that they make and grant Carnegie Mellon
                     27:  * the rights to redistribute these changes.
                     28:  */
                     29: /*
                     30:  *     File:   kern/kalloc.c
                     31:  *     Author: Avadis Tevanian, Jr.
                     32:  *     Date:   1985
                     33:  *
                     34:  *     General kernel memory allocator.  This allocator is designed
                     35:  *     to be used by the kernel to manage dynamic memory fast.
                     36:  */
                     37: 
                     38: #include <mach/machine/vm_types.h>
                     39: #include <mach/vm_param.h>
                     40: 
                     41: #include <kern/zalloc.h>
                     42: #include <kern/kalloc.h>
                     43: #include <vm/vm_kern.h>
                     44: #include <vm/vm_object.h>
                     45: #include <vm/vm_map.h>
                     46: 
                     47: 
                     48: 
                     49: vm_map_t kalloc_map;
                     50: vm_size_t kalloc_map_size = 8 * 1024 * 1024;
                     51: vm_size_t kalloc_max;
                     52: 
                     53: /*
                     54:  *     All allocations of size less than kalloc_max are rounded to the
                     55:  *     next highest power of 2.  This allocator is built on top of
                     56:  *     the zone allocator.  A zone is created for each potential size
                     57:  *     that we are willing to get in small blocks.
                     58:  *
                     59:  *     We assume that kalloc_max is not greater than 64K;
                     60:  *     thus 16 is a safe array size for k_zone and k_zone_name.
                     61:  */
                     62: 
                     63: int first_k_zone = -1;
                     64: struct zone *k_zone[16];
                     65: static char *k_zone_name[16] = {
                     66:        "kalloc.1",             "kalloc.2",
                     67:        "kalloc.4",             "kalloc.8",
                     68:        "kalloc.16",            "kalloc.32",
                     69:        "kalloc.64",            "kalloc.128",
                     70:        "kalloc.256",           "kalloc.512",
                     71:        "kalloc.1024",          "kalloc.2048",
                     72:        "kalloc.4096",          "kalloc.8192",
                     73:        "kalloc.16384",         "kalloc.32768"
                     74: };
                     75: 
                     76: /*
                     77:  *  Max number of elements per zone.  zinit rounds things up correctly
                     78:  *  Doing things this way permits each zone to have a different maximum size
                     79:  *  based on need, rather than just guessing; it also
                     80:  *  means its patchable in case you're wrong!
                     81:  */
                     82: unsigned long k_zone_max[16] = {
                     83:       1024,            /*      1 Byte  */
                     84:       1024,            /*      2 Byte  */
                     85:       1024,            /*      4 Byte  */
                     86:       1024,            /*      8 Byte  */
                     87:       1024,            /*     16 Byte  */
                     88:       4096,            /*     32 Byte  */
                     89:       4096,            /*     64 Byte  */
                     90:       4096,            /*    128 Byte  */
                     91:       4096,            /*    256 Byte  */
                     92:       1024,            /*    512 Byte  */
                     93:       1024,            /*   1024 Byte  */
                     94:       1024,            /*   2048 Byte  */
                     95:       1024,            /*   4096 Byte  */
                     96:       4096,            /*   8192 Byte  */
                     97:       64,              /*  16384 Byte  */
                     98:       64,              /*  32768 Byte  */
                     99: };
                    100: 
                    101: /*
                    102:  *     Initialize the memory allocator.  This should be called only
                    103:  *     once on a system wide basis (i.e. first processor to get here
                    104:  *     does the initialization).
                    105:  *
                    106:  *     This initializes all of the zones.
                    107:  */
                    108: 
                    109: #include <oskit/x86/debug_reg.h>
                    110: 
                    111: void kalloc_init()
                    112: {
                    113:        vm_offset_t min, max;
                    114:        vm_size_t size;
                    115:        register int i;
                    116: 
                    117:        kalloc_map = kmem_suballoc(kernel_map, &min, &max,
                    118:                                   kalloc_map_size, FALSE);
                    119: 
                    120:        /*
                    121:         *      Ensure that zones up to size 8192 bytes exist.
                    122:         *      This is desirable because messages are allocated
                    123:         *      with kalloc, and messages up through size 8192 are common.
                    124:         */
                    125: 
                    126:        if (PAGE_SIZE < 16*1024)
                    127:                kalloc_max = 16*1024;
                    128:        else
                    129:                kalloc_max = PAGE_SIZE;
                    130: 
                    131:        /*
                    132:         *      Allocate a zone for each size we are going to handle.
                    133:         *      We specify non-paged memory.
                    134:         */
                    135:        for (i = 0, size = 1; size < kalloc_max; i++, size <<= 1) {
                    136:                if (size < MINSIZE) {
                    137:                        k_zone[i] = 0;
                    138:                        continue;
                    139:                }
                    140:                if (size == MINSIZE) {
                    141:                        first_k_zone = i;
                    142:                }
                    143:                k_zone[i] = zinit(size, k_zone_max[i] * size, size,
                    144:                                  size >= PAGE_SIZE ? ZONE_COLLECTABLE : 0,
                    145:                                  k_zone_name[i]);
                    146:        }
                    147: }
                    148: 
                    149: vm_offset_t kalloc(size)
                    150:        vm_size_t size;
                    151: {
                    152:        register int zindex;
                    153:        register vm_size_t allocsize;
                    154:        vm_offset_t addr;
                    155: 
                    156:        /* compute the size of the block that we will actually allocate */
                    157: 
                    158:        allocsize = size;
                    159:        if (size < kalloc_max) {
                    160:                allocsize = MINSIZE;
                    161:                zindex = first_k_zone;
                    162:                while (allocsize < size) {
                    163:                        allocsize <<= 1;
                    164:                        zindex++;
                    165:                }
                    166:        }
                    167: 
                    168:        /*
                    169:         * If our size is still small enough, check the queue for that size
                    170:         * and allocate.
                    171:         */
                    172: 
                    173:        if (allocsize < kalloc_max) {
                    174:                addr = zalloc(k_zone[zindex]);
                    175:        } else {
                    176:                if (kmem_alloc_wired(kalloc_map, &addr, allocsize)
                    177:                                                        != KERN_SUCCESS)
                    178:                        addr = 0;
                    179:        }
                    180:        return(addr);
                    181: }
                    182: 
                    183: vm_offset_t kget(size)
                    184:        vm_size_t size;
                    185: {
                    186:        register int zindex;
                    187:        register vm_size_t allocsize;
                    188:        vm_offset_t addr;
                    189: 
                    190:        /* compute the size of the block that we will actually allocate */
                    191: 
                    192:        allocsize = size;
                    193:        if (size < kalloc_max) {
                    194:                allocsize = MINSIZE;
                    195:                zindex = first_k_zone;
                    196:                while (allocsize < size) {
                    197:                        allocsize <<= 1;
                    198:                        zindex++;
                    199:                }
                    200:        }
                    201: 
                    202:        /*
                    203:         * If our size is still small enough, check the queue for that size
                    204:         * and allocate.
                    205:         */
                    206: 
                    207:        if (allocsize < kalloc_max) {
                    208:                addr = zget(k_zone[zindex]);
                    209:        } else {
                    210:                /* This will never work, so we might as well panic */
                    211:                panic("kget");
                    212:        }
                    213:        return(addr);
                    214: }
                    215: 
                    216: void
                    217: kfree(data, size)
                    218:        vm_offset_t data;
                    219:        vm_size_t size;
                    220: {
                    221:        register int zindex;
                    222:        register vm_size_t freesize;
                    223: 
                    224:        freesize = size;
                    225:        if (size < kalloc_max) {
                    226:                freesize = MINSIZE;
                    227:                zindex = first_k_zone;
                    228:                while (freesize < size) {
                    229:                        freesize <<= 1;
                    230:                        zindex++;
                    231:                }
                    232:        }
                    233: 
                    234:        if (freesize < kalloc_max) {
                    235:                zfree(k_zone[zindex], data);
                    236:        } else {
                    237:                kmem_free(kalloc_map, data, freesize);
                    238:        }
                    239: }

unix.superglobalmegacorp.com

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