X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0c530ab8987f0ae6a1a3d9284f40182b88852816..2d21ac55c334faf3a56e5634905ed6987fc787d4:/bsd/dev/dtrace/dtrace_alloc.c diff --git a/bsd/dev/dtrace/dtrace_alloc.c b/bsd/dev/dtrace/dtrace_alloc.c new file mode 100644 index 000000000..df0107bd3 --- /dev/null +++ b/bsd/dev/dtrace/dtrace_alloc.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2005-2007 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* + * DTrace kalloc emulation. + * + * This is a subset of kalloc functionality, to allow dtrace + * specific allocation to be accounted for separately from the + * general kalloc pool. + * + * Note that allocations greater than dalloc_max still go into + * the kalloc.large bucket, as it seems impossible to emulate + * that functionality in the bsd kern. + */ + +#include +#include +#include +#include +#include + +#if defined(DTRACE_MEMORY_ZONES) + +#define DTRACE_ALLOC_MINSIZE 16 + +vm_size_t dtrace_alloc_max; +vm_size_t dtrace_alloc_max_prerounded; +int first_d_zone = -1; +struct zone *d_zone[16]; +static const char *d_zone_name[16] = { + "dtrace.1", "dtrace.2", + "dtrace.4", "dtrace.8", + "dtrace.16", "dtrace.32", + "dtrace.64", "dtrace.128", + "dtrace.256", "dtrace.512", + "dtrace.1024", "dtrace.2048", + "dtrace.4096", "dtrace.8192", + "dtrace.16384", "dtrace.32768" +}; + +unsigned long d_zone_max[16] = { + 1024, /* 1 Byte */ + 1024, /* 2 Byte */ + 1024, /* 4 Byte */ + 1024, /* 8 Byte */ + 1024, /* 16 Byte */ + 4096, /* 32 Byte */ + 4096, /* 64 Byte */ + 4096, /* 128 Byte */ + 4096, /* 256 Byte */ + 1024, /* 512 Byte */ + 1024, /* 1024 Byte */ + 1024, /* 2048 Byte */ + 1024, /* 4096 Byte */ + 4096, /* 8192 Byte */ + 64, /* 16384 Byte */ + 64, /* 32768 Byte */ +}; + +void dtrace_alloc_init(void) +{ + vm_size_t size; + int i; + + if (PAGE_SIZE < 16*1024) + dtrace_alloc_max = 16*1024; + else + dtrace_alloc_max = PAGE_SIZE; + dtrace_alloc_max_prerounded = dtrace_alloc_max / 2 + 1; + + /* + * Allocate a zone for each size we are going to handle. + * We specify non-paged memory. + */ + for (i = 0, size = 1; size < dtrace_alloc_max; i++, size <<= 1) { + if (size < DTRACE_ALLOC_MINSIZE) { + d_zone[i] = NULL; + continue; + } + if (size == DTRACE_ALLOC_MINSIZE) { + first_d_zone = i; + } + d_zone[i] = zinit(size, d_zone_max[i] * size, size, d_zone_name[i]); + } +} + +void *dtrace_alloc(vm_size_t size) +{ + int zindex; + vm_size_t allocsize; + + /* + * If size is too large for a zone, then use kmem_alloc. + * (We use kmem_alloc instead of kmem_alloc_wired so that + * krealloc can use kmem_realloc.) + */ + + if (size >= dtrace_alloc_max_prerounded) { + return _MALLOC(size, M_TEMP, M_WAITOK); + } + + /* compute the size of the block that we will actually allocate */ + allocsize = DTRACE_ALLOC_MINSIZE; + zindex = first_d_zone; + while (allocsize < size) { + allocsize <<= 1; + zindex++; + } + + return(zalloc_canblock(d_zone[zindex], TRUE)); +} + +void dtrace_free(void *data, vm_size_t size) +{ + int zindex; + vm_size_t freesize; + + if (size >= dtrace_alloc_max_prerounded) { + _FREE(data, M_TEMP); + return; + } + + /* compute the size of the block that we actually allocated from */ + freesize = DTRACE_ALLOC_MINSIZE; + zindex = first_d_zone; + while (freesize < size) { + freesize <<= 1; + zindex++; + } + + /* free to the appropriate zone */ + zfree(d_zone[zindex], data); +} + +#endif /* DTRACE_MEMORY_ZONES */