Restore build on FreeBSD.
[getmangos.git] / dep / ACE_wrappers / ace / Malloc.h
blob7b59f8ae1d0012b9e7ab5b2627b860249b3f729f
1 // -*- C++ -*-
3 //==========================================================================
4 /**
5 * @file Malloc.h
7 * $Id: Malloc.h 81796 2008-05-28 13:46:21Z sma $
9 * @author Doug Schmidt and Irfan Pyarali
11 //==========================================================================
13 #ifndef ACE_MALLOC_H
14 #define ACE_MALLOC_H
16 #include /**/ "ace/pre.h"
18 #include /**/ "ace/ACE_export.h"
20 #if !defined (ACE_LACKS_PRAGMA_ONCE)
21 # pragma once
22 #endif /* ACE_LACKS_PRAGMA_ONCE */
24 #include "ace/Log_Msg.h"
26 #if defined (ACE_HAS_MALLOC_STATS)
27 # include "ace/Atomic_Op.h"
28 # if defined (ACE_HAS_THREADS)
29 # include "ace/Process_Mutex.h"
30 # define ACE_PROCESS_MUTEX ACE_Process_Mutex
31 # else /* ACE_HAS_THREADS */
32 # include "ace/SV_Semaphore_Simple.h"
33 # define ACE_PROCESS_MUTEX ACE_SV_Semaphore_Simple
34 # endif /* ACE_HAS_THREADS */
37 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
39 typedef ACE_Atomic_Op<ACE_PROCESS_MUTEX, int> ACE_INT;
41 /******************************************************************
43 * Assume that ACE_MALLOC_ALIGN is the number of bytes of the alignment
44 of the platform. Usually, this will be 4 on most platforms. Some
45 platforms require this to be 8. In any case, this macro should
46 always be a 2's power.
48 * Malloc_Header structure.
50 Notice that sizeof (ACE_Malloc_Header) must be multiple of
51 ACE_MALLOC_ALIGN
53 +-----------------------------------------+
54 |MALLOC_HEADER_PTR *next_block_; |
55 | // Points to next free Malloc_Header |
56 | // in this chain. |
57 +-----------------------------------------+
58 |size_t size_; |
59 | // Size of buffer associate with |
60 | // this Malloc_Header |
61 } // The size is in number of |
62 | // Malloc_Header (including this one.)|
63 +-----------------------------------------+
64 |char paddings_[ACE_MALLOC_PADDING_SIZE]; |
65 | // Padding array. This purpose |
66 | // of this padding array is to adjust |
67 | // the sizeof (Malloc_Header) to be |
68 | // multiple of ACE_MALLOC_ALIGN. |
69 +-----------------------------------------+
71 * Name_Node
73 ACE_Malloc allows searching thru it's allocated buffer using names.
74 Name_Node is an internal data structure that ACE_Malloc used to
75 maintain a linked list that manages this (name, buffer) mappings.
77 +-----------------------------------------+
78 |char *name_; |
79 | // Points to a dynamically allocated |
80 | // char buffer that holds the name |
81 | // of this node. This buffer is |
82 | // allocated from using this |
83 | // ACE_MALLOC instance that owns this |
84 | // Name_Node (so it always points to |
85 | // a buffer owned by its Malloc. |
86 +-----------------------------------------+
87 |char *pointer_; |
88 | // Points to the content that <name_> |
89 | // referring to. Like <name_>, the |
90 | // context always resides within the |
91 | // Malloc. |
92 +-----------------------------------------+
93 |NAME_NODE_PTR next_; |
94 +-----------------------------------------+
95 |NAME_NODE_PTR prev_; |
96 | // Name Node linked list pointers. |
97 +-----------------------------------------+
100 * Control_Block
102 Only the first ACE_Malloc instance that uses
103 the shared memory will initialize the control block because all
104 later instances are supposed to share the memory with the first
105 instance. The following diagram shows the initial value of a
106 Control_Block.
108 +-----------------------------------------+
109 |NAME_NODE_PTR name_head_; |<---- NULL.
110 | // Entry point for double-linked list.|
111 | // Initialized to NULL pointer to |
112 | // indicate an empty list. |
113 +-----------------------------------------+
114 |MALLOC_HEADER_PTR freep_; |
115 | // Pointer to last un-allocated |
116 | // malloc_header linked list. |---+
117 +-----------------------------------------+ |
118 |char lock_name_[MAXNAMELEN]; | |
119 | // The global name of the lock. | |
120 +-----------------------------------------+ |
121 |Malloc_Stats malloc_stats_; | |
122 | // (Optional statistic information. | |
123 | // Do not exist if | |
124 | // ACE_HAS_MALLOC_STATS is not | |
125 | // defined. | |
126 +-----------------------------------------+ |
127 |char align_[CONTROL_BLOCK_ALIGN_BYTES]; | |
128 | // | |
129 +-----------------------------------------+ |
130 |Malloc_Header base_; |<--+
131 | // Dummy node used to anchor the |
132 | // freelist. |<--+
133 | +-------------+ |
134 | |next_ |---+
135 | +-------------+
136 | |size_ |----> 0
137 +-----------------------------------------+
139 The first ACE_Malloc initializes the control block by allocating a
140 memory block of size equal to or greater than sizeof (control block)
141 (rounded to the closest <rounded_bytes>) and invokes the placement
142 new's on to initialize the control block and its internal
143 pointers/data structures. If the extra memory (memory after the
144 <base_> in the following diagram) is enough to create a
145 Malloc_Header chain, one is created and added to the freelist list.
146 That is, if the memory size returned by init_acquire() is greater
147 than the sizeof Control_Block, the control block is initialized to
148 the following diagram:
151 +-------------------------------------
152 |name_head_; |
153 +-------------------------------------+
154 |MALLOC_HEADER_PTR freep_; |--+
155 +-------------------------------------+ |
156 |lock_name_[...]; | |
157 +-------------------------------------+ |
158 |malloc_stats_; (Optional) | |
159 +-------------------------------------+ |
160 |align_[...]; | |
161 +-------------------------------------+ |
162 |Malloc_Header base_; |<-+
163 | +-----------+
164 | |next_; |--+
165 | +-----------+ |
166 | |size_ = 0; | |
167 +=====================================+ |
168 |Malloc_Header base_; |<-+
169 | +-----------+
170 | |next_; |
171 | +-----------+
172 | |size_ = 3; |
173 +-------------------------------------+
174 |Malloc_Header base_; |
175 | +-----------+
176 | (Uninitialized) |next_; |
177 | +-----------+
178 | |size_; |
179 +-------------------------------------+
180 |Malloc_Header base_; |
181 | +-----------+
182 | (Uninitialized) |next_; |
183 | +-----------+
184 | |size_; |
185 +-------------------------------------+
187 ***********************************************************/
189 /// This keeps stats on the usage of the memory manager.
190 struct ACE_Export ACE_Malloc_Stats
192 ACE_Malloc_Stats (void);
193 void dump (void) const;
195 /// Coarse-grained unit of allocation.
196 ACE_INT nchunks_;
198 /// Fine-grained unit of allocation.
199 ACE_INT nblocks_;
201 /// Number of blocks in use
202 ACE_INT ninuse_;
205 ACE_END_VERSIONED_NAMESPACE_DECL
207 # define ACE_MALLOC_STATS(X) X
208 #else
209 # define ACE_MALLOC_STATS(X)
210 #endif /* ACE_HAS_MALLOC_STATS */
212 #if !defined (ACE_MALLOC_PADDING)
213 // ACE_MALLOC_PADDING allows you to insure that allocated regions are
214 // at least <ACE_MALLOC_PADDING> bytes long. It is especially useful
215 // when you want areas to be at least a page long, or 32K long, or
216 // something like that.
218 # define ACE_MALLOC_PADDING 1
219 #endif /* ACE_MALLOC_PADDING */
221 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
223 union ACE_max_align_info
225 int (*i)();
226 void* p;
227 long l;
228 double d;
231 #if !defined (ACE_MALLOC_ALIGN)
232 // Align the malloc header size to a multiple of a double.
233 # define ACE_MALLOC_ALIGN (sizeof (ACE_max_align_info))
234 #endif /* ACE_MALLOC_ALIGN */
236 #if !defined ACE_MALLOC_ROUNDUP
237 # define ACE_MALLOC_ROUNDUP(X, Y) (((X) + ((Y) - 1)) & ~((Y) - 1))
238 #endif
240 // ACE_MALLOC_HEADER_SIZE is the normalized malloc header size.
241 #define ACE_MALLOC_HEADER_SIZE ACE_MALLOC_ROUNDUP(ACE_MALLOC_PADDING, ACE_MALLOC_ALIGN)
244 * @class ACE_Control_Block
246 * @brief This information is stored in memory allocated by the <Memory_Pool>.
248 * This class defines the "old" control block class for use in
249 * ACE_Malloc_T. This control block implementation is
250 * considerable more efficient than the "position independent"
251 * one below (ACE_PI_Control_Block) but if you are going to use
252 * it to construct a ACE_Malloc_T and access the memory from
253 * several different processes, you must "map" the underlying
254 * memory pool to the same address.
256 class ACE_Export ACE_Control_Block
258 public:
261 * @class ACE_Malloc_Header
263 * @brief This is the control block header. It's used by <ACE_Malloc>
264 * to keep track of each chunk of data when it's in the free
265 * list or in use.
267 class ACE_Export ACE_Malloc_Header
269 public:
270 ACE_Malloc_Header (void);
272 /// Points to next block if on free list.
273 ACE_Malloc_Header *next_block_;
275 /// Initialize a malloc header pointer.
276 static void init_ptr (ACE_Malloc_Header **ptr,
277 ACE_Malloc_Header *init,
278 void *base_addr);
280 /// Size of this header control block.
281 size_t size_;
283 # if !defined (ACE_MALLOC_PADDING_SIZE)
284 # 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))
285 # endif /* !ACE_MALLOC_PADDING_SIZE */
286 char padding_[(ACE_MALLOC_PADDING_SIZE) ? ACE_MALLOC_PADDING_SIZE : ACE_MALLOC_ALIGN];
288 /// Dump the state of the object.
289 void dump (void) const;
293 * @class ACE_Name_Node
295 * @brief This class supports "named memory regions" within ACE_Malloc.
297 * Internally, the named memory regions are stored as a
298 * doubly-linked list within the @c Memory_Pool. This makes
299 * it easy to iterate over the items in the list in both FIFO
300 * and LIFO order.
302 class ACE_Export ACE_Name_Node
304 public:
305 // = Initialization methods.
306 /// Constructor.
307 ACE_Name_Node (const char *name,
308 char *name_ptr,
309 char *pointer,
310 ACE_Name_Node *head);
312 /// Constructor.
313 ACE_Name_Node (void);
315 /// Constructor.
316 ~ACE_Name_Node (void);
318 /// Initialize a name node pointer.
319 static void init_ptr (ACE_Name_Node **ptr,
320 ACE_Name_Node *init,
321 void *base_addr);
323 /// Return a pointer to the name of this node.
324 const char *name (void) const;
326 /// Name of the Node.
327 char *name_;
329 /// Pointer to the contents.
330 char *pointer_;
332 /// Pointer to the next node in the doubly-linked list.
333 ACE_Name_Node *next_;
335 /// Pointer to the previous node in the doubly-linked list.
336 ACE_Name_Node *prev_;
338 /// Dump the state of the object.
339 void dump (void) const;
340 private:
341 /// Copy constructor.
342 ACE_Name_Node (const ACE_Name_Node &);
345 /// Print out a bunch of size info for debugging.
346 static void print_alignment_info (void);
348 /// Reference counter.
349 int ref_counter_;
351 /// Head of the linked list of Name Nodes.
352 ACE_Name_Node *name_head_;
354 /// Current head of the freelist.
355 ACE_Malloc_Header *freep_;
357 /// Name of lock thats ensures mutual exclusion.
358 char lock_name_[MAXNAMELEN];
360 #if defined (ACE_HAS_MALLOC_STATS)
361 /// Keep statistics about ACE_Malloc state and performance.
362 ACE_Malloc_Stats malloc_stats_;
363 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
364 + sizeof (ACE_Malloc_Header*) \
365 + sizeof (int) \
366 + MAXNAMELEN \
367 + sizeof (ACE_Malloc_Stats)))
368 #else
369 #define ACE_CONTROL_BLOCK_SIZE ((int)(sizeof (ACE_Name_Node*) \
370 + sizeof (ACE_Malloc_Header*) \
371 + sizeof (int) \
372 + MAXNAMELEN))
373 #endif /* ACE_HAS_MALLOC_STATS */
375 # if !defined (ACE_CONTROL_BLOCK_ALIGN_BYTES)
376 # define ACE_CONTROL_BLOCK_ALIGN_BYTES \
377 ACE_MALLOC_ROUNDUP (ACE_CONTROL_BLOCK_SIZE, ACE_MALLOC_ALIGN) - ACE_CONTROL_BLOCK_SIZE
378 # endif /* !ACE_CONTROL_BLOCK_ALIGN_BYTES */
379 char align_[(ACE_CONTROL_BLOCK_ALIGN_BYTES) ? ACE_CONTROL_BLOCK_ALIGN_BYTES : ACE_MALLOC_ALIGN];
381 /// Dummy node used to anchor the freelist. This needs to come last...
382 ACE_Malloc_Header base_;
384 /// Dump the state of the object.
385 void dump (void) const;
388 ACE_END_VERSIONED_NAMESPACE_DECL
390 #if defined (__ACE_INLINE__)
391 #include "ace/Malloc.inl"
392 #endif /* __ACE_INLINE__ */
394 #include /**/ "ace/post.h"
396 #endif /* ACE_MALLOC_H */