00001 /* 00002 * Copyright 2003, 2004 PathScale, Inc. All Rights Reserved. 00003 */ 00004 00005 /* 00006 00007 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00008 00009 This program is free software; you can redistribute it and/or modify it 00010 under the terms of version 2 of the GNU General Public License as 00011 published by the Free Software Foundation. 00012 00013 This program is distributed in the hope that it would be useful, but 00014 WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 00017 Further, this software is distributed without any warranty that it is 00018 free of the rightful claim of any third person regarding infringement 00019 or the like. Any license provided herein, whether implied or 00020 otherwise, applies only to this software file. Patent licenses, if 00021 any, provided herein do not apply to combinations of this program with 00022 other software, or any other product whatsoever. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with this program; if not, write the Free Software Foundation, Inc., 59 00026 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00027 00028 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00029 Mountain View, CA 94043, or: 00030 00031 http://www.sgi.com 00032 00033 For further information regarding this notice, see: 00034 00035 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00036 00037 */ 00038 00039 00040 /* ==================================================================== 00041 * ==================================================================== 00042 * 00043 * Module: mempool.h 00044 * $Revision: 1.1 $ 00045 * $Date: 2005/07/27 02:17:56 $ 00046 * $Author: kevinlo $ 00047 * $Source: /depot/CVSROOT/javi/src/sw/cmplr/common/util/mempool.h,v $ 00048 * 00049 * Revision history: 00050 * 19-Sep-89 - Original Version 00051 * 24-Jan-91 - Copied for TP/Muse 00052 * 28-May-91 - Integrated Josie routines 00053 * 20-Sep-91 - Added TYPE_X_MALLOC and TYPE_ALLOC macros 00054 * 05-Apr-93 - Rewritten from scratch to allow statistics, better 00055 * handling of large blocks. 00056 * 00057 * Description: 00058 * 00059 * This package provides a different interface from the traditional C 00060 * malloc/free memory allocation, and is MUCH more effecient for a 00061 * particular style of memory allocation common in the compiler. In 00062 * this style, individual memory blocks are not freed one at a time. 00063 * Rather all the outstanding memory in a particular memory pool is 00064 * freed as a whole. Doing this allow us to replace large numbers of 00065 * calls to alloc/free with only a few calls which allocate and 00066 * deallocate large blocks. 00067 * 00068 * Each MEM_POOL has a current allocation level. MEM_POOLs may be 00069 * Push'ed onto a new allocation level or Pop'ed back to their 00070 * previous allocation level. When a MEM_POOL is pop'ed, all the 00071 * memory allocated from it since it was pushed to its current level 00072 * is freed. 00073 * 00074 * Compiling all the compiler sources with -DIs_True_On and MEM_Trace_Enable 00075 * enables collection of memory allocation statistics. With these it is 00076 * possible to see a lot of information about the callsites where 00077 * memory is allocated. In particular, it is possible to see how much 00078 * memory allocated from each callsite is outstanding. 00079 * 00080 * Before you begin 00081 * ================ 00082 * 00083 * void MEM_Initialize() 00084 * 00085 * Initialize the memory pool package. 00086 * 00087 * Global Variables 00088 * ================ 00089 * 00090 * MEM_POOL *Malloc_Mem_Pool 00091 * 00092 * If this MEM_POOL is passed as an argument to an alloc or free 00093 * routine, use malloc instead of the mempools. 00094 * Note that it causes the use of malloc and not calloc. Memory 00095 * from this pool will not be automatically zeroed. 00096 * 00097 * MEM_POOL *Default_Mem_Pool 00098 * 00099 * Use the default MEM_POOL 00100 * 00101 * 00102 * Operations defined on MEM_POOLS 00103 * =============================== 00104 * 00105 * void MEM_POOL_Set_Default(MEM_POOL *pool) 00106 * 00107 * All subsequent uses of Default_Mem_Pool will refer to pool 00108 * 00109 * void MEM_POOL_Initialize( 00110 * MEM_POOL *pool, 00111 * char *name, 00112 * BOOL bz 00113 * ) 00114 * 00115 * Must be called on a pool before it used for the other 00116 * operations. 00117 * 00118 * pool - is a pointer to the MEM_POOL to initialize. 00119 * name - is a name to use when printing information 00120 * about it 00121 * bz - If TRUE, memory allocated from the pool will 00122 * always be zero'ed 00123 * 00124 * After a MEM_POOL has been initialized, it is important 00125 * that the structure it points to at no point go out of 00126 * scope, so MEM_POOLs initialized this way should generally 00127 * statically allocated. 00128 * 00129 * 00130 * BOOL MEM_POOL_Zeroed(MEM_POOL *pool) 00131 * 00132 * Returns TRUE iff <pool> zeroes newly allocated memory 00133 * (i.e., if <bz> argument was TRUE when pool was initialized). 00134 * 00135 * 00136 * void MEM_POOL_Push( 00137 * MEM_POOL *pool 00138 * ) 00139 * 00140 * Check that the pool is not frozen. If not, 00141 * push a pool to a new allocation level. 00142 * 00143 * pool - is a pointer to the MEM_POOL to push 00144 * 00145 * void MEM_POOL_Push_Freeze( 00146 * MEM_POOL *pool 00147 * ) 00148 * 00149 * Same as MEM_POOL_Push, except that after being pushed, 00150 * the pool is frozen for subsequent push/pop operations 00151 * until the pool is unfrozen. 00152 * 00153 * pool - is a pointer to the MEM_POOL to push 00154 * 00155 * void MEM_POOL_Pop( 00156 * MEM_POOL *pool 00157 * ) 00158 * 00159 * Check that the pool is not frozen. If not, then 00160 * pop a MEM_POOL to a previous allcation level. All memory 00161 * allocated since the matching call to MEM_POOL_Push is 00162 * freed. As a special case, unmatched pop's just free ALL 00163 * outstanding storage in t 00164 * 00165 * pool - is a pointer to the MEM_POOL to pop 00166 * 00167 * void MEM_POOL_Pop_Unfreeze( 00168 * MEM_POOL *pool 00169 * ) 00170 * 00171 * Same as MEM_POOL_Pop, except that the memory pool is first 00172 * unfrozen. Must be called on a frozen memory pool. 00173 * 00174 * pool - is a pointer to the MEM_POOL to pop 00175 * 00176 * 00177 * MEM_PTR MEM_POOL_Alloc( 00178 * MEM_POOL *pool, 00179 * size_t size 00180 * ) 00181 * 00182 * Allocate memory from a pool. Always double word aligned. 00183 * 00184 * pool - is a pointer to the MEM_POOL for allocation 00185 * size - gives the number of bytes to allocate. 00186 * 00187 * This is a low level usage and is discouraged in favor of 00188 * the TYPE_ forms below. 00189 * 00190 * If pool == Malloc_Mem_Pool this just calls the system malloc 00191 * 00192 * 00193 * MEM_PTR MEM_POOL_Realloc( 00194 * MEM_POOL *pool, 00195 * MEM_PTR old_block, 00196 * size_t old_size, 00197 * size_t new_size 00198 * ) 00199 * 00200 * Reallocate memory from a pool. 00201 * 00202 * pool - is a pointer to the MEM_POOL for allocation 00203 * old_block - is a value previously returned from 00204 * MEM_POOL_Alloc, or MEM_POOL_Realloc. 00205 * (Very important.) It must have been 00206 * (re)allocated from the given pool. (Very 00207 * important.) 00208 * old_size - is the size used to (re)allocate old_block 00209 * new_size - is the size new allocation size. 00210 * 00211 * Returns a block of memory 'new_size' bytes long. The 00212 * first 'old_size' byte of the returned memory contain the 00213 * same values as in the 'old_block'. 00214 * 00215 * Implementation notes: There are some cases in which this 00216 * is more effecient than just allocating a new block and 00217 * copying in the firrt old_size bytes. In particular, if 00218 * 'old_block' was the last block of memory allocated from 00219 * 'pool' the reallocation will often be 'in place'. Even if 00220 * it isn't in place, the memory for 'old_block' will be made 00221 * available for future by the pool package. If it 00222 * especially important to get this effect for some reason, 00223 * you should consider using a dedicated pool to hold the 00224 * vector that you plan to realloc. 00225 * 00226 * If pool == Malloc_Mem_Pool this just calls the system realloc 00227 * 00228 * 00229 * void MEM_POOL_FREE( 00230 * MEM_POOL *pool, 00231 * void *data 00232 * ) 00233 * 00234 * Free the data from a MEM_POOL. If pool == Malloc_Mem_Pool, 00235 * this calls the UNIX free. Otherwise this is a no-op. 00236 * 00237 * 00238 * void MEM_POOL_Delete(MEM_POOL *pool) 00239 * 00240 * Free all the memory associated with <pool>. Currently, 00241 * deleted pools are not reported by MEM_Trace (but this can 00242 * be changed). Note that <*pool> itself is not freed. A 00243 * deleted pool cannot be used unless it is first initialized 00244 * again with MEM_POOL_Initialize. 00245 * 00246 * 00247 * Typed allocation macros 00248 * ======================= 00249 * 00250 * Use of these forms is STRONGLY encouraged as they will allow us to 00251 * collect information by types as will as by callsites. They are 00252 * also terser and less error prone than bare calls to alloc with 00253 * sizeof and a cast. 00254 * 00255 * type * TYPE_MEM_POOL_ALLOC( 00256 * type, 00257 * MEM_POOL *pool 00258 * ) 00259 * 00260 * type * TYPE_MEM_POOL_ALLOC_N( 00261 * type, 00262 * MEM_POOL *pool, 00263 * size_t count 00264 * ) 00265 * 00266 * type * TYPE_MEM_POOL_REALLOC_N( 00267 * type, 00268 * MEM_POOL *pool, 00269 * type *old_block, 00270 * size_t old_count, 00271 * size_t new_count 00272 * ) 00273 * 00274 * Allocate one or more objects of a particular type from a 00275 * pool and return a typed pointer. The plain form allocates 00276 * a single object. The _N for allocates a vector of such 00277 * objects. 00278 * 00279 * type - is the name of the type to allocate. Enough 00280 * memory is allocated to hold one (plain form) 00281 * or n (_N form) for these. 00282 * pool - is a pointer to the MEM_POOL to use, 00283 * count - How many objects (_N form only). 00284 * 00285 * If pool == Malloc_Mem_Pool this calls the system malloc/realloc 00286 * 00287 * 00288 * type * TYPE_MEM_POOL_REALLOC_N( 00289 * type, 00290 * MEM_POOL *pool, 00291 * type *old_block, 00292 * size_t old_count, 00293 * size_t new_count 00294 * ) 00295 * 00296 * Reallocate a vector of one or more objects. Both the old 00297 * and new vectors must be in the same pool. 00298 * 00299 * type - is the name of the type to allocate. Enough 00300 * memory is allocated to hold one (plain form) 00301 * or n (_N form) for these. 00302 * pool - is a pointer to the MEM_POOL to use, 00303 * old_block - is the block of memory to reallocate. 00304 * It must have been (re)allocated from the 00305 * given 'pool' 00306 * old_count - is the number of elements allocated in 00307 * 'old_block'. It is VERY IMPORTANT that 00308 * this be accurate. 00309 * new_count - How many objects 00310 * 00311 * 00312 * Tracing memory allocation 00313 * ========================= 00314 * 00315 * When Is_True_On is enabled, we also support: 00316 * 00317 * void MEM_Tracing_Enable(void) 00318 * 00319 * Tell the memory package to collect alloc call site 00320 * statistics. 00321 * 00322 * void MEM_Trace(void) 00323 * 00324 * Produces a report on the TFile at to memory allocation. 00325 * This report starts with the low-level malloc information 00326 * (see malloc(3)) provided by the -lmalloc package. 00327 * Then for each pool, a list MEM_POOL_Alloc callsites is 00328 * given, sorted by the maximum amount of outstanding memory 00329 * at any time for each callsite. Here is a key to the per 00330 * callsite information: 00331 * 00332 * maxt - Maximum outstanding memory at any one time 00333 * curr - Current memory outstanding 00334 * tot - Total memory allocated from this callsite 00335 * maxs - Largest memory block allocated from this 00336 * callsite 00337 * count - Count of times callsite was executed 00338 * grew - Count of times more memory was allocated 00339 * from this callsite than last time it was 00340 * executed. 00341 * shrank - Count of times less memory was allocated 00342 * from this callsite than last time it was 00343 * executed. 00344 * 00345 * void Trace_Memory_Allocation( 00346 * const INT phase, 00347 * const char *const pname 00348 * ) 00349 * 00350 * Produce a memory allocation trace (via MEM_Trace) when 00351 * the trace switch -ta<m> is specified on the compile line. 00352 * 00353 * phase - Phase after which we're printing 00354 * pname - Print name for phase 00355 * 00356 * Related Utilities 00357 * ================= 00358 * 00359 * While not strictly MEM_POOL related, the following utilities are 00360 * are provided: 00361 * 00362 * type * TYPE_ALLOCA( 00363 * type 00364 * ) 00365 * 00366 * type * TYPE_ALLOCA_N( 00367 * type, 00368 * size_t count 00369 * ) 00370 * 00371 * Allocate one or more objects of a particular type using 00372 * alloca and return a typed pointer. The plain form allocates 00373 * a single object. The _N for allocates a vector of such 00374 * objects. 00375 * 00376 * type - is the name of the type to allocate. Enough 00377 * memory is allocated to hold one (plain form) 00378 * or n (_N form) for these. 00379 * count - How many objects (_N form only). 00380 * 00381 * Backward Compatibility 00382 * ====================== 00383 * 00384 * For the sake of backward compatibility, this package also supports 00385 * an older interface. It's direct usage in new code is discouraged. 00386 * It deals with allocations from four predefined pools which are 00387 * never directly accessed, but are accessed via function calls. 00388 * 00389 * The four predefined pools are: 00390 * 00391 * L - Pushed and popped to get local utility storage 00392 * Pu - Pushed and popped to get storage that can be freed 00393 * up after we are done with each program unit 00394 * Src - Pushed and popped to get storage that can be freed 00395 * up after we are done with each source file. 00396 * P - Pushed and popped to get utiity storage that can be 00397 * freed up when we are done with the current "phase". 00398 * 00399 * All four pools support: 00400 * 00401 * MEM_PTR X_Alloc( 00402 * size_t size 00403 * ) 00404 * 00405 * TYPE_X_ALLOC( 00406 * type 00407 * ) 00408 * 00409 * TYPE_X_ALLOC_N( 00410 * type, 00411 * INT32 n 00412 * ) 00413 * 00414 * (Where X is one of the predefined pools.) 00415 * 00416 * Additionally, the Local pool supports: 00417 * 00418 * void L_Save(void) 00419 * 00420 * Pushes the L pool. 00421 * 00422 * void L_Free(void) 00423 * 00424 * Pops the L pool. 00425 * 00426 * ==================================================================== 00427 * ==================================================================== */ 00428 00429 00430 00431 00432 00433 #ifndef mempool_INCLUDED 00434 #define mempool_INCLUDED 00435 #ifdef __cplusplus 00436 extern "C" { 00437 #endif 00438 00439 00440 00441 //#include "defs.h" 00442 00443 #define TYPE_ALLOCA(type) ((type *)alloca(sizeof(type))) 00444 #define TYPE_ALLOCA_N(type,n) ((type *)alloca(sizeof(type) * (n))) 00445 00446 #if 0 00447 #define TYPE_MALLOC(type) ((type *) malloc(sizeof(type))) 00448 #define TYPE_MALLOC_N(type,n) ((type *) malloc(sizeof(type) * (n))) 00449 #endif 00450 00451 #define Malloc_Mem_Pool (MEM_POOL *) 1 00452 #define Default_Mem_Pool (MEM_POOL *) 0 00453 00454 /* MEM_BLOCK - Internals private. 00455 */ 00456 typedef struct mem_block MEM_BLOCK; 00457 00458 /* MEM_POOL_BLOCKS - Internals private. 00459 */ 00460 typedef struct mem_pool_blocks MEM_POOL_BLOCKS; 00461 00462 /* MEM_STAT - Internals private. 00463 */ 00464 typedef struct mem_stat MEM_STAT; 00465 00466 /* MEM_PURE_STACK - Internals private. 00467 */ 00468 typedef struct mem_pure_stack MEM_PURE_STACK; 00469 00470 /* MEM_POOL - An object out of which to allocate and free memory. 00471 * See below for currently supported MEM_POOL operations. 00472 * 00473 * Internals private, but documented here, as the 00474 * declaration must be public so its size will be known to clients. 00475 */ 00476 typedef struct mem_pool MEM_POOL; 00477 struct mem_pool { 00478 char *name; /* Name of the pool for 00479 * debugging only. 00480 */ 00481 MEM_POOL_BLOCKS *blocks; /* Current top of allocation 00482 * stack. This changes when the 00483 * pool is pushed or popped. 00484 */ 00485 MEM_POOL *rest; /* Used to keep a link of all 00486 * initialized pools. 00487 */ 00488 MEM_PURE_STACK *pure_stack; /* Stack of pointers, one for each push 00489 * level, each pointer pointing to first 00490 * allocated piece in that push-level. 00491 */ 00492 mBOOL bz; /* To allocate zero'd memory 00493 * or not out of this pool. 00494 */ 00495 mBOOL frozen; /* If frozen, then subsequent Push/Pop 00496 * operations are disabled until the 00497 * mem_pool is unfrozen. 00498 * Default unfrozen. 00499 */ 00500 mUINT16 magic_num; /* Set to a a magic number when 00501 * the MEM_POOL is initialized, and 00502 * reset to zero when the pool is deleted. 00503 * Used to check that the pool is 00504 * initialized before a Push/Alloc. 00505 */ 00506 MEM_STAT *alloc_site_list; /* Used to report statistics 00507 * about call sites that have 00508 * outstanding allocation in the 00509 * pool. 00510 */ 00511 }; 00512 00513 #define MEM_STAT_ARGS(line,file) ,INT32 line, const char *file 00514 00515 extern void 00516 MEM_Initialize(void); 00517 00518 #define MEM_POOL_Zeroed(pool) ((pool)->bz) 00519 00520 /* These pools zero newly-allocated memory. 00521 */ 00522 extern MEM_POOL MEM_local_pool; 00523 extern MEM_POOL MEM_src_pool; 00524 extern MEM_POOL MEM_pu_pool; 00525 extern MEM_POOL MEM_phase_pool; 00526 00527 extern MEM_POOL *MEM_local_pool_ptr; 00528 extern MEM_POOL *MEM_src_pool_ptr; 00529 extern MEM_POOL *MEM_pu_pool_ptr; 00530 extern MEM_POOL *MEM_phase_pool_ptr; 00531 00532 /* These pools don't zero newly-allocated memory, and hence allocation 00533 * is faster than the zeroed pools above. These should be used whenever 00534 * appropriate. 00535 */ 00536 extern MEM_POOL MEM_local_nz_pool; 00537 extern MEM_POOL MEM_src_nz_pool; 00538 extern MEM_POOL MEM_pu_nz_pool; 00539 extern MEM_POOL MEM_phase_nz_pool; 00540 00541 extern MEM_POOL *MEM_local_nz_pool_ptr; 00542 extern MEM_POOL *MEM_src_nz_pool_ptr; 00543 extern MEM_POOL *MEM_pu_nz_pool_ptr; 00544 extern MEM_POOL *MEM_phase_nz_pool_ptr; 00545 00546 extern void MEM_Trace(void); 00547 00548 extern void 00549 Trace_Memory_Allocation( 00550 INT phase, 00551 const char *pname 00552 ); 00553 00554 extern void MEM_Tracing_Enable(void); 00555 00556 extern MEM_PTR 00557 MEM_POOL_Alloc_P 00558 ( 00559 MEM_POOL *mempool, 00560 size_t size 00561 MEM_STAT_ARGS(line,file) 00562 ); 00563 00564 extern MEM_PTR 00565 MEM_POOL_Realloc_P 00566 ( 00567 MEM_POOL *mempool, 00568 MEM_PTR old_block, 00569 size_t old_size, 00570 size_t new_size 00571 MEM_STAT_ARGS(line,file) 00572 ); 00573 00574 extern void 00575 MEM_POOL_Push_P 00576 ( 00577 MEM_POOL *pool 00578 MEM_STAT_ARGS(line,file) 00579 ); 00580 00581 extern void 00582 MEM_POOL_Push_Freeze_P 00583 ( 00584 MEM_POOL *pool 00585 MEM_STAT_ARGS(line,file) 00586 ); 00587 00588 extern void 00589 MEM_POOL_Pop_P 00590 ( 00591 MEM_POOL *pool 00592 MEM_STAT_ARGS(line,file) 00593 ); 00594 00595 extern void 00596 MEM_POOL_Pop_Unfreeze_P 00597 ( 00598 MEM_POOL *pool 00599 MEM_STAT_ARGS(line,file) 00600 ); 00601 00602 extern void MEM_POOL_Set_Default(MEM_POOL *pool); 00603 extern void MEM_POOL_FREE(MEM_POOL *pool, void *data); 00604 extern void MEM_POOL_Delete(MEM_POOL *pool); 00605 00606 extern void 00607 MEM_POOL_Initialize_P 00608 ( 00609 MEM_POOL *pool, 00610 char *name, 00611 BOOL bz 00612 MEM_STAT_ARGS(line,file) 00613 ); 00614 00615 #ifdef Is_True_On 00616 #define MEM_POOL_Alloc(pool,size) \ 00617 MEM_POOL_Alloc_P(pool,size,__LINE__,__FILE__) 00618 00619 #define MEM_POOL_Realloc(pool,o,os,ns) \ 00620 MEM_POOL_Realloc_P((pool),(o),(os),(ns),__LINE__,__FILE__) 00621 00622 #define MEM_POOL_Push(pool) \ 00623 MEM_POOL_Push_P(pool,__LINE__,__FILE__) 00624 00625 #define MEM_POOL_Push_Freeze(pool) \ 00626 MEM_POOL_Push_Freeze_P(pool,__LINE__,__FILE__) 00627 00628 #define MEM_POOL_Pop(pool) \ 00629 MEM_POOL_Pop_P(pool,__LINE__,__FILE__) 00630 00631 #define MEM_POOL_Pop_Unfreeze(pool) \ 00632 MEM_POOL_Pop_Unfreeze_P(pool,__LINE__,__FILE__) 00633 00634 #define MEM_POOL_Initialize(pool,name,bz) \ 00635 MEM_POOL_Initialize_P(pool,name,bz,__LINE__,__FILE__) 00636 #else 00637 #define MEM_POOL_Alloc(pool,size) \ 00638 MEM_POOL_Alloc_P(pool,size,0,NULL) 00639 00640 #define MEM_POOL_Realloc(pool,o,os,ns) \ 00641 MEM_POOL_Realloc_P((pool),(o),(os),(ns),0,NULL) 00642 00643 #define MEM_POOL_Push(pool) \ 00644 MEM_POOL_Push_P(pool,0,NULL) 00645 00646 #define MEM_POOL_Push_Freeze(pool) \ 00647 MEM_POOL_Push_Freeze_P(pool,0,NULL) 00648 00649 #define MEM_POOL_Pop(pool) \ 00650 MEM_POOL_Pop_P(pool,0,NULL) 00651 00652 #define MEM_POOL_Pop_Unfreeze(pool) \ 00653 MEM_POOL_Pop_Unfreeze_P(pool,0,NULL) 00654 00655 #define MEM_POOL_Initialize(pool,name,bz) \ 00656 MEM_POOL_Initialize_P(pool,name,bz,0,NULL) 00657 #endif 00658 00659 #define TYPE_MEM_POOL_ALLOC(type,pool) \ 00660 ((type *) MEM_POOL_Alloc(pool,sizeof(type))) 00661 00662 #define TYPE_MEM_POOL_ALLOC_N(type,pool,n) \ 00663 ((type *) MEM_POOL_Alloc(pool,sizeof(type) * (n))) 00664 00665 #define TYPE_MEM_POOL_REALLOC_N(type,pool,old_block,old_n,new_n) \ 00666 ((type *) MEM_POOL_Realloc(pool,((MEM_PTR) old_block), \ 00667 (sizeof(type) * (old_n)), \ 00668 (sizeof(type) * (new_n)))) 00669 00670 00671 /* Backward compatibility 00672 */ 00673 #define L_Save() MEM_POOL_Push(MEM_local_pool_ptr) 00674 #define L_Alloc(x) MEM_POOL_Alloc(MEM_local_pool_ptr,(x)) 00675 #define L_Free() MEM_POOL_Pop(MEM_local_pool_ptr) 00676 00677 #define P_Alloc(x) MEM_POOL_Alloc(MEM_phase_pool_ptr,(x)) 00678 #define Src_Alloc(x) MEM_POOL_Alloc(MEM_src_pool_ptr,(x)) 00679 #define Pu_Alloc(x) MEM_POOL_Alloc(MEM_pu_pool_ptr,(x)) 00680 00681 #define TYPE_L_ALLOC(type) ((type*)L_Alloc(sizeof(type))) 00682 #define TYPE_L_ALLOC_N(type,n) ((type*)L_Alloc(sizeof(type)*(n))) 00683 #define TYPE_P_ALLOC(type) ((type*)P_Alloc(sizeof(type))) 00684 #define TYPE_P_ALLOC_N(type,n) ((type*)P_Alloc(sizeof(type)*(n))) 00685 #define TYPE_PU_ALLOC(type) ((type*)Pu_Alloc(sizeof(type))) 00686 #define TYPE_PU_ALLOC_N(type,n) ((type*)Pu_Alloc(sizeof(type)*(n))) 00687 #define TYPE_SRC_ALLOC(type) ((type*)Src_Alloc(sizeof(type))) 00688 #define TYPE_SRC_ALLOC_N(type,n) ((type*)Src_Alloc(sizeof(type)*(n))) 00689 00690 /* Routines to grow space (based on realloc), clearing the new part of 00691 * the grown area while leaving the (copied) original contents 00692 * unmodified. 00693 */ 00694 MEM_PTR Realloc_Clear ( /* realloc and clear new space */ 00695 MEM_PTR ptr, /* Currently allocated memory */ 00696 INT32 new_size, /* New size desired */ 00697 INT32 old_size /* Old size (leave this much unchanged) */ 00698 ); 00699 MEM_PTR Re_Calloc ( /* Realloc and clear -- calloc-style call */ 00700 MEM_PTR ptr, /* Currently allocated memory */ 00701 INT32 new_nelem, /* New element count desired */ 00702 INT32 elsize, /* Element size */ 00703 INT32 old_nelem /* Old element count (leave unchanged) */ 00704 ); 00705 00706 00707 #ifdef __cplusplus 00708 } 00709 #endif 00710 00711 #ifdef __cplusplus 00712 00713 /* Class for automatically pushing and popping a mempool. This is useful 00714 * for automatically doing a MEM_POOL_Pop() whenever we return from a 00715 * function, and for guaranteeing that all objects allocated from a mempool 00716 * are deallocated before the mempool is popped. 00717 * 00718 * Use the class within a function body, like this: 00719 * 00720 * RETURN_TYPE my_func(...) 00721 * { 00722 * // mempool must have already been initialized; typically it's a 00723 * // file static or global variable. You MUST declare popper before 00724 * // you start allocating storage from mempool. 00725 * MEM_POOL_Popper popper(&mempool); // constructor does MEM_POOL_Push() 00726 * 00727 * // Temporary that's no longer needed after we return from my_func(). 00728 * // Its declaration MUST come after popper. 00729 * DYN_ARRAY<WN *> array_of_wn(&mempool); 00730 * // Other temporaries allocated from mempool. 00731 * 00732 * ... // code that allocates elements for array_of_wn and other temps. 00733 * 00734 * if (some_condition) 00735 * // Temporaries are automatically destructed and mempool is popped, 00736 * // in the right order, despite early return from function. 00737 * return val1; 00738 * 00739 * // Temporaries are automatically destructed and mempool is popped, 00740 * // in the right order. 00741 * return val2; 00742 * } 00743 * 00744 * The reason the MEM_POOL_Popper destructor call (hence also the 00745 * MEM_POOL_Pop()) is guaranteed to follow the destruction of objects 00746 * allocated from the mempool is that C++ guarantees that auto objects are 00747 * destructed in the reverse order of their appearance in the block (see 00748 * Stroustrup, "C++ Programming Language" 3rd ed., p. 245). 00749 */ 00750 00751 class MEM_POOL_Popper { 00752 MEM_POOL *pool; 00753 public: 00754 MEM_POOL_Popper(MEM_POOL *_pool) : pool(_pool) { MEM_POOL_Push(pool); } 00755 ~MEM_POOL_Popper() { MEM_POOL_Pop(pool); } 00756 00757 MEM_POOL* Pool () const { return pool; } 00758 }; 00759 00760 /* Similar to MEM_POOL_Popper, CXX_MEM_POOL is used for initializing and 00761 * automatically deleting a MEM_POOL within a local scope. 00762 */ 00763 00764 class CXX_MEM_POOL { 00765 MEM_POOL mem_pool; 00766 00767 public: 00768 MEM_POOL *operator()() { return &mem_pool; } 00769 00770 CXX_MEM_POOL(char *name, BOOL do_bzero) { 00771 mem_pool.magic_num = 0; /* force it to be uninitialized */ 00772 MEM_POOL_Initialize(&mem_pool, name, do_bzero); 00773 MEM_POOL_Push(&mem_pool); 00774 }; 00775 ~CXX_MEM_POOL() { 00776 MEM_POOL_Pop(&mem_pool); 00777 MEM_POOL_Delete(&mem_pool); 00778 } 00779 }; 00780 00781 /* MEM_POOL_Constructor: to be phased out. 00782 This is used for those cases where the MEM_POOL needs to be file-level 00783 static or global. 00784 */ 00785 00786 class MEM_POOL_Constructor 00787 { 00788 private: 00789 MEM_POOL *pool; 00790 00791 public: 00792 00793 MEM_POOL_Constructor (MEM_POOL* p, char* name, BOOL zero) : pool (p) { 00794 MEM_POOL_Initialize (pool, name, zero); 00795 MEM_POOL_Push (pool); 00796 } 00797 00798 ~MEM_POOL_Constructor () { 00799 MEM_POOL_Pop (pool); 00800 MEM_POOL_Delete (pool); 00801 } 00802 00803 MEM_POOL* Pool () const { return pool; }; 00804 }; 00805 #endif /* #ifdef __cplusplus */ 00806 00807 #endif /* mempool_INCLUDED */
1.5.6