Malloc_T.h

Go to the documentation of this file.
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 */

Generated on Thu Nov 9 09:41:54 2006 for ACE by doxygen 1.3.6