00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Malloc_T.h 00006 * 00007 * Malloc_T.h,v 4.86 2005/12/22 01:17:51 shuston Exp 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> and 00010 * Irfan Pyarali <irfan@cs.wustl.edu> 00011 */ 00012 //========================================================================== 00013 00014 #ifndef ACE_MALLOC_T_H 00015 #define ACE_MALLOC_T_H 00016 #include /**/ "ace/pre.h" 00017 00018 #include "ace/Malloc.h" /* Need ACE_Control_Block */ 00019 #include "ace/Malloc_Base.h" /* Need ACE_Allocator */ 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/Malloc_Allocator.h" 00026 #include "ace/Free_List.h" 00027 #include "ace/Guard_T.h" 00028 00029 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00030 00031 /** 00032 * @class ACE_Cached_Mem_Pool_Node 00033 * 00034 * @brief ACE_Cached_Mem_Pool_Node keeps unused memory within a free 00035 * list. 00036 * 00037 * The length of a piece of unused memory must be greater than 00038 * sizeof (void*). This makes sense because we'll waste even 00039 * more memory if we keep them in a separate data structure. 00040 * This class should really be placed within the ACE_Cached_Allocator 00041 * class but this can't be done due to C++ compiler portability problems. 00042 */ 00043 template <class T> 00044 class ACE_Cached_Mem_Pool_Node 00045 { 00046 public: 00047 /// Return the address of free memory. 00048 T *addr (void); 00049 00050 /// Get the next ACE_Cached_Mem_Pool_Node in a list. 00051 ACE_Cached_Mem_Pool_Node<T> *get_next (void); 00052 00053 /// Set the next ACE_Cached_Mem_Pool_Node. 00054 void set_next (ACE_Cached_Mem_Pool_Node<T> *ptr); 00055 00056 private: 00057 /** 00058 * Since memory is not used when placed in a free list, 00059 * we can use it to maintain the structure of free list. 00060 * I was using union to hide the fact of overlapping memory 00061 * usage. However, that cause problem on MSVC. So, I now turn 00062 * back to hack this with casting. 00063 */ 00064 ACE_Cached_Mem_Pool_Node<T> *next_; 00065 }; 00066 00067 /** 00068 * @class ACE_Cached_Allocator 00069 * 00070 * @brief A fixed-size allocator that caches items for quicker access. 00071 * 00072 * This class enables caching of dynamically allocated, 00073 * fixed-sized classes. Notice that the <code>sizeof (TYPE)</code> 00074 * must be greater than or equal to <code> sizeof (void*) </code> for 00075 * this to work properly. 00076 * 00077 * This class can be configured flexibly with different types of 00078 * ACE_LOCK strategies that support the @a ACE_Thread_Mutex, 00079 * @a ACE_Thread_Semaphore, @a ACE_Process_Mutex, and @a 00080 * ACE_Process_Semaphore constructor API. 00081 * 00082 * @sa ACE_Dynamic_Cached_Allocator 00083 */ 00084 template <class T, class ACE_LOCK> 00085 class ACE_Cached_Allocator : public ACE_New_Allocator 00086 { 00087 public: 00088 /// Create a cached memory pool with @a n_chunks chunks 00089 /// each with sizeof (TYPE) size. 00090 ACE_Cached_Allocator (size_t n_chunks); 00091 00092 /// Clear things up. 00093 ~ACE_Cached_Allocator (void); 00094 00095 /** 00096 * Get a chunk of memory from free list cache. Note that @a nbytes is 00097 * only checked to make sure that it's less or equal to sizeof T, and is 00098 * otherwise ignored since @c malloc() always returns a pointer to an 00099 * item of sizeof (T). 00100 */ 00101 void *malloc (size_t nbytes = sizeof (T)); 00102 00103 /** 00104 * Get a chunk of memory from free list cache, giving them 00105 * @a initial_value. Note that @a nbytes is only checked to make sure 00106 * that it's less or equal to sizeof T, and is otherwise ignored since 00107 * calloc() always returns a pointer to an item of sizeof (T). 00108 */ 00109 virtual void *calloc (size_t nbytes, 00110 char initial_value = '\0'); 00111 00112 /// This method is a no-op and just returns 0 since the free list 00113 /// only works with fixed sized entities. 00114 virtual void *calloc (size_t n_elem, 00115 size_t elem_size, 00116 char initial_value = '\0'); 00117 00118 /// Return a chunk of memory back to free list cache. 00119 void free (void *); 00120 00121 /// Return the number of chunks available in the cache. 00122 size_t pool_depth (void); 00123 00124 private: 00125 /// Remember how we allocate the memory in the first place so 00126 /// we can clear things up later. 00127 char *pool_; 00128 00129 /// Maintain a cached memory free list. 00130 ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<T>, ACE_LOCK> free_list_; 00131 }; 00132 00133 /** 00134 * @class ACE_Dynamic_Cached_Allocator 00135 * 00136 * @brief A size-based allocator that caches blocks for quicker access. 00137 * 00138 * This class enables caching of dynamically allocated, 00139 * fixed-size chunks. Notice that the <code>chunk_size</code> 00140 * must be greater than or equal to <code> sizeof (void*) </code> for 00141 * this to work properly. 00142 * 00143 * This class can be configured flexibly with different types of 00144 * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a 00145 * ACE_Process_Mutex constructor API. 00146 * 00147 * @sa ACE_Cached_Allocator 00148 */ 00149 template <class ACE_LOCK> 00150 class ACE_Dynamic_Cached_Allocator : public ACE_New_Allocator 00151 { 00152 public: 00153 /// Create a cached memory pool with @a n_chunks chunks 00154 /// each with @a chunk_size size. 00155 ACE_Dynamic_Cached_Allocator (size_t n_chunks, size_t chunk_size); 00156 00157 /// Clear things up. 00158 ~ACE_Dynamic_Cached_Allocator (void); 00159 00160 /** 00161 * Get a chunk of memory from free list cache. Note that @a nbytes is 00162 * only checked to make sure that it's less or equal to @a chunk_size, 00163 * and is otherwise ignored since malloc() always returns a pointer to an 00164 * item of @a chunk_size size. 00165 */ 00166 void *malloc (size_t nbytes = 0); 00167 00168 /** 00169 * Get a chunk of memory from free list cache, giving them 00170 * @a initial_value. Note that @a nbytes is only checked to make sure 00171 * that it's less or equal to @a chunk_size, and is otherwise ignored 00172 * since calloc() always returns a pointer to an item of @a chunk_size. 00173 */ 00174 virtual void *calloc (size_t nbytes, 00175 char initial_value = '\0'); 00176 00177 /// This method is a no-op and just returns 0 since the free list 00178 /// only works with fixed sized entities. 00179 virtual void *calloc (size_t n_elem, 00180 size_t elem_size, 00181 char initial_value = '\0'); 00182 00183 /// Return a chunk of memory back to free list cache. 00184 void free (void *); 00185 00186 /// Return the number of chunks available in the cache. 00187 size_t pool_depth (void); 00188 00189 private: 00190 /// Remember how we allocate the memory in the first place so 00191 /// we can clear things up later. 00192 char *pool_; 00193 00194 /// Maintain a cached memory free list. We use @c char as template 00195 /// parameter, although sizeof(char) is usually less than 00196 /// sizeof(void*). Really important is that @a chunk_size 00197 /// must be greater or equal to sizeof(void*). 00198 ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<char>, ACE_LOCK> free_list_; 00199 00200 /// Remember the size of our chunks. 00201 size_t chunk_size_; 00202 }; 00203 00204 /** 00205 * @class ACE_Allocator_Adapter 00206 * 00207 * @brief This class is an Adapter that allows the ACE_Allocator to 00208 * use the ACE_Malloc class below. 00209 */ 00210 template <class MALLOC> 00211 class ACE_Allocator_Adapter : public ACE_Allocator 00212 { 00213 public: 00214 // Trait. 00215 typedef MALLOC ALLOCATOR; 00216 00217 #if defined (ACE_HAS_TEMPLATE_TYPEDEFS) 00218 // The following code will break C++ compilers that don't support 00219 // template typedefs correctly. 00220 typedef const ACE_TYPENAME MALLOC::MEMORY_POOL_OPTIONS *MEMORY_POOL_OPTIONS; 00221 #else 00222 typedef const void *MEMORY_POOL_OPTIONS; 00223 #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ 00224 00225 // = Initialization. 00226 /** 00227 * Note that @a pool_name should be located in 00228 * a directory with the appropriate visibility and protection so 00229 * that all processes that need to access it can do so. */ 00230 ACE_Allocator_Adapter (const char *pool_name = 0); 00231 00232 /** 00233 * Note that @a pool_name should be located in 00234 * a directory with the appropriate visibility and protection so 00235 * that all processes that need to access it can do so. 00236 * This constructor must be inline to avoid bugs with some C++ 00237 * compilers. */ 00238 ACE_Allocator_Adapter (const char *pool_name, 00239 const char *lock_name, 00240 MEMORY_POOL_OPTIONS options = 0) 00241 : allocator_ (ACE_TEXT_CHAR_TO_TCHAR (pool_name), 00242 ACE_TEXT_CHAR_TO_TCHAR (lock_name), 00243 options) 00244 { 00245 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter"); 00246 } 00247 00248 #if defined (ACE_HAS_WCHAR) 00249 /** 00250 * Note that @a pool_name should be located in 00251 * a directory with the appropriate visibility and protection so 00252 * that all processes that need to access it can do so. */ 00253 ACE_Allocator_Adapter (const wchar_t *pool_name); 00254 00255 /** 00256 * Note that @a pool_name should be located in 00257 * a directory with the appropriate visibility and protection so 00258 * that all processes that need to access it can do so. 00259 * This constructor must be inline to avoid bugs with some C++ 00260 * compilers. */ 00261 ACE_Allocator_Adapter (const wchar_t *pool_name, 00262 const wchar_t *lock_name, 00263 MEMORY_POOL_OPTIONS options = 0) 00264 : allocator_ (ACE_TEXT_WCHAR_TO_TCHAR (pool_name), 00265 ACE_TEXT_WCHAR_TO_TCHAR (lock_name), 00266 options) 00267 { 00268 ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter"); 00269 } 00270 #endif /* ACE_HAS_WCHAR */ 00271 00272 /// Destructor. 00273 virtual ~ACE_Allocator_Adapter (void); 00274 00275 // = Memory Management 00276 00277 /// Allocate @a nbytes, but don't give them any initial value. 00278 virtual void *malloc (size_t nbytes); 00279 00280 /// Allocate @a nbytes, giving them all an @a initial_value. 00281 virtual void *calloc (size_t nbytes, char initial_value = '\0'); 00282 00283 /// Allocate @a n_elem each of size @a elem_size, giving them 00284 /// @a initial_value. 00285 virtual void *calloc (size_t n_elem, 00286 size_t elem_size, 00287 char initial_value = '\0'); 00288 00289 /// Free @a ptr (must have been allocated by ACE_Allocator::malloc()). 00290 virtual void free (void *ptr); 00291 00292 /// Remove any resources associated with this memory manager. 00293 virtual int remove (void); 00294 00295 // = Map manager like functions 00296 00297 /** 00298 * Associate @a name with @a pointer. If @a duplicates == 0 then do 00299 * not allow duplicate @a name/pointer associations, else if 00300 * @a duplicates> != 0 then allow duplicate @a name/pointer 00301 * assocations. Returns 0 if successfully binds (1) a previously 00302 * unbound @a name or (2) @a duplicates != 0, returns 1 if trying to 00303 * bind a previously bound @a name and @a duplicates == 0, else 00304 * returns -1 if a resource failure occurs. 00305 */ 00306 virtual int bind (const char *name, void *pointer, int duplicates = 0); 00307 00308 /** 00309 * Associate @a name with @a pointer. Does not allow duplicate 00310 * name/pointer associations. Returns 0 if successfully binds 00311 * (1) a previously unbound @a name, 1 if trying to bind a previously 00312 * bound @a name, or returns -1 if a resource failure occurs. When 00313 * this call returns, @a pointer's value will always reference the 00314 * void * that @a name is associated with. Thus, if the caller needs 00315 * to use @a pointer (e.g., to free it) a copy must be maintained by 00316 * the caller. 00317 */ 00318 virtual int trybind (const char *name, void *&pointer); 00319 00320 /// Locate @a name and pass out parameter via pointer. If found, 00321 /// return 0, returns -1 if @a name isn't found. 00322 virtual int find (const char *name, void *&pointer); 00323 00324 /// Returns 0 if the name is in the mapping and -1 if not. 00325 virtual int find (const char *name); 00326 00327 /// Unbind (remove) the name from the map. Don't return the pointer 00328 /// to the caller 00329 virtual int unbind (const char *name); 00330 00331 /// Break any association of name. Returns the value of pointer in 00332 /// case the caller needs to deallocate memory. 00333 virtual int unbind (const char *name, void *&pointer); 00334 00335 // = Protection and "sync" (i.e., flushing data to backing store). 00336 00337 /** 00338 * Sync @a len bytes of the memory region to the backing store 00339 * starting at @c this->base_addr_. If @a len == -1 then sync the 00340 * whole region. 00341 */ 00342 virtual int sync (ssize_t len = -1, int flags = MS_SYNC); 00343 00344 /// Sync @a len bytes of the memory region to the backing store 00345 /// starting at @c addr_. 00346 virtual int sync (void *addr, size_t len, int flags = MS_SYNC); 00347 00348 /** 00349 * Change the protection of the pages of the mapped region to @a prot 00350 * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 00351 * then change protection of all pages in the mapped region. 00352 */ 00353 virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); 00354 00355 /// Change the protection of the pages of the mapped region to @a prot 00356 /// starting at @a addr up to @a len bytes. 00357 virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); 00358 00359 /// Returns the underlying allocator. 00360 ALLOCATOR &alloc (void); 00361 00362 #if defined (ACE_HAS_MALLOC_STATS) 00363 /// Dump statistics of how malloc is behaving. 00364 virtual void print_stats (void) const; 00365 #endif /* ACE_HAS_MALLOC_STATS */ 00366 00367 /// Dump the state of the object. 00368 virtual void dump (void) const; 00369 00370 private: 00371 /// ALLOCATOR instance, which is owned by the adapter. 00372 ALLOCATOR allocator_; 00373 }; 00374 00375 /** 00376 * @class ACE_Static_Allocator 00377 * 00378 * @brief Defines a class that provided a highly optimized memory 00379 * management scheme for allocating memory statically. 00380 * 00381 * This class allocates a fixed-size @c POOL_SIZE of memory and 00382 * uses the ACE_Static_Allocator_Base class implementations of 00383 * malloc() and calloc() to optimize memory allocation from this 00384 * pool. 00385 */ 00386 template <size_t POOL_SIZE> 00387 class ACE_Static_Allocator : public ACE_Static_Allocator_Base 00388 { 00389 public: 00390 ACE_Static_Allocator (void) 00391 : ACE_Static_Allocator_Base (pool_, POOL_SIZE) 00392 { 00393 // This function <{must}> be inlined!!! 00394 } 00395 00396 private: 00397 /// Pool contents. 00398 char pool_[POOL_SIZE]; 00399 }; 00400 00401 // Forward declaration. 00402 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00403 class ACE_Malloc_LIFO_Iterator_T; 00404 00405 // Ensure backwards compatibility... 00406 #define ACE_Malloc_Iterator ACE_Malloc_LIFO_Iterator 00407 00408 // Forward declaration. 00409 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00410 class ACE_Malloc_FIFO_Iterator_T; 00411 00412 /** 00413 * @class ACE_Malloc_T 00414 * 00415 * @brief Define a C++ class that uses parameterized types to provide 00416 * an extensible mechanism for encapsulating various of dynamic 00417 * memory management strategies. 00418 * 00419 * This class can be configured flexibly with different 00420 * MEMORY_POOL strategies and different types of ACE_LOCK 00421 * strategies that support the @a ACE_Thread_Mutex and @a 00422 * ACE_Process_Mutex constructor API. 00423 * 00424 * Note that the @a bind() and @a find() methods use linear search, so 00425 * it's not a good idea to use them for managing a large number of 00426 * entities. If you need to manage a large number of entities, it's 00427 * recommended that you @a bind() an @ ACE_Hash_Map_Manager that 00428 * resides in shared memory, use @a find() to locate it, and then 00429 * store/retrieve the entities in the hash map. 00430 * */ 00431 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00432 class ACE_Malloc_T 00433 { 00434 public: 00435 friend class ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>; 00436 friend class ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>; 00437 typedef ACE_MEM_POOL MEMORY_POOL; 00438 typedef ACE_MEM_POOL_OPTIONS MEMORY_POOL_OPTIONS; 00439 typedef ACE_TYPENAME ACE_CB::ACE_Name_Node NAME_NODE; 00440 typedef ACE_TYPENAME ACE_CB::ACE_Malloc_Header MALLOC_HEADER; 00441 00442 // = Initialization and termination methods. 00443 /** 00444 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00445 * initialize the memory pool, and uses ACE::basename() to 00446 * automatically extract out the name used for the underlying lock 00447 * name (if necessary). 00448 * 00449 * Note that @a pool_name should be located in 00450 * a directory with the appropriate visibility and protection so 00451 * that all processes that need to access it can do so. 00452 */ 00453 ACE_Malloc_T (const ACE_TCHAR *pool_name = 0); 00454 00455 /** 00456 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00457 * initialize the memory pool, and uses @a lock_name to automatically 00458 * extract out the name used for the underlying lock name (if 00459 * necessary). In addition, @a options is passed through to 00460 * initialize the underlying memory pool. 00461 * 00462 * Note that @a pool_name should be located in 00463 * a directory with the appropriate visibility and protection so 00464 * that all processes that need to access it can do so. 00465 */ 00466 ACE_Malloc_T (const ACE_TCHAR *pool_name, 00467 const ACE_TCHAR *lock_name, 00468 const ACE_MEM_POOL_OPTIONS *options = 0); 00469 00470 /** 00471 * Initialize an ACE_Malloc with an external ACE_LOCK. 00472 * This constructor passes @a pool_name and @a options to initialize 00473 * the memory pool. @a lock is used as the pool lock, and must be 00474 * properly set up and ready for use before being passed to this method. 00475 */ 00476 ACE_Malloc_T (const ACE_TCHAR *pool_name, 00477 const ACE_MEM_POOL_OPTIONS *options, 00478 ACE_LOCK *lock); 00479 00480 #if !defined (ACE_HAS_TEMPLATE_TYPEDEFS) 00481 /// This is necessary to work around template bugs with certain C++ 00482 /// compilers. 00483 ACE_Malloc_T (const ACE_TCHAR *pool_name, 00484 const ACE_TCHAR *lock_name, 00485 const void *options = 0); 00486 #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ 00487 00488 /// Destructor 00489 ~ACE_Malloc_T (void); 00490 00491 /// Get Reference counter. 00492 int ref_counter (void); 00493 00494 /// Release ref counter. 00495 int release (int close = 0); 00496 00497 /// Releases resources allocated by this object. 00498 int remove (void); 00499 00500 // = Memory management 00501 00502 /// Allocate @a nbytes, but don't give them any initial value. 00503 void *malloc (size_t nbytes); 00504 00505 /// Allocate @a nbytes, giving them @a initial_value. 00506 void *calloc (size_t nbytes, char initial_value = '\0'); 00507 00508 /// Allocate @a n_elem each of size @a elem_size, giving them 00509 /// @a initial_value. 00510 void *calloc (size_t n_elem, 00511 size_t elem_size, 00512 char initial_value = '\0'); 00513 00514 /// Deallocate memory pointed to by @a ptr, which must have been 00515 /// allocated previously by malloc(). 00516 void free (void *ptr); 00517 00518 /// Returns a reference to the underlying memory pool. 00519 MEMORY_POOL &memory_pool (void); 00520 00521 // = Map manager like functions 00522 00523 /** 00524 * Associate @a name with @a pointer. If @a duplicates == 0 then do 00525 * not allow duplicate name/pointer associations, else if 00526 * @a duplicates != 0 then allow duplicate name/pointer 00527 * assocations. Returns 0 if successfully binds (1) a previously 00528 * unbound @a name or (2) @a duplicates != 0, returns 1 if trying to 00529 * bind a previously bound @a name and @a duplicates == 0, else 00530 * returns -1 if a resource failure occurs. 00531 */ 00532 int bind (const char *name, void *pointer, int duplicates = 0); 00533 00534 /** 00535 * Associate @a name with @a pointer. Does not allow duplicate 00536 * name/pointer associations. Returns 0 if successfully binds 00537 * (1) a previously unbound @a name, 1 if trying to bind a previously 00538 * bound @a name, or returns -1 if a resource failure occurs. When 00539 * this call returns @a pointer's value will always reference the 00540 * void * that @a name is associated with. Thus, if the caller needs 00541 * to use @a pointer (e.g., to free it) a copy must be maintained by 00542 * the caller. 00543 */ 00544 int trybind (const char *name, void *&pointer); 00545 00546 /// Locate @a name and pass out parameter via @a pointer. If found, 00547 /// return 0, returns -1 if failure occurs. 00548 int find (const char *name, void *&pointer); 00549 00550 /// Returns 0 if @a name is in the mapping. -1, otherwise. 00551 int find (const char *name); 00552 00553 /** 00554 * Unbind (remove) the name from the map. Don't return the pointer 00555 * to the caller. If you want to remove all occurrences of @a name 00556 * you'll need to call this method multiple times until it fails... 00557 */ 00558 int unbind (const char *name); 00559 00560 /** 00561 * Unbind (remove) one association of @a name to @a pointer. Returns 00562 * the value of pointer in case the caller needs to deallocate 00563 * memory. If you want to remove all occurrences of @a name you'll 00564 * need to call this method multiple times until it fails... 00565 */ 00566 int unbind (const char *name, void *&pointer); 00567 00568 // = Protection and "sync" (i.e., flushing data to backing store). 00569 00570 /** 00571 * Sync @a len bytes of the memory region to the backing store 00572 * starting at @c this->base_addr_. If @a len == -1 then sync the 00573 * whole region. 00574 */ 00575 int sync (ssize_t len = -1, int flags = MS_SYNC); 00576 00577 /// Sync @a len bytes of the memory region to the backing store 00578 /// starting at @c addr_. 00579 int sync (void *addr, size_t len, int flags = MS_SYNC); 00580 00581 /** 00582 * Change the protection of the pages of the mapped region to @a prot 00583 * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 00584 * then change protection of all pages in the mapped region. 00585 */ 00586 int protect (ssize_t len = -1, int prot = PROT_RDWR); 00587 00588 /// Change the protection of the pages of the mapped region to @a prot 00589 /// starting at @a addr up to @a len bytes. 00590 int protect (void *addr, size_t len, int prot = PROT_RDWR); 00591 00592 /** 00593 * Returns a count of the number of available chunks that can hold 00594 * @a size byte allocations. Function can be used to determine if you 00595 * have reached a water mark. This implies a fixed amount of allocated 00596 * memory. 00597 * 00598 * @param size The chunk size of that you would like a count of 00599 * @return Function returns the number of chunks of the given size 00600 * that would fit in the currently allocated memory. 00601 */ 00602 ssize_t avail_chunks (size_t size) const; 00603 00604 #if defined (ACE_HAS_MALLOC_STATS) 00605 /// Dump statistics of how malloc is behaving. 00606 void print_stats (void) const; 00607 #endif /* ACE_HAS_MALLOC_STATS */ 00608 00609 /// Returns a pointer to the lock used to provide mutual exclusion to 00610 /// an ACE_Malloc allocator. 00611 ACE_LOCK &mutex (void); 00612 00613 /// Dump the state of an object. 00614 void dump (void) const; 00615 00616 /// Declare the dynamic allocation hooks. 00617 ACE_ALLOC_HOOK_DECLARE; 00618 00619 /// Return cb_ptr value. 00620 void *base_addr (void); 00621 00622 /** 00623 * Bad flag. This operation should be called immediately after the 00624 * construction of the Malloc object to query whether the object was 00625 * constructed successfully. If not, the user should invoke @c 00626 * remove and release the object (it is not usable.) 00627 * @retval 0 if all is fine. non-zero if this malloc object is 00628 * unuable. 00629 */ 00630 int bad (void); 00631 00632 private: 00633 /// Initialize the Malloc pool. 00634 int open (void); 00635 00636 /// Associate @a name with @a pointer. Assumes that locks are held by 00637 /// callers. 00638 int shared_bind (const char *name, 00639 void *pointer); 00640 00641 /** 00642 * Try to locate @a name. If found, return the associated 00643 * ACE_Name_Node, else returns 0 if can't find the @a name. 00644 * Assumes that locks are held by callers. Remember to cast the 00645 * return value to ACE_CB::ACE_Name_Node*. 00646 */ 00647 void *shared_find (const char *name); 00648 00649 /// Allocate memory. Assumes that locks are held by callers. 00650 void *shared_malloc (size_t nbytes); 00651 00652 /// Deallocate memory. Assumes that locks are held by callers. 00653 void shared_free (void *ptr); 00654 00655 /// Pointer to the control block that is stored in memory controlled 00656 /// by <MEMORY_POOL>. 00657 ACE_CB *cb_ptr_; 00658 00659 /// Pool of memory used by ACE_Malloc to manage its freestore. 00660 MEMORY_POOL memory_pool_; 00661 00662 /// Lock that ensures mutual exclusion for the memory pool. 00663 ACE_LOCK *lock_; 00664 int delete_lock_; // True if destructor should delete the lock 00665 00666 /// Keep track of failure in constructor. 00667 int bad_flag_; 00668 }; 00669 00670 /*****************************************************************************/ 00671 00672 /** 00673 * @class ACE_Malloc_Lock_Adapter_T 00674 * 00675 * @brief Template functor adapter for lock strategies used with ACE_Malloc_T. 00676 * 00677 * This class acts as a factory for lock strategies that have various ctor 00678 * signatures. If the lock strategy's ctor takes an ACE_TCHAR* as the first 00679 * and only required parameter, it will just work. Otherwise use template 00680 * specialization to create a version that matches the lock strategy's ctor 00681 * signature. See ACE_Process_Semaphore and ACE_Thread_Semaphore for 00682 * examples. 00683 * 00684 */ 00685 /*****************************************************************************/ 00686 00687 /** 00688 * @class ACE_Malloc_LIFO_Iterator_T 00689 * 00690 * @brief LIFO iterator for names stored in Malloc'd memory. 00691 * 00692 * This class can be configured flexibly with different types of 00693 * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a 00694 * ACE_Process_Mutex constructor API. 00695 * 00696 * Does not support deletions while iteration is occurring. 00697 */ 00698 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00699 class ACE_Malloc_LIFO_Iterator_T 00700 { 00701 public: 00702 typedef ACE_TYPENAME ACE_CB::ACE_Name_Node NAME_NODE; 00703 typedef ACE_TYPENAME ACE_CB::ACE_Malloc_Header MALLOC_HEADER; 00704 00705 // = Initialization method. 00706 /// If @a name = 0 it will iterate through everything else only 00707 /// through those entries whose @a name match. 00708 ACE_Malloc_LIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc, 00709 const char *name = 0); 00710 00711 /// Destructor. 00712 ~ACE_Malloc_LIFO_Iterator_T (void); 00713 00714 // = Iteration methods. 00715 00716 /// Returns 1 when all items have been seen, else 0. 00717 int done (void) const; 00718 00719 /// Pass back the next entry in the set that hasn't yet been 00720 /// visited. Returns 0 when all items have been seen, else 1. 00721 int next (void *&next_entry); 00722 00723 /** 00724 * Pass back the next entry (and the name associated with it) in 00725 * the set that hasn't yet been visited. Returns 0 when all items 00726 * have been seen, else 1. 00727 */ 00728 int next (void *&next_entry, 00729 const char *&name); 00730 00731 /// Move forward by one element in the set. Returns 0 when all the 00732 /// items in the set have been seen, else 1. 00733 int advance (void); 00734 00735 /// Dump the state of an object. 00736 void dump (void) const; 00737 00738 /// Declare the dynamic allocation hooks. 00739 ACE_ALLOC_HOOK_DECLARE; 00740 00741 private: 00742 /// Malloc we are iterating over. 00743 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc_; 00744 00745 /// Keeps track of how far we've advanced... 00746 NAME_NODE *curr_; 00747 00748 /// Lock Malloc for the lifetime of the iterator. 00749 ACE_Read_Guard<ACE_LOCK> guard_; 00750 00751 /// Name that we are searching for. 00752 const char *name_; 00753 }; 00754 00755 /** 00756 * @class ACE_Malloc_FIFO_Iterator_T 00757 * 00758 * @brief FIFO iterator for names stored in Malloc'd memory. 00759 * 00760 * This class can be configured flexibly with different types of 00761 * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a 00762 * ACE_Process_Mutex constructor API. 00763 * 00764 * Does not support deletions while iteration is occurring. 00765 */ 00766 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00767 class ACE_Malloc_FIFO_Iterator_T 00768 { 00769 public: 00770 typedef ACE_TYPENAME ACE_CB::ACE_Name_Node NAME_NODE; 00771 typedef ACE_TYPENAME ACE_CB::ACE_Malloc_Header MALLOC_HEADER; 00772 00773 // = Initialization method. 00774 /// If @a name = 0 it will iterate through everything else only 00775 /// through those entries whose @a name match. 00776 ACE_Malloc_FIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc, 00777 const char *name = 0); 00778 00779 /// Destructor. 00780 ~ACE_Malloc_FIFO_Iterator_T (void); 00781 00782 // = Iteration methods. 00783 00784 /// Returns 1 when all items have been seen, else 0. 00785 int done (void) const; 00786 00787 /// Pass back the next entry in the set that hasn't yet been 00788 /// visited. Returns 0 when all items have been seen, else 1. 00789 int next (void *&next_entry); 00790 00791 /** 00792 * Pass back the next entry (and the name associated with it) in 00793 * the set that hasn't yet been visited. Returns 0 when all items 00794 * have been seen, else 1. 00795 */ 00796 int next (void *&next_entry, 00797 const char *&name); 00798 00799 /// Move forward by one element in the set. Returns 0 when all the 00800 /// items in the set have been seen, else 1. 00801 int advance (void); 00802 00803 /// Go to the starting element that was inserted first. Returns 0 00804 /// when there is no item in the set, else 1. 00805 int start (void); 00806 00807 /// Dump the state of an object. 00808 void dump (void) const; 00809 00810 /// Declare the dynamic allocation hooks. 00811 ACE_ALLOC_HOOK_DECLARE; 00812 00813 private: 00814 /// Malloc we are iterating over. 00815 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc_; 00816 00817 /// Keeps track of how far we've advanced... 00818 NAME_NODE *curr_; 00819 00820 /// Lock Malloc for the lifetime of the iterator. 00821 ACE_Read_Guard<ACE_LOCK> guard_; 00822 00823 /// Name that we are searching for. 00824 const char *name_; 00825 }; 00826 00827 template <ACE_MEM_POOL_1, class ACE_LOCK> 00828 class ACE_Malloc : public ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> 00829 { 00830 public: 00831 // = Initialization and termination methods. 00832 /** 00833 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00834 * initialize the memory pool, and uses ACE::basename() to 00835 * automatically extract out the name used for the underlying lock 00836 * name (if necessary). Note that @a pool_name should be located in 00837 * a directory with the appropriate visibility and protection so 00838 * that all processes that need to access it can do so. 00839 */ 00840 ACE_Malloc (const ACE_TCHAR *pool_name = 0); 00841 00842 /** 00843 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00844 * initialize the memory pool, and uses @a lock_name to automatically 00845 * extract out the name used for the underlying lock name (if 00846 * necessary). In addition, @a options is passed through to 00847 * initialize the underlying memory pool. Note that @a pool_name 00848 * should be located in a directory with the appropriate visibility 00849 * and protection so that all processes that need to access it can 00850 * do so. 00851 */ 00852 ACE_Malloc (const ACE_TCHAR *pool_name, 00853 const ACE_TCHAR *lock_name, 00854 const ACE_MEM_POOL_OPTIONS *options = 0); 00855 00856 #if !defined (ACE_HAS_TEMPLATE_TYPEDEFS) 00857 /// This is necessary to work around template bugs with certain C++ 00858 /// compilers. 00859 ACE_Malloc (const ACE_TCHAR *pool_name, 00860 const ACE_TCHAR *lock_name, 00861 const void *options = 0); 00862 #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ 00863 }; 00864 00865 template <ACE_MEM_POOL_1, class ACE_LOCK> 00866 class ACE_Malloc_LIFO_Iterator : public ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> 00867 { 00868 public: 00869 // = Initialization method. 00870 /// If @a name = 0 it will iterate through everything else only 00871 /// through those entries whose @a name match. 00872 ACE_Malloc_LIFO_Iterator (ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK> &malloc, 00873 const char *name = 0); 00874 }; 00875 00876 template <ACE_MEM_POOL_1, class ACE_LOCK> 00877 class ACE_Malloc_FIFO_Iterator : public ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> 00878 { 00879 public: 00880 // = Initialization method. 00881 /// If @a name = 0 it will iterate through everything else only 00882 /// through those entries whose @a name match. 00883 ACE_Malloc_FIFO_Iterator (ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK> &malloc, 00884 const char *name = 0); 00885 }; 00886 00887 template <class ACE_LOCK> 00888 class ACE_Malloc_Lock_Adapter_T 00889 { 00890 public: 00891 ACE_LOCK * operator () (const ACE_TCHAR *myname); 00892 }; 00893 00894 ACE_END_VERSIONED_NAMESPACE_DECL 00895 00896 #if defined (__ACE_INLINE__) 00897 #include "ace/Malloc_T.inl" 00898 #endif /* __ACE_INLINE__ */ 00899 00900 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00901 #include "ace/Malloc_T.cpp" 00902 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00903 00904 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00905 #pragma implementation ("Malloc_T.cpp") 00906 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00907 00908 #include /**/ "ace/post.h" 00909 #endif /* ACE_MALLOC_H */