2 * Copyright (c) 2005-2007 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 * DTrace kalloc emulation.
32 * This is a subset of kalloc functionality, to allow dtrace
33 * specific allocation to be accounted for separately from the
34 * general kalloc pool.
36 * Note that allocations greater than dalloc_max still go into
37 * the kalloc.large bucket, as it seems impossible to emulate
38 * that functionality in the bsd kern.
43 #include <sys/malloc.h>
44 #include <sys/dtrace.h>
45 #include <kern/zalloc.h>
47 #if defined(DTRACE_MEMORY_ZONES)
49 #define DTRACE_ALLOC_MINSIZE 16
51 vm_size_t dtrace_alloc_max
;
52 vm_size_t dtrace_alloc_max_prerounded
;
53 int first_d_zone
= -1;
54 struct zone
*d_zone
[16];
55 static const char *d_zone_name
[16] = {
56 "dtrace.1", "dtrace.2",
57 "dtrace.4", "dtrace.8",
58 "dtrace.16", "dtrace.32",
59 "dtrace.64", "dtrace.128",
60 "dtrace.256", "dtrace.512",
61 "dtrace.1024", "dtrace.2048",
62 "dtrace.4096", "dtrace.8192",
63 "dtrace.16384", "dtrace.32768"
66 unsigned long d_zone_max
[16] = {
85 void dtrace_alloc_init(void)
90 if (PAGE_SIZE
< 16*1024)
91 dtrace_alloc_max
= 16*1024;
93 dtrace_alloc_max
= PAGE_SIZE
;
94 dtrace_alloc_max_prerounded
= dtrace_alloc_max
/ 2 + 1;
97 * Allocate a zone for each size we are going to handle.
98 * We specify non-paged memory.
100 for (i
= 0, size
= 1; size
< dtrace_alloc_max
; i
++, size
<<= 1) {
101 if (size
< DTRACE_ALLOC_MINSIZE
) {
105 if (size
== DTRACE_ALLOC_MINSIZE
) {
108 d_zone
[i
] = zinit(size
, d_zone_max
[i
] * size
, size
, d_zone_name
[i
]);
112 void *dtrace_alloc(vm_size_t size
)
118 * If size is too large for a zone, then use kmem_alloc.
119 * (We use kmem_alloc instead of kmem_alloc_kobject so that
120 * krealloc can use kmem_realloc.)
123 if (size
>= dtrace_alloc_max_prerounded
) {
124 return _MALLOC(size
, M_TEMP
, M_WAITOK
);
127 /* compute the size of the block that we will actually allocate */
128 allocsize
= DTRACE_ALLOC_MINSIZE
;
129 zindex
= first_d_zone
;
130 while (allocsize
< size
) {
135 return(zalloc_canblock(d_zone
[zindex
], TRUE
));
138 void dtrace_free(void *data
, vm_size_t size
)
143 if (size
>= dtrace_alloc_max_prerounded
) {
148 /* compute the size of the block that we actually allocated from */
149 freesize
= DTRACE_ALLOC_MINSIZE
;
150 zindex
= first_d_zone
;
151 while (freesize
< size
) {
156 /* free to the appropriate zone */
157 zfree(d_zone
[zindex
], data
);
160 #endif /* DTRACE_MEMORY_ZONES */