|
|
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.