00001 /* 00002 * @(#)hprof_blocks.c 1.7 10/03/23 00003 * 00004 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * -Redistribution of source code must retain the above copyright notice, this 00010 * list of conditions and the following disclaimer. 00011 * 00012 * -Redistribution in binary form must reproduce the above copyright notice, 00013 * this list of conditions and the following disclaimer in the documentation 00014 * and/or other materials provided with the distribution. 00015 * 00016 * Neither the name of Oracle or the names of contributors may 00017 * be used to endorse or promote products derived from this software without 00018 * specific prior written permission. 00019 * 00020 * This software is provided "AS IS," without a warranty of any kind. ALL 00021 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING 00022 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00023 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") 00024 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE 00025 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 00026 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST 00027 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 00028 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY 00029 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 00030 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00031 * 00032 * You acknowledge that this software is not designed, licensed or intended 00033 * for use in the design, construction, operation or maintenance of any 00034 * nuclear facility. 00035 */ 00036 00037 /* Allocations from large blocks, no individual free's */ 00038 00039 #include "hprof.h" 00040 00041 /* 00042 * This file contains some allocation code that allows you 00043 * to have space allocated via larger blocks of space. 00044 * The only free allowed is of all the blocks and all the elements. 00045 * Elements can be of different alignments and fixed or variable sized. 00046 * The space allocated never moves. 00047 * 00048 */ 00049 00050 /* Get the real size allocated based on alignment and bytes needed */ 00051 static int 00052 real_size(int alignment, int nbytes) 00053 { 00054 if ( alignment > 1 ) { 00055 int wasted; 00056 00057 wasted = alignment - ( nbytes % alignment ); 00058 if ( wasted != alignment ) { 00059 nbytes += wasted; 00060 } 00061 } 00062 return nbytes; 00063 } 00064 00065 /* Add a new current_block to the Blocks* chain, adjust size if nbytes big. */ 00066 static void 00067 add_block(Blocks *blocks, int nbytes) 00068 { 00069 int header_size; 00070 int block_size; 00071 BlockHeader *block_header; 00072 00073 HPROF_ASSERT(blocks!=NULL); 00074 HPROF_ASSERT(nbytes>0); 00075 00076 header_size = real_size(blocks->alignment, sizeof(BlockHeader)); 00077 block_size = blocks->elem_size*blocks->population; 00078 if ( nbytes > block_size ) { 00079 block_size = real_size(blocks->alignment, nbytes); 00080 } 00081 block_header = (BlockHeader*)HPROF_MALLOC(block_size+header_size); 00082 block_header->next = NULL; 00083 block_header->bytes_left = block_size; 00084 block_header->next_pos = header_size; 00085 00086 /* Link in new block */ 00087 if ( blocks->current_block != NULL ) { 00088 blocks->current_block->next = block_header; 00089 } 00090 blocks->current_block = block_header; 00091 if ( blocks->first_block == NULL ) { 00092 blocks->first_block = block_header; 00093 } 00094 } 00095 00096 /* Initialize a new Blocks */ 00097 Blocks * 00098 blocks_init(int alignment, int elem_size, int population) 00099 { 00100 Blocks *blocks; 00101 00102 HPROF_ASSERT(alignment>0); 00103 HPROF_ASSERT(elem_size>0); 00104 HPROF_ASSERT(population>0); 00105 00106 blocks = (Blocks*)HPROF_MALLOC(sizeof(Blocks)); 00107 blocks->alignment = alignment; 00108 blocks->elem_size = elem_size; 00109 blocks->population = population; 00110 blocks->first_block = NULL; 00111 blocks->current_block = NULL; 00112 return blocks; 00113 } 00114 00115 /* Allocate bytes from a Blocks area. */ 00116 void * 00117 blocks_alloc(Blocks *blocks, int nbytes) 00118 { 00119 BlockHeader *block; 00120 int pos; 00121 void *ptr; 00122 00123 HPROF_ASSERT(blocks!=NULL); 00124 HPROF_ASSERT(nbytes>=0); 00125 if ( nbytes == 0 ) { 00126 return NULL; 00127 } 00128 00129 block = blocks->current_block; 00130 nbytes = real_size(blocks->alignment, nbytes); 00131 if ( block == NULL || block->bytes_left < nbytes ) { 00132 add_block(blocks, nbytes); 00133 block = blocks->current_block; 00134 } 00135 pos = block->next_pos; 00136 ptr = (void*)(((char*)block)+pos); 00137 block->next_pos += nbytes; 00138 block->bytes_left -= nbytes; 00139 return ptr; 00140 } 00141 00142 /* Terminate the Blocks */ 00143 void 00144 blocks_term(Blocks *blocks) 00145 { 00146 BlockHeader *block; 00147 00148 HPROF_ASSERT(blocks!=NULL); 00149 00150 block = blocks->first_block; 00151 while ( block != NULL ) { 00152 BlockHeader *next_block; 00153 00154 next_block = block->next; 00155 HPROF_FREE(block); 00156 block = next_block; 00157 } 00158 HPROF_FREE(blocks); 00159 } 00160
1.6.1