Document return values
[ACE_TAO.git] / ACE / ace / Malloc.h
blob06b9eb6cbe37fd092949dac0705d71ab2de9e822
1 // -*- C++ -*-
3 //==========================================================================
4 /**
5 * @file Malloc.h
7 * @author Doug Schmidt and Irfan Pyarali
8 */
9 //==========================================================================
11 #ifndef ACE_MALLOC_H
12 #define ACE_MALLOC_H
14 #include /**/ "ace/pre.h"
16 #include /**/ "ace/ACE_export.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 # 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
49 ACE_MALLOC_ALIGN
51 +-----------------------------------------+
52 |MALLOC_HEADER_PTR *next_block_; |
53 | // Points to next free Malloc_Header |
54 | // in this chain. |
55 +-----------------------------------------+
56 |size_t size_; |
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 +-----------------------------------------+
69 * Name_Node
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 +-----------------------------------------+
76 |char *name_; |
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 +-----------------------------------------+
85 |char *pointer_; |
86 | // Points to the content that <name_> |
87 | // referring to. Like <name_>, the |
88 | // context always resides within the |
89 | // Malloc. |
90 +-----------------------------------------+
91 |NAME_NODE_PTR next_; |
92 +-----------------------------------------+
93 |NAME_NODE_PTR prev_; |
94 | // Name Node linked list pointers. |
95 +-----------------------------------------+
98 * Control_Block
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
104 Control_Block.
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 | |
123 | // defined. | |
124 +-----------------------------------------+ |
125 |char align_[CONTROL_BLOCK_ALIGN_BYTES]; | |
126 | // | |
127 +-----------------------------------------+ |
128 |Malloc_Header base_; |<--+
129 | // Dummy node used to anchor the |
130 | // freelist. |<--+
131 | +-------------+ |
132 | |next_ |---+
133 | +-------------+
134 | |size_ |----> 0
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 +-------------------------------------
150 |name_head_; |
151 +-------------------------------------+
152 |MALLOC_HEADER_PTR freep_; |--+
153 +-------------------------------------+ |
154 |lock_name_[...]; | |
155 +-------------------------------------+ |
156 |malloc_stats_; (Optional) | |
157 +-------------------------------------+ |
158 |align_[...]; | |
159 +-------------------------------------+ |
160 |Malloc_Header base_; |<-+
161 | +-----------+
162 | |next_; |--+
163 | +-----------+ |
164 | |size_ = 0; | |
165 +=====================================+ |
166 |Malloc_Header base_; |<-+
167 | +-----------+
168 | |next_; |
169 | +-----------+
170 | |size_ = 3; |
171 +-------------------------------------+
172 |Malloc_Header base_; |
173 | +-----------+
174 | (Uninitialized) |next_; |
175 | +-----------+
176 | |size_; |
177 +-------------------------------------+
178 |Malloc_Header base_; |
179 | +-----------+
180 | (Uninitialized) |next_; |
181 | +-----------+
182 | |size_; |
183 +-------------------------------------+
185 ***********************************************************/
187 /// This keeps stats on the usage of the memory manager.
188 struct ACE_Export ACE_Malloc_Stats
190 ACE_Malloc_Stats ();
191 void dump () const;
193 /// Coarse-grained unit of allocation.
194 ACE_INT nchunks_;
196 /// Fine-grained unit of allocation.
197 ACE_INT nblocks_;
199 /// Number of blocks in use
200 ACE_INT ninuse_;
203 ACE_END_VERSIONED_NAMESPACE_DECL
205 # define ACE_MALLOC_STATS(X) X
206 #else
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
223 int (*i)();
224 void* p;
225 long l;
226 double d;
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))
236 #endif
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
256 public:
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
262 * list or in use.
264 class ACE_Export ACE_Malloc_Header
266 public:
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,
275 void *base_addr);
277 /// Size of this header control block.
278 size_t size_;
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.
286 void dump () const;
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
297 * and LIFO order.
299 class ACE_Export ACE_Name_Node
301 public:
302 /// Constructor.
303 ACE_Name_Node (const char *name,
304 char *name_ptr,
305 char *pointer,
306 ACE_Name_Node *head);
308 /// Constructor.
309 ACE_Name_Node ();
311 /// Constructor.
312 ~ACE_Name_Node ();
314 /// Initialize a name node pointer.
315 static void init_ptr (ACE_Name_Node **ptr,
316 ACE_Name_Node *init,
317 void *base_addr);
319 /// Return a pointer to the name of this node.
320 const char *name () const;
322 /// Name of the Node.
323 char *name_;
325 /// Pointer to the contents.
326 char *pointer_;
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.
335 void dump () const;
336 private:
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.
345 int ref_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*) \
361 + sizeof (int) \
362 + MAXNAMELEN \
363 + sizeof (ACE_Malloc_Stats)))
364 #else
365 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
366 + sizeof (ACE_Malloc_Header*) \
367 + sizeof (int) \
368 + MAXNAMELEN))
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.
381 void dump () const;
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 */