Malloc.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //==========================================================================
00004 /**
00005  *  @file    Malloc.h
00006  *
00007  *  Malloc.h,v 4.88 2005/11/29 07:39:36 jwillemsen Exp
00008  *
00009  *  @author Doug Schmidt and Irfan Pyarali
00010  */
00011 //==========================================================================
00012 
00013 #ifndef ACE_MALLOC_H
00014 #define ACE_MALLOC_H
00015 
00016 #include /**/ "ace/pre.h"
00017 
00018 #include "ace/ACE_export.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "ace/Log_Msg.h"
00025 
00026 #if defined (ACE_HAS_MALLOC_STATS)
00027 #  include "ace/Atomic_Op.h"
00028 #  if defined (ACE_HAS_THREADS)
00029 #    include "ace/Process_Mutex.h"
00030 #    define ACE_PROCESS_MUTEX ACE_Process_Mutex
00031 #  else /* ACE_HAS_THREADS */
00032 #    include "ace/SV_Semaphore_Simple.h"
00033 #    define ACE_PROCESS_MUTEX ACE_SV_Semaphore_Simple
00034 #  endif /* ACE_HAS_THREADS */
00035 
00036 
00037 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00038 
00039 typedef ACE_Atomic_Op<ACE_PROCESS_MUTEX, int> ACE_INT;
00040 
00041 /******************************************************************
00042 
00043 * Assume that ACE_MALLOC_ALIGN is the number of bytes of the alignment
00044   of the platform. Usually, this will be 4 on most platforms.  Some
00045   platforms require this to be 8.  In any case, this macro should
00046   always be a 2's power.
00047 
00048 * Malloc_Header structure.
00049 
00050   Notice that sizeof (ACE_Malloc_Header) must be multiple of
00051   ACE_MALLOC_ALIGN
00052 
00053    +-----------------------------------------+
00054    |MALLOC_HEADER_PTR *next_block_;          |
00055    |   // Points to next free Malloc_Header  |
00056    |   // in this chain.                     |
00057    +-----------------------------------------+
00058    |size_t size_;                            |
00059    |   // Size of buffer associate with      |
00060    |   // this Malloc_Header                 |
00061    }   // The size is in number of           |
00062    |   // Malloc_Header (including this one.)|
00063    +-----------------------------------------+
00064    |char paddings_[ACE_MALLOC_PADDING_SIZE]; |
00065    |   // Padding array.  This purpose  |
00066    |   // of this padding array is to adjust |
00067    |   // the sizeof (Malloc_Header) to be   |
00068    |   // multiple of ACE_MALLOC_ALIGN.      |
00069    +-----------------------------------------+
00070 
00071 * Name_Node
00072 
00073   ACE_Malloc allows searching thru it's allocated buffer using names.
00074   Name_Node is an internal data structure that ACE_Malloc used to
00075   maintain a linked list that manages this (name, buffer) mappings.
00076 
00077    +-----------------------------------------+
00078    |char *name_;                             |
00079    |   // Points to a dynamically allocated  |
00080    |   // char buffer that holds the name    |
00081    |   // of this node.  This buffer is      |
00082    |   // allocated from using this          |
00083    |   // ACE_MALLOC instance that owns this |
00084    |   // Name_Node (so it always points to  |
00085    |   // a buffer owned by its Malloc.      |
00086    +-----------------------------------------+
00087    |char *pointer_;                          |
00088    |   // Points to the content that <name_> |
00089    |   // referring to.  Like <name_>, the   |
00090    |   // context always resides within the  |
00091    |   // Malloc.                            |
00092    +-----------------------------------------+
00093    |NAME_NODE_PTR next_;                     |
00094    +-----------------------------------------+
00095    |NAME_NODE_PTR prev_;                     |
00096    |   // Name Node linked list pointers.    |
00097    +-----------------------------------------+
00098 
00099 
00100 * Control_Block
00101 
00102   Only the first ACE_Malloc instance that uses
00103   the shared memory will initialize the control block because all
00104   later instances are supposed to share the memory with the first
00105   instance.  The following diagram shows the initial value of a
00106   Control_Block.
00107 
00108    +-----------------------------------------+
00109    |NAME_NODE_PTR name_head_;                |<---- NULL
00110    |   // Entry point for double-linked list.|
00111    |   // Initialized to NULL pointer to     |
00112    |   // indicate an empty list.            |
00113    +-----------------------------------------+
00114    |MALLOC_HEADER_PTR freep_;                |
00115    |   // Pointer to last un-allocated       |
00116    |   // malloc_header linked list.         |---+
00117    +-----------------------------------------+   |
00118    |char lock_name_[MAXNAMELEN];             |   |
00119    |   // The global name of the lock.       |   |
00120    +-----------------------------------------+   |
00121    |Malloc_Stats malloc_stats_;              |   |
00122    |   // (Optional statistic information.   |   |
00123    |   //  Do not exist if                   |   |
00124    |   //  ACE_HAS_MALLOC_STATS is not       |   |
00125    |   //  defined.                          |   |
00126    +-----------------------------------------+   |
00127    |char align_[CONTROL_BLOCK_ALIGN_BYTES];  |   |
00128    |   //                                    |   |
00129    +-----------------------------------------+   |
00130    |Malloc_Header base_;                     |<--+
00131    |  // Dummy node used to anchor the       |
00132    |  // freelist.                           |<--+
00133    |                           +-------------+   |
00134    |                           |next_        |---+
00135    |                           +-------------+
00136    |                           |size_        |----> 0
00137    +-----------------------------------------+
00138 
00139   The first ACE_Malloc initializes the control block by allocating a
00140   memory block of size equal to or greater than sizeof (control block)
00141   (rounded to the closest <rounded_bytes>) and invokes the placement
00142   new's on to initialize the control block and its internal
00143   pointers/data structures.  If the extra memory (memory after the
00144   <base_> in the following diagram) is enough to create a
00145   Malloc_Header chain, one is created and added to the freelist list.
00146   That is, if the memory size returned by init_acquire() is greater
00147   than the sizeof Control_Block, the control block is initialized to
00148   the following diagram:
00149 
00150 
00151    +-------------------------------------
00152    |name_head_;                          |
00153    +-------------------------------------+
00154    |MALLOC_HEADER_PTR freep_;            |--+
00155    +-------------------------------------+  |
00156    |lock_name_[...];                     |  |
00157    +-------------------------------------+  |
00158    |malloc_stats_; (Optional)            |  |
00159    +-------------------------------------+  |
00160    |align_[...];                         |  |
00161    +-------------------------------------+  |
00162    |Malloc_Header base_;                 |<-+
00163    |                         +-----------+
00164    |                         |next_;     |--+
00165    |                         +-----------+  |
00166    |                         |size_ = 0; |  |
00167    +=====================================+  |
00168    |Malloc_Header base_;                 |<-+
00169    |                         +-----------+
00170    |                         |next_;     |
00171    |                         +-----------+
00172    |                         |size_ = 3; |
00173    +-------------------------------------+
00174    |Malloc_Header base_;                 |
00175    |                         +-----------+
00176    |   (Uninitialized)       |next_;     |
00177    |                         +-----------+
00178    |                         |size_;     |
00179    +-------------------------------------+
00180    |Malloc_Header base_;                 |
00181    |                         +-----------+
00182    |   (Uninitialized)       |next_;     |
00183    |                         +-----------+
00184    |                         |size_;     |
00185    +-------------------------------------+
00186 
00187 ***********************************************************/
00188 
00189 /// This keeps stats on the usage of the memory manager.
00190 struct ACE_Export ACE_Malloc_Stats
00191 {
00192   ACE_Malloc_Stats (void);
00193   void dump (void) const;
00194 
00195   /// Coarse-grained unit of allocation.
00196   ACE_INT nchunks_;
00197 
00198   /// Fine-grained unit of allocation.
00199   ACE_INT nblocks_;
00200 
00201   /// Number of blocks in use
00202   ACE_INT ninuse_;
00203 };
00204 
00205 ACE_END_VERSIONED_NAMESPACE_DECL
00206 
00207 #  define ACE_MALLOC_STATS(X) X
00208 #else
00209 #  define ACE_MALLOC_STATS(X)
00210 #endif /* ACE_HAS_MALLOC_STATS */
00211 
00212 #if !defined (ACE_MALLOC_PADDING)
00213 // ACE_MALLOC_PADDING allows you to insure that allocated regions are
00214 // at least <ACE_MALLOC_PADDING> bytes long.  It is especially useful
00215 // when you want areas to be at least a page long, or 32K long, or
00216 // something like that.
00217 
00218 #  define ACE_MALLOC_PADDING 1
00219 #endif /* ACE_MALLOC_PADDING */
00220 
00221 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00222 
00223 union ACE_max_align_info
00224 {
00225   int (*i)();
00226   void* p;
00227   long l;
00228   double d;
00229 };
00230 
00231 #if !defined (ACE_MALLOC_ALIGN)
00232 // Align the malloc header size to a multiple of a double.
00233 #  define ACE_MALLOC_ALIGN (sizeof (ACE_max_align_info))
00234 #endif /* ACE_MALLOC_ALIGN */
00235 
00236 #if !defined ACE_MALLOC_ROUNDUP
00237 #  define ACE_MALLOC_ROUNDUP(X, Y) ((X) + ((Y) - 1) & ~((Y) - 1))
00238 #endif
00239 
00240 // ACE_MALLOC_HEADER_SIZE is the normalized malloc header size.
00241 #define ACE_MALLOC_HEADER_SIZE ACE_MALLOC_ROUNDUP(ACE_MALLOC_PADDING, ACE_MALLOC_ALIGN)
00242 
00243 /**
00244  * @class ACE_Control_Block
00245  *
00246  * @brief This information is stored in memory allocated by the <Memory_Pool>.
00247  *
00248  * This class defines the "old" control block class for use in
00249  * ACE_Malloc_T.  This control block implementation is
00250  * considerable more efficient than the "position independent"
00251  * one below (ACE_PI_Control_Block) but if you are going to use
00252  * it to construct a ACE_Malloc_T and access the memory from
00253  * several different processes, you must "map" the underlying
00254  * memory pool to the same address.
00255  */
00256 class ACE_Export ACE_Control_Block
00257 {
00258 public:
00259 
00260   /**
00261    * @class ACE_Malloc_Header
00262    *
00263    * @brief This is the control block header.  It's used by <ACE_Malloc>
00264    * to keep track of each chunk of data when it's in the free
00265    * list or in use.
00266    */
00267   class ACE_Export ACE_Malloc_Header
00268   {
00269   public:
00270     ACE_Malloc_Header (void);
00271 
00272     /// Points to next block if on free list.
00273     ACE_Malloc_Header *next_block_;
00274 
00275     /// Initialize a malloc header pointer.
00276     static void init_ptr (ACE_Malloc_Header **ptr,
00277                           ACE_Malloc_Header *init,
00278                           void *base_addr);
00279 
00280     /// Size of this header control block.
00281     size_t size_;
00282 
00283 # if !defined (ACE_MALLOC_PADDING_SIZE)
00284 #   define ACE_MALLOC_PADDING_SIZE ACE_MALLOC_ROUNDUP (ACE_MALLOC_HEADER_SIZE + sizeof (ACE_Malloc_Header*) + sizeof (size_t), ACE_MALLOC_ALIGN) - (sizeof (ACE_Malloc_Header*) + sizeof (size_t))
00285 # endif /* !ACE_MALLOC_PADDING_SIZE */
00286     char padding_[(ACE_MALLOC_PADDING_SIZE) ? ACE_MALLOC_PADDING_SIZE : ACE_MALLOC_ALIGN];
00287 
00288     /// Dump the state of the object.
00289     void dump (void) const;
00290   };
00291 
00292   /**
00293    * @class ACE_Name_Node
00294    *
00295    * @brief This class supports "named memory regions" within ACE_Malloc.
00296    *
00297    * Internally, the named memory regions are stored as a
00298    * doubly-linked list within the @c Memory_Pool.  This makes
00299    * it easy to iterate over the items in the list in both FIFO
00300    * and LIFO order.
00301    */
00302   class ACE_Export ACE_Name_Node
00303   {
00304   public:
00305     // = Initialization methods.
00306     /// Constructor.
00307     ACE_Name_Node (const char *name,
00308                    char *name_ptr,
00309                    char *pointer,
00310                    ACE_Name_Node *head);
00311 
00312     /// Constructor.
00313     ACE_Name_Node (void);
00314 
00315     /// Constructor.
00316     ~ACE_Name_Node (void);
00317 
00318     /// Initialize a name node pointer.
00319     static void init_ptr (ACE_Name_Node **ptr,
00320                           ACE_Name_Node *init,
00321                           void *base_addr);
00322 
00323     /// Return a pointer to the name of this node.
00324     const char *name (void) const;
00325 
00326     /// Name of the Node.
00327     char *name_;
00328 
00329     /// Pointer to the contents.
00330     char *pointer_;
00331 
00332     /// Pointer to the next node in the doubly-linked list.
00333     ACE_Name_Node *next_;
00334 
00335     /// Pointer to the previous node in the doubly-linked list.
00336     ACE_Name_Node *prev_;
00337 
00338     /// Dump the state of the object.
00339     void dump (void) const;
00340   private:
00341     /// Copy constructor.
00342     ACE_Name_Node (const ACE_Name_Node &);
00343   };
00344 
00345   /// Print out a bunch of size info for debugging.
00346   static void print_alignment_info (void);
00347 
00348   /// Reference counter.
00349   int ref_counter_;
00350 
00351   /// Head of the linked list of Name Nodes.
00352   ACE_Name_Node *name_head_;
00353 
00354   /// Current head of the freelist.
00355   ACE_Malloc_Header *freep_;
00356 
00357   /// Name of lock thats ensures mutual exclusion.
00358   char lock_name_[MAXNAMELEN];
00359 
00360 #if defined (ACE_HAS_MALLOC_STATS)
00361   /// Keep statistics about ACE_Malloc state and performance.
00362   ACE_Malloc_Stats malloc_stats_;
00363 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
00364                                       + sizeof (ACE_Malloc_Header*) \
00365                                       + sizeof (int) \
00366                                       + MAXNAMELEN  \
00367                                       + sizeof (ACE_Malloc_Stats)))
00368 #else
00369 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
00370                                       + sizeof (ACE_Malloc_Header*) \
00371                                       + sizeof (int) \
00372                                       + MAXNAMELEN))
00373 #endif /* ACE_HAS_MALLOC_STATS */
00374 
00375 # if !defined (ACE_CONTROL_BLOCK_ALIGN_BYTES)
00376 #   define ACE_CONTROL_BLOCK_ALIGN_BYTES \
00377         ACE_MALLOC_ROUNDUP (ACE_CONTROL_BLOCK_SIZE, ACE_MALLOC_ALIGN) - ACE_CONTROL_BLOCK_SIZE
00378 # endif /* !ACE_CONTROL_BLOCK_ALIGN_BYTES */
00379   char align_[(ACE_CONTROL_BLOCK_ALIGN_BYTES) ? ACE_CONTROL_BLOCK_ALIGN_BYTES : ACE_MALLOC_ALIGN];
00380 
00381   /// Dummy node used to anchor the freelist.  This needs to come last...
00382   ACE_Malloc_Header base_;
00383 
00384   /// Dump the state of the object.
00385   void dump (void) const;
00386 };
00387 
00388 ACE_END_VERSIONED_NAMESPACE_DECL
00389 
00390 #if defined (__ACE_INLINE__)
00391 #include "ace/Malloc.inl"
00392 #endif /* __ACE_INLINE__ */
00393 
00394 #include /**/ "ace/post.h"
00395 
00396 #endif /* ACE_MALLOC_H */

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