Annotation of kernel/kern/kalloc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  *     File:   kern/kalloc.c
                     52:  *     Author: Avadis Tevanian, Jr.
                     53:  *     Date:   1985
                     54:  *
                     55:  *     General kernel memory allocator.  This allocator is designed
                     56:  *     to be used by the kernel to manage dynamic memory fast.
                     57:  */
                     58: 
                     59: #include <mach/machine/vm_types.h>
                     60: #include <mach/vm_param.h>
                     61: 
                     62: #include <kern/zalloc.h>
                     63: #include <kern/kalloc.h>
                     64: #include <vm/vm_kern.h>
                     65: #include <vm/vm_object.h>
                     66: #include <vm/vm_map.h>
                     67: 
                     68: vm_map_t kalloc_map;
                     69: 
                     70: /*
                     71:  *     All allocations of size less than kalloc_max are rounded to the
                     72:  *     next highest power of 2.  This allocator is built on top of
                     73:  *     the zone allocator.  A zone is created for each potential size
                     74:  *     that we are willing to get in small blocks.
                     75:  *
                     76:  *     We assume that kalloc_max is not greater than 64K;
                     77:  *     thus 16 is a safe array size for k_zone and k_zone_name.
                     78:  */
                     79: 
                     80: #define        NKSIZE  16
                     81: vm_size_t k_zone_maxsize;
                     82: struct zone *k_zone[NKSIZE];
                     83: static char k_zone_name[NKSIZE][16];
                     84: vm_size_t k_zone_elemsize[NKSIZE] = {
                     85:        16, 32, 48, 64, 80, 128, 256, 384, 512,
                     86:        1024, 2048, 3072, 4096, 8192, 12288, 16384
                     87: };
                     88: 
                     89: #if DIAGNOSTIC
                     90: /*
                     91:  * Be careful with ZALLOC0!  It seems that kdp now has a subtle dependency
                     92:  * on allocated memory not being initialized.  If you do use it you'll need
                     93:  * to enter gdb with cmd-Power and even then you may see a "SIGTRAP".
                     94:  */
                     95: #if ZALLOC0
                     96: void    *memset __P((void *, int, size_t));
                     97: #endif
                     98: #endif
                     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: void kalloc_init(void)
                    110: {
                    111:        vm_size_t size;
                    112:        register int i;
                    113:        
                    114:        kalloc_map = kernel_map;
                    115: 
                    116:        /*
                    117:         *      Allocate a zone for each size we are going to handle.
                    118:         *      We specify non-paged memory.
                    119:         */
                    120:        for (i = 0; i < NKSIZE; i++) {
                    121:                if ((size = k_zone_elemsize[i]) >= PAGE_SIZE)
                    122:                        break;
                    123:                sprintf (k_zone_name[i], "kalloc.%d", size);
                    124:                k_zone[i] = zinit(size, 1024*1024, PAGE_SIZE,
                    125:                        FALSE, k_zone_name[i]);
                    126:                k_zone_maxsize = size;
                    127:        }
                    128: }
                    129: 
                    130: vm_offset_t kalloc_noblock(size)
                    131:        vm_size_t size;
                    132: {
                    133:        register int zindex = 0;
                    134:        register vm_size_t allocsize;
                    135:        vm_offset_t addr;
                    136: 
                    137:        /* compute the size of the block that we will actually allocate */
                    138: 
                    139:        allocsize = size;
                    140:        if (size <= k_zone_maxsize) {
                    141:                allocsize = k_zone_elemsize[0];
                    142:                zindex = 0;
                    143:                while (allocsize < size) {
                    144:                        allocsize = k_zone_elemsize[++zindex];
                    145:                }
                    146:        }
                    147: 
                    148:        /*
                    149:         * If our size is still small enough, check the queue for that size
                    150:         * and allocate.
                    151:         */
                    152: 
                    153:        if (allocsize <= k_zone_maxsize) {
                    154:                addr = zalloc_noblock(k_zone[zindex]);
                    155: #if DIAGNOSTIC
                    156: #if ZALLOC0
                    157:                (void) memset((void *)addr, 0, (size_t) size);
                    158: #endif
                    159: #endif
                    160:        } else {
                    161:                if (kmem_alloc_zone(kalloc_map, &addr, allocsize, FALSE)
                    162:                                                            != KERN_SUCCESS)
                    163:                        addr = 0;
                    164:        }
                    165: 
                    166:        return(addr);
                    167: }
                    168: 
                    169: vm_offset_t kalloc(size)
                    170:        vm_size_t size;
                    171: {
                    172:        register int zindex = 0;
                    173:        register vm_size_t allocsize;
                    174:        vm_offset_t addr;
                    175: 
                    176:        /* compute the size of the block that we will actually allocate */
                    177:        allocsize = size;
                    178:        if (size <= k_zone_maxsize) {
                    179:                allocsize = k_zone_elemsize[0];
                    180:                zindex = 0;
                    181:                while (allocsize < size) {
                    182:                        allocsize = k_zone_elemsize[++zindex];
                    183:                }
                    184:        }
                    185: 
                    186:        /*
                    187:         * If our size is still small enough, check the queue for that size
                    188:         * and allocate.
                    189:         */
                    190: 
                    191:        if (allocsize <= k_zone_maxsize) {
                    192:                addr = zalloc(k_zone[zindex]);
                    193: #if DIAGNOSTIC
                    194: #if ZALLOC0
                    195:                (void) memset((void *)addr, 0, (size_t) size);
                    196: #endif
                    197: #endif
                    198:        } else {
                    199:                if (kmem_alloc_wired(kalloc_map, &addr, allocsize)
                    200:                                                        != KERN_SUCCESS)
                    201:                        addr = 0;
                    202:        }
                    203:        return(addr);
                    204: }
                    205: 
                    206: vm_offset_t kget(size)
                    207:        vm_size_t size;
                    208: {
                    209:        register int zindex = 0;
                    210:        register vm_size_t allocsize;
                    211:        vm_offset_t addr = 0;
                    212: 
                    213:        /* compute the size of the block that we will actually allocate */
                    214:        allocsize = size;
                    215:        if (size <= k_zone_maxsize) {
                    216:                allocsize = k_zone_elemsize[0];
                    217:                zindex = 0;
                    218:                while (allocsize < size) {
                    219:                        allocsize = k_zone_elemsize[++zindex];
                    220:                }
                    221:        }
                    222: 
                    223:        /*
                    224:         * If our size is still small enough, check the queue for that size
                    225:         * and allocate.
                    226:         */
                    227: 
                    228:        if (allocsize <= k_zone_maxsize) {
                    229:                addr = zget(k_zone[zindex]);
                    230:        } else {
                    231:                /* This will never work, so we might as well panic */
                    232:                panic("kget");
                    233:        }
                    234:        return(addr);
                    235: }
                    236: 
                    237: void 
                    238: kfree(data, size)
                    239:        vm_offset_t data;
                    240:        vm_size_t size;
                    241: {
                    242:        register int zindex = 0;
                    243:        register vm_size_t freesize;
                    244: 
                    245:        freesize = size;
                    246:        if (size <= k_zone_maxsize) {
                    247:                freesize = k_zone_elemsize[0];
                    248:                zindex = 0;
                    249:                while (freesize < size) {
                    250:                        freesize = k_zone_elemsize[++zindex];
                    251:                }
                    252:        }
                    253: 
                    254:        if (freesize <= k_zone_maxsize) {
                    255:                zfree(k_zone[zindex], data);
                    256:        } else {
                    257:                kmem_free(kalloc_map, data, freesize);
                    258:        }
                    259: }
                    260: 
                    261: struct zone *kalloc_zone(
                    262:        vm_size_t       size)
                    263: {
                    264:        register int zindex = 0;
                    265:        register vm_size_t allocsize;
                    266: 
                    267:        /* compute the size of the block that we will actually allocate */
                    268: 
                    269:        allocsize = size;
                    270:        if (size <= k_zone_maxsize) {
                    271:                allocsize = k_zone_elemsize[0];
                    272:                zindex = 0;
                    273:                while (allocsize < size) {
                    274:                        allocsize = k_zone_elemsize[++zindex];
                    275:                }
                    276: 
                    277:                return (k_zone[zindex]);
                    278:        }
                    279: 
                    280:        return (0);
                    281: }

unix.superglobalmegacorp.com

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