|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.