00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Malloc_T.h 00006 * 00007 * $Id: Malloc_T.h 78610 2007-06-27 14:03:35Z shuston $ 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 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 A class template that uses parameterized types to provide 00416 * an extensible mechanism for encapsulating various 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 ACE_Thread_Mutex and ACE_Process_Mutex 00422 * constructor API. 00423 * 00424 * Common MEMORY_POOL strategies to use with this class are: 00425 * - ACE_Local_Memory_Pool 00426 * - ACE_MMAP_Memory_Pool 00427 * - ACE_Pagefile_Memory_Pool 00428 * - ACE_Shared_Memory_Pool 00429 * - ACE_Sbrk_Memory_Pool 00430 * 00431 * The MEMORY_POOL class must provide the following methods: 00432 * - constructor (const ACE_TCHAR *pool_name) 00433 * - constructor (const ACE_TCHAR *pool_name, const MEMORY_POOL_OPTIONS *options) 00434 * - void dump (void) const (needed if ACE is built with ACE_HAS_DUMP defined) 00435 * - void *init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time); 00436 * - int release (void) 00437 * - void *acquire (size_t nbytes, size_t &rounded_bytes) 00438 * - void *base_addr (void) 00439 * - seh_selector() (only needed on Windows) 00440 * 00441 * Note that the ACE_Allocator_Adapter class can be used to integrate allocator 00442 * classes which do not meet the interface requirements of ACE_Malloc_T. 00443 * 00444 * @Note The bind() and find() methods use linear search, so 00445 * it's not a good idea to use them for managing a large number of 00446 * entities. If you need to manage a large number of entities, it's 00447 * recommended that you bind() an ACE_Hash_Map_Manager that 00448 * resides in shared memory, use find() to locate it, and then 00449 * store/retrieve the entities in the hash map. 00450 */ 00451 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00452 class ACE_Malloc_T 00453 { 00454 public: 00455 friend class ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>; 00456 friend class ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB>; 00457 typedef ACE_MEM_POOL MEMORY_POOL; 00458 typedef ACE_MEM_POOL_OPTIONS MEMORY_POOL_OPTIONS; 00459 typedef typename ACE_CB::ACE_Name_Node NAME_NODE; 00460 typedef typename ACE_CB::ACE_Malloc_Header MALLOC_HEADER; 00461 00462 // = Initialization and termination methods. 00463 /** 00464 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00465 * initialize the memory pool, and uses ACE::basename() to 00466 * automatically extract out the name used for the underlying lock 00467 * name (if necessary). 00468 * 00469 * Note that @a pool_name should be located in 00470 * a directory with the appropriate visibility and protection so 00471 * that all processes that need to access it can do so. 00472 */ 00473 ACE_Malloc_T (const ACE_TCHAR *pool_name = 0); 00474 00475 /** 00476 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00477 * initialize the memory pool, and uses @a lock_name to automatically 00478 * extract out the name used for the underlying lock name (if 00479 * necessary). In addition, @a options is passed through to 00480 * initialize the underlying memory pool. 00481 * 00482 * Note that @a pool_name should be located in 00483 * a directory with the appropriate visibility and protection so 00484 * that all processes that need to access it can do so. 00485 */ 00486 ACE_Malloc_T (const ACE_TCHAR *pool_name, 00487 const ACE_TCHAR *lock_name, 00488 const ACE_MEM_POOL_OPTIONS *options = 0); 00489 00490 /** 00491 * Initialize an ACE_Malloc with an external ACE_LOCK. 00492 * This constructor passes @a pool_name and @a options to initialize 00493 * the memory pool. @a lock is used as the pool lock, and must be 00494 * properly set up and ready for use before being passed to this method. 00495 */ 00496 ACE_Malloc_T (const ACE_TCHAR *pool_name, 00497 const ACE_MEM_POOL_OPTIONS *options, 00498 ACE_LOCK *lock); 00499 00500 #if !defined (ACE_HAS_TEMPLATE_TYPEDEFS) 00501 /// This is necessary to work around template bugs with certain C++ 00502 /// compilers. 00503 ACE_Malloc_T (const ACE_TCHAR *pool_name, 00504 const ACE_TCHAR *lock_name, 00505 const void *options = 0); 00506 #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ 00507 00508 /// Destructor 00509 ~ACE_Malloc_T (void); 00510 00511 /// Get Reference counter. 00512 int ref_counter (void); 00513 00514 /// Release ref counter. 00515 int release (int close = 0); 00516 00517 /// Releases resources allocated by this object. 00518 int remove (void); 00519 00520 // = Memory management 00521 00522 /// Allocate @a nbytes, but don't give them any initial value. 00523 void *malloc (size_t nbytes); 00524 00525 /// Allocate @a nbytes, giving them @a initial_value. 00526 void *calloc (size_t nbytes, char initial_value = '\0'); 00527 00528 /// Allocate @a n_elem each of size @a elem_size, giving them 00529 /// @a initial_value. 00530 void *calloc (size_t n_elem, 00531 size_t elem_size, 00532 char initial_value = '\0'); 00533 00534 /// Deallocate memory pointed to by @a ptr, which must have been 00535 /// allocated previously by malloc(). 00536 void free (void *ptr); 00537 00538 /// Returns a reference to the underlying memory pool. 00539 MEMORY_POOL &memory_pool (void); 00540 00541 // = Map manager like functions 00542 00543 /** 00544 * Associate @a name with @a pointer. If @a duplicates == 0 then do 00545 * not allow duplicate name/pointer associations, else if 00546 * @a duplicates != 0 then allow duplicate name/pointer 00547 * assocations. Returns 0 if successfully binds (1) a previously 00548 * unbound @a name or (2) @a duplicates != 0, returns 1 if trying to 00549 * bind a previously bound @a name and @a duplicates == 0, else 00550 * returns -1 if a resource failure occurs. 00551 */ 00552 int bind (const char *name, void *pointer, int duplicates = 0); 00553 00554 /** 00555 * Associate @a name with @a pointer. Does not allow duplicate 00556 * name/pointer associations. Returns 0 if successfully binds 00557 * (1) a previously unbound @a name, 1 if trying to bind a previously 00558 * bound @a name, or returns -1 if a resource failure occurs. When 00559 * this call returns @a pointer's value will always reference the 00560 * void * that @a name is associated with. Thus, if the caller needs 00561 * to use @a pointer (e.g., to free it) a copy must be maintained by 00562 * the caller. 00563 */ 00564 int trybind (const char *name, void *&pointer); 00565 00566 /// Locate @a name and pass out parameter via @a pointer. If found, 00567 /// return 0, returns -1 if failure occurs. 00568 int find (const char *name, void *&pointer); 00569 00570 /// Returns 0 if @a name is in the mapping. -1, otherwise. 00571 int find (const char *name); 00572 00573 /** 00574 * Unbind (remove) the name from the map. Don't return the pointer 00575 * to the caller. If you want to remove all occurrences of @a name 00576 * you'll need to call this method multiple times until it fails... 00577 */ 00578 int unbind (const char *name); 00579 00580 /** 00581 * Unbind (remove) one association of @a name to @a pointer. Returns 00582 * the value of pointer in case the caller needs to deallocate 00583 * memory. If you want to remove all occurrences of @a name you'll 00584 * need to call this method multiple times until it fails... 00585 */ 00586 int unbind (const char *name, void *&pointer); 00587 00588 // = Protection and "sync" (i.e., flushing data to backing store). 00589 00590 /** 00591 * Sync @a len bytes of the memory region to the backing store 00592 * starting at @c this->base_addr_. If @a len == -1 then sync the 00593 * whole region. 00594 */ 00595 int sync (ssize_t len = -1, int flags = MS_SYNC); 00596 00597 /// Sync @a len bytes of the memory region to the backing store 00598 /// starting at @c addr_. 00599 int sync (void *addr, size_t len, int flags = MS_SYNC); 00600 00601 /** 00602 * Change the protection of the pages of the mapped region to @a prot 00603 * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 00604 * then change protection of all pages in the mapped region. 00605 */ 00606 int protect (ssize_t len = -1, int prot = PROT_RDWR); 00607 00608 /// Change the protection of the pages of the mapped region to @a prot 00609 /// starting at @a addr up to @a len bytes. 00610 int protect (void *addr, size_t len, int prot = PROT_RDWR); 00611 00612 /** 00613 * Returns a count of the number of available chunks that can hold 00614 * @a size byte allocations. Function can be used to determine if you 00615 * have reached a water mark. This implies a fixed amount of allocated 00616 * memory. 00617 * 00618 * @param size The chunk size of that you would like a count of 00619 * @return Function returns the number of chunks of the given size 00620 * that would fit in the currently allocated memory. 00621 */ 00622 ssize_t avail_chunks (size_t size) const; 00623 00624 #if defined (ACE_HAS_MALLOC_STATS) 00625 /// Dump statistics of how malloc is behaving. 00626 void print_stats (void) const; 00627 #endif /* ACE_HAS_MALLOC_STATS */ 00628 00629 /// Returns a pointer to the lock used to provide mutual exclusion to 00630 /// an ACE_Malloc allocator. 00631 ACE_LOCK &mutex (void); 00632 00633 /// Dump the state of an object. 00634 void dump (void) const; 00635 00636 /// Declare the dynamic allocation hooks. 00637 ACE_ALLOC_HOOK_DECLARE; 00638 00639 /// Return cb_ptr value. 00640 void *base_addr (void); 00641 00642 /** 00643 * Bad flag. This operation should be called immediately after the 00644 * construction of the Malloc object to query whether the object was 00645 * constructed successfully. If not, the user should invoke @c 00646 * remove and release the object (it is not usable.) 00647 * @retval 0 if all is fine. non-zero if this malloc object is 00648 * unuable. 00649 */ 00650 int bad (void); 00651 00652 private: 00653 /// Initialize the Malloc pool. 00654 int open (void); 00655 00656 /// Associate @a name with @a pointer. Assumes that locks are held by 00657 /// callers. 00658 int shared_bind (const char *name, 00659 void *pointer); 00660 00661 /** 00662 * Try to locate @a name. If found, return the associated 00663 * ACE_Name_Node, else returns 0 if can't find the @a name. 00664 * Assumes that locks are held by callers. Remember to cast the 00665 * return value to ACE_CB::ACE_Name_Node*. 00666 */ 00667 void *shared_find (const char *name); 00668 00669 /// Allocate memory. Assumes that locks are held by callers. 00670 void *shared_malloc (size_t nbytes); 00671 00672 /// Deallocate memory. Assumes that locks are held by callers. 00673 void shared_free (void *ptr); 00674 00675 /// Pointer to the control block that is stored in memory controlled 00676 /// by <MEMORY_POOL>. 00677 ACE_CB *cb_ptr_; 00678 00679 /// Pool of memory used by ACE_Malloc to manage its freestore. 00680 MEMORY_POOL memory_pool_; 00681 00682 /// Lock that ensures mutual exclusion for the memory pool. 00683 ACE_LOCK *lock_; 00684 00685 /// True if destructor should delete the lock 00686 bool delete_lock_; 00687 00688 /// Keep track of failure in constructor. 00689 int bad_flag_; 00690 }; 00691 00692 /*****************************************************************************/ 00693 00694 /** 00695 * @class ACE_Malloc_Lock_Adapter_T 00696 * 00697 * @brief Template functor adapter for lock strategies used with ACE_Malloc_T. 00698 * 00699 * This class acts as a factory for lock strategies that have various ctor 00700 * signatures. If the lock strategy's ctor takes an ACE_TCHAR* as the first 00701 * and only required parameter, it will just work. Otherwise use template 00702 * specialization to create a version that matches the lock strategy's ctor 00703 * signature. See ACE_Process_Semaphore and ACE_Thread_Semaphore for 00704 * examples. 00705 * 00706 */ 00707 /*****************************************************************************/ 00708 00709 /** 00710 * @class ACE_Malloc_LIFO_Iterator_T 00711 * 00712 * @brief LIFO iterator for names stored in Malloc'd memory. 00713 * 00714 * This class can be configured flexibly with different types of 00715 * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a 00716 * ACE_Process_Mutex constructor API. 00717 * 00718 * Does not support deletions while iteration is occurring. 00719 */ 00720 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00721 class ACE_Malloc_LIFO_Iterator_T 00722 { 00723 public: 00724 typedef typename ACE_CB::ACE_Name_Node NAME_NODE; 00725 typedef typename ACE_CB::ACE_Malloc_Header MALLOC_HEADER; 00726 00727 // = Initialization method. 00728 /// If @a name = 0 it will iterate through everything else only 00729 /// through those entries whose @a name match. 00730 ACE_Malloc_LIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc, 00731 const char *name = 0); 00732 00733 /// Destructor. 00734 ~ACE_Malloc_LIFO_Iterator_T (void); 00735 00736 // = Iteration methods. 00737 00738 /// Returns 1 when all items have been seen, else 0. 00739 int done (void) const; 00740 00741 /// Pass back the next entry in the set that hasn't yet been 00742 /// visited. Returns 0 when all items have been seen, else 1. 00743 int next (void *&next_entry); 00744 00745 /** 00746 * Pass back the next entry (and the name associated with it) in 00747 * the set that hasn't yet been visited. Returns 0 when all items 00748 * have been seen, else 1. 00749 */ 00750 int next (void *&next_entry, 00751 const char *&name); 00752 00753 /// Move forward by one element in the set. Returns 0 when all the 00754 /// items in the set have been seen, else 1. 00755 int advance (void); 00756 00757 /// Dump the state of an object. 00758 void dump (void) const; 00759 00760 /// Declare the dynamic allocation hooks. 00761 ACE_ALLOC_HOOK_DECLARE; 00762 00763 private: 00764 /// Malloc we are iterating over. 00765 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc_; 00766 00767 /// Keeps track of how far we've advanced... 00768 NAME_NODE *curr_; 00769 00770 /// Lock Malloc for the lifetime of the iterator. 00771 ACE_Read_Guard<ACE_LOCK> guard_; 00772 00773 /// Name that we are searching for. 00774 const char *name_; 00775 }; 00776 00777 /** 00778 * @class ACE_Malloc_FIFO_Iterator_T 00779 * 00780 * @brief FIFO iterator for names stored in Malloc'd memory. 00781 * 00782 * This class can be configured flexibly with different types of 00783 * ACE_LOCK strategies that support the @a ACE_Thread_Mutex and @a 00784 * ACE_Process_Mutex constructor API. 00785 * 00786 * Does not support deletions while iteration is occurring. 00787 */ 00788 template <ACE_MEM_POOL_1, class ACE_LOCK, class ACE_CB> 00789 class ACE_Malloc_FIFO_Iterator_T 00790 { 00791 public: 00792 typedef typename ACE_CB::ACE_Name_Node NAME_NODE; 00793 typedef typename ACE_CB::ACE_Malloc_Header MALLOC_HEADER; 00794 00795 // = Initialization method. 00796 /// If @a name = 0 it will iterate through everything else only 00797 /// through those entries whose @a name match. 00798 ACE_Malloc_FIFO_Iterator_T (ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc, 00799 const char *name = 0); 00800 00801 /// Destructor. 00802 ~ACE_Malloc_FIFO_Iterator_T (void); 00803 00804 // = Iteration methods. 00805 00806 /// Returns 1 when all items have been seen, else 0. 00807 int done (void) const; 00808 00809 /// Pass back the next entry in the set that hasn't yet been 00810 /// visited. Returns 0 when all items have been seen, else 1. 00811 int next (void *&next_entry); 00812 00813 /** 00814 * Pass back the next entry (and the name associated with it) in 00815 * the set that hasn't yet been visited. Returns 0 when all items 00816 * have been seen, else 1. 00817 */ 00818 int next (void *&next_entry, 00819 const char *&name); 00820 00821 /// Move forward by one element in the set. Returns 0 when all the 00822 /// items in the set have been seen, else 1. 00823 int advance (void); 00824 00825 /// Go to the starting element that was inserted first. Returns 0 00826 /// when there is no item in the set, else 1. 00827 int start (void); 00828 00829 /// Dump the state of an object. 00830 void dump (void) const; 00831 00832 /// Declare the dynamic allocation hooks. 00833 ACE_ALLOC_HOOK_DECLARE; 00834 00835 private: 00836 /// Malloc we are iterating over. 00837 ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_CB> &malloc_; 00838 00839 /// Keeps track of how far we've advanced... 00840 NAME_NODE *curr_; 00841 00842 /// Lock Malloc for the lifetime of the iterator. 00843 ACE_Read_Guard<ACE_LOCK> guard_; 00844 00845 /// Name that we are searching for. 00846 const char *name_; 00847 }; 00848 00849 template <ACE_MEM_POOL_1, class ACE_LOCK> 00850 class ACE_Malloc : public ACE_Malloc_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> 00851 { 00852 public: 00853 // = Initialization and termination methods. 00854 /** 00855 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00856 * initialize the memory pool, and uses ACE::basename() to 00857 * automatically extract out the name used for the underlying lock 00858 * name (if necessary). Note that @a pool_name should be located in 00859 * a directory with the appropriate visibility and protection so 00860 * that all processes that need to access it can do so. 00861 */ 00862 ACE_Malloc (const ACE_TCHAR *pool_name = 0); 00863 00864 /** 00865 * Initialize ACE_Malloc. This constructor passes @a pool_name to 00866 * initialize the memory pool, and uses @a lock_name to automatically 00867 * extract out the name used for the underlying lock name (if 00868 * necessary). In addition, @a options is passed through to 00869 * initialize the underlying memory pool. Note that @a pool_name 00870 * should be located in a directory with the appropriate visibility 00871 * and protection so that all processes that need to access it can 00872 * do so. 00873 */ 00874 ACE_Malloc (const ACE_TCHAR *pool_name, 00875 const ACE_TCHAR *lock_name, 00876 const ACE_MEM_POOL_OPTIONS *options = 0); 00877 00878 #if !defined (ACE_HAS_TEMPLATE_TYPEDEFS) 00879 /// This is necessary to work around template bugs with certain C++ 00880 /// compilers. 00881 ACE_Malloc (const ACE_TCHAR *pool_name, 00882 const ACE_TCHAR *lock_name, 00883 const void *options = 0); 00884 #endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ 00885 }; 00886 00887 template <ACE_MEM_POOL_1, class ACE_LOCK> 00888 class ACE_Malloc_LIFO_Iterator : public ACE_Malloc_LIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> 00889 { 00890 public: 00891 // = Initialization method. 00892 /// If @a name = 0 it will iterate through everything else only 00893 /// through those entries whose @a name match. 00894 ACE_Malloc_LIFO_Iterator (ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK> &malloc, 00895 const char *name = 0); 00896 }; 00897 00898 template <ACE_MEM_POOL_1, class ACE_LOCK> 00899 class ACE_Malloc_FIFO_Iterator : public ACE_Malloc_FIFO_Iterator_T<ACE_MEM_POOL_2, ACE_LOCK, ACE_Control_Block> 00900 { 00901 public: 00902 // = Initialization method. 00903 /// If @a name = 0 it will iterate through everything else only 00904 /// through those entries whose @a name match. 00905 ACE_Malloc_FIFO_Iterator (ACE_Malloc<ACE_MEM_POOL_2, ACE_LOCK> &malloc, 00906 const char *name = 0); 00907 }; 00908 00909 template <class ACE_LOCK> 00910 class ACE_Malloc_Lock_Adapter_T 00911 { 00912 public: 00913 ACE_LOCK * operator () (const ACE_TCHAR *myname); 00914 }; 00915 00916 ACE_END_VERSIONED_NAMESPACE_DECL 00917 00918 #if defined (__ACE_INLINE__) 00919 #include "ace/Malloc_T.inl" 00920 #endif /* __ACE_INLINE__ */ 00921 00922 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00923 #include "ace/Malloc_T.cpp" 00924 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00925 00926 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00927 #pragma implementation ("Malloc_T.cpp") 00928 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00929 00930 #include /**/ "ace/post.h" 00931 #endif /* ACE_MALLOC_H */