3 //==========================================================================
7 * @author Doug Schmidt and Irfan Pyarali
9 //==========================================================================
14 #include /**/ "ace/pre.h"
16 #include /**/ "ace/ACE_export.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #include "ace/Log_Category.h"
24 #if defined (ACE_HAS_MALLOC_STATS)
25 # include "ace/Atomic_Op.h"
26 # if defined (ACE_HAS_THREADS)
27 # include "ace/Process_Mutex.h"
28 # define ACE_PROCESS_MUTEX ACE_Process_Mutex
29 # else /* ACE_HAS_THREADS */
30 # include "ace/SV_Semaphore_Simple.h"
31 # define ACE_PROCESS_MUTEX ACE_SV_Semaphore_Simple
32 # endif /* ACE_HAS_THREADS */
35 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
37 typedef ACE_Atomic_Op
<ACE_PROCESS_MUTEX
, int> ACE_INT
;
39 /******************************************************************
41 * Assume that ACE_MALLOC_ALIGN is the number of bytes of the alignment
42 of the platform. Usually, this will be 4 on most platforms. Some
43 platforms require this to be 8. In any case, this macro should
44 always be a 2's power.
46 * Malloc_Header structure.
48 Notice that sizeof (ACE_Malloc_Header) must be multiple of
51 +-----------------------------------------+
52 |MALLOC_HEADER_PTR *next_block_; |
53 | // Points to next free Malloc_Header |
55 +-----------------------------------------+
57 | // Size of buffer associate with |
58 | // this Malloc_Header |
59 } // The size is in number of |
60 | // Malloc_Header (including this one.)|
61 +-----------------------------------------+
62 |char paddings_[ACE_MALLOC_PADDING_SIZE]; |
63 | // Padding array. This purpose |
64 | // of this padding array is to adjust |
65 | // the sizeof (Malloc_Header) to be |
66 | // multiple of ACE_MALLOC_ALIGN. |
67 +-----------------------------------------+
71 ACE_Malloc allows searching thru it's allocated buffer using names.
72 Name_Node is an internal data structure that ACE_Malloc used to
73 maintain a linked list that manages this (name, buffer) mappings.
75 +-----------------------------------------+
77 | // Points to a dynamically allocated |
78 | // char buffer that holds the name |
79 | // of this node. This buffer is |
80 | // allocated from using this |
81 | // ACE_MALLOC instance that owns this |
82 | // Name_Node (so it always points to |
83 | // a buffer owned by its Malloc. |
84 +-----------------------------------------+
86 | // Points to the content that <name_> |
87 | // referring to. Like <name_>, the |
88 | // context always resides within the |
90 +-----------------------------------------+
91 |NAME_NODE_PTR next_; |
92 +-----------------------------------------+
93 |NAME_NODE_PTR prev_; |
94 | // Name Node linked list pointers. |
95 +-----------------------------------------+
100 Only the first ACE_Malloc instance that uses
101 the shared memory will initialize the control block because all
102 later instances are supposed to share the memory with the first
103 instance. The following diagram shows the initial value of a
106 +-----------------------------------------+
107 |NAME_NODE_PTR name_head_; |<---- NULL.
108 | // Entry point for double-linked list.|
109 | // Initialized to NULL pointer to |
110 | // indicate an empty list. |
111 +-----------------------------------------+
112 |MALLOC_HEADER_PTR freep_; |
113 | // Pointer to last un-allocated |
114 | // malloc_header linked list. |---+
115 +-----------------------------------------+ |
116 |char lock_name_[MAXNAMELEN]; | |
117 | // The global name of the lock. | |
118 +-----------------------------------------+ |
119 |Malloc_Stats malloc_stats_; | |
120 | // (Optional statistic information. | |
121 | // Do not exist if | |
122 | // ACE_HAS_MALLOC_STATS is not | |
124 +-----------------------------------------+ |
125 |char align_[CONTROL_BLOCK_ALIGN_BYTES]; | |
127 +-----------------------------------------+ |
128 |Malloc_Header base_; |<--+
129 | // Dummy node used to anchor the |
135 +-----------------------------------------+
137 The first ACE_Malloc initializes the control block by allocating a
138 memory block of size equal to or greater than sizeof (control block)
139 (rounded to the closest <rounded_bytes>) and invokes the placement
140 new's on to initialize the control block and its internal
141 pointers/data structures. If the extra memory (memory after the
142 <base_> in the following diagram) is enough to create a
143 Malloc_Header chain, one is created and added to the freelist list.
144 That is, if the memory size returned by init_acquire() is greater
145 than the sizeof Control_Block, the control block is initialized to
146 the following diagram:
149 +-------------------------------------
151 +-------------------------------------+
152 |MALLOC_HEADER_PTR freep_; |--+
153 +-------------------------------------+ |
154 |lock_name_[...]; | |
155 +-------------------------------------+ |
156 |malloc_stats_; (Optional) | |
157 +-------------------------------------+ |
159 +-------------------------------------+ |
160 |Malloc_Header base_; |<-+
165 +=====================================+ |
166 |Malloc_Header base_; |<-+
171 +-------------------------------------+
172 |Malloc_Header base_; |
174 | (Uninitialized) |next_; |
177 +-------------------------------------+
178 |Malloc_Header base_; |
180 | (Uninitialized) |next_; |
183 +-------------------------------------+
185 ***********************************************************/
187 /// This keeps stats on the usage of the memory manager.
188 struct ACE_Export ACE_Malloc_Stats
193 /// Coarse-grained unit of allocation.
196 /// Fine-grained unit of allocation.
199 /// Number of blocks in use
203 ACE_END_VERSIONED_NAMESPACE_DECL
205 # define ACE_MALLOC_STATS(X) X
207 # define ACE_MALLOC_STATS(X)
208 #endif /* ACE_HAS_MALLOC_STATS */
210 #if !defined (ACE_MALLOC_PADDING)
211 // ACE_MALLOC_PADDING allows you to insure that allocated regions are
212 // at least <ACE_MALLOC_PADDING> bytes long. It is especially useful
213 // when you want areas to be at least a page long, or 32K long, or
214 // something like that.
216 # define ACE_MALLOC_PADDING 1
217 #endif /* ACE_MALLOC_PADDING */
219 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
221 union ACE_max_align_info
229 #if !defined (ACE_MALLOC_ALIGN)
230 // Align the malloc header size to a multiple of a double.
231 # define ACE_MALLOC_ALIGN (sizeof (ACE_max_align_info))
232 #endif /* ACE_MALLOC_ALIGN */
234 #if !defined ACE_MALLOC_ROUNDUP
235 # define ACE_MALLOC_ROUNDUP(X, Y) (((X) + ((Y) - 1)) & ~((Y) - 1))
238 // ACE_MALLOC_HEADER_SIZE is the normalized malloc header size.
239 #define ACE_MALLOC_HEADER_SIZE ACE_MALLOC_ROUNDUP(ACE_MALLOC_PADDING, ACE_MALLOC_ALIGN)
242 * @class ACE_Control_Block
244 * @brief This information is stored in memory allocated by the <Memory_Pool>.
246 * This class defines the "old" control block class for use in
247 * ACE_Malloc_T. This control block implementation is
248 * considerable more efficient than the "position independent"
249 * one below (ACE_PI_Control_Block) but if you are going to use
250 * it to construct a ACE_Malloc_T and access the memory from
251 * several different processes, you must "map" the underlying
252 * memory pool to the same address.
254 class ACE_Export ACE_Control_Block
258 * @class ACE_Malloc_Header
260 * @brief This is the control block header. It's used by <ACE_Malloc>
261 * to keep track of each chunk of data when it's in the free
264 class ACE_Export ACE_Malloc_Header
267 ACE_Malloc_Header ();
269 /// Points to next block if on free list.
270 ACE_Malloc_Header
*next_block_
;
272 /// Initialize a malloc header pointer.
273 static void init_ptr (ACE_Malloc_Header
**ptr
,
274 ACE_Malloc_Header
*init
,
277 /// Size of this header control block.
280 # if !defined (ACE_MALLOC_PADDING_SIZE)
281 # 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))
282 # endif /* !ACE_MALLOC_PADDING_SIZE */
283 char padding_
[(ACE_MALLOC_PADDING_SIZE
) ? ACE_MALLOC_PADDING_SIZE
: ACE_MALLOC_ALIGN
];
285 /// Dump the state of the object.
290 * @class ACE_Name_Node
292 * @brief This class supports "named memory regions" within ACE_Malloc.
294 * Internally, the named memory regions are stored as a
295 * doubly-linked list within the @c Memory_Pool. This makes
296 * it easy to iterate over the items in the list in both FIFO
299 class ACE_Export ACE_Name_Node
303 ACE_Name_Node (const char *name
,
306 ACE_Name_Node
*head
);
314 /// Initialize a name node pointer.
315 static void init_ptr (ACE_Name_Node
**ptr
,
319 /// Return a pointer to the name of this node.
320 const char *name () const;
322 /// Name of the Node.
325 /// Pointer to the contents.
328 /// Pointer to the next node in the doubly-linked list.
329 ACE_Name_Node
*next_
;
331 /// Pointer to the previous node in the doubly-linked list.
332 ACE_Name_Node
*prev_
;
334 /// Dump the state of the object.
337 /// Copy constructor.
338 ACE_Name_Node (const ACE_Name_Node
&);
341 /// Print out a bunch of size info for debugging.
342 static void print_alignment_info ();
344 /// Reference counter.
347 /// Head of the linked list of Name Nodes.
348 ACE_Name_Node
*name_head_
;
350 /// Current head of the freelist.
351 ACE_Malloc_Header
*freep_
;
353 /// Name of lock thats ensures mutual exclusion.
354 char lock_name_
[MAXNAMELEN
];
356 #if defined (ACE_HAS_MALLOC_STATS)
357 /// Keep statistics about ACE_Malloc state and performance.
358 ACE_Malloc_Stats malloc_stats_
;
359 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
360 + sizeof (ACE_Malloc_Header*) \
363 + sizeof (ACE_Malloc_Stats)))
365 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
366 + sizeof (ACE_Malloc_Header*) \
369 #endif /* ACE_HAS_MALLOC_STATS */
371 # if !defined (ACE_CONTROL_BLOCK_ALIGN_BYTES)
372 # define ACE_CONTROL_BLOCK_ALIGN_BYTES \
373 ACE_MALLOC_ROUNDUP (ACE_CONTROL_BLOCK_SIZE, ACE_MALLOC_ALIGN) - ACE_CONTROL_BLOCK_SIZE
374 # endif /* !ACE_CONTROL_BLOCK_ALIGN_BYTES */
375 char align_
[(ACE_CONTROL_BLOCK_ALIGN_BYTES
) ? ACE_CONTROL_BLOCK_ALIGN_BYTES
: ACE_MALLOC_ALIGN
];
377 /// Dummy node used to anchor the freelist. This needs to come last...
378 ACE_Malloc_Header base_
;
380 /// Dump the state of the object.
384 ACE_END_VERSIONED_NAMESPACE_DECL
386 #if defined (__ACE_INLINE__)
387 #include "ace/Malloc.inl"
388 #endif /* __ACE_INLINE__ */
390 #include /**/ "ace/post.h"
392 #endif /* ACE_MALLOC_H */