1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
// -*- C++ -*-
//==========================================================================
/**
* @file PI_Malloc.h
*
* $Id$
*
* @author Priyanka Gontla <pgontla@ece.uci.edu>
* @author Based on code that existed in other ACE files.
*/
//==========================================================================
#ifndef ACE_PI_MALLOC_H
#define ACE_PI_MALLOC_H
#include /**/ "ace/pre.h"
#include /**/ "ace/ACE_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
#include "ace/Malloc.h"
#include "ace/Based_Pointer_T.h"
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
// prepare for position independent malloc
/**
* @class ACE_PI_Control_Block
*
* @brief This information is stored in memory allocated by the Memory_Pool.
*
* This class implements the control block structure that can be
* used in a "position indepent" fashion, i.e., you don't need to
* "map" the underlying memory pool to the same address in
* processes sharing the memory. The tradoff of this flexibility
* is more expensive malloc/free operations.
*/
class ACE_Export ACE_PI_Control_Block
{
public:
class ACE_Malloc_Header;
class ACE_Name_Node;
typedef ACE_Based_Pointer<ACE_Malloc_Header> MALLOC_HEADER_PTR;
typedef ACE_Based_Pointer<ACE_Name_Node> NAME_NODE_PTR;
typedef ACE_Based_Pointer_Basic<char> CHAR_PTR;
/**
* @class ACE_Malloc_Header
*
* @brief This is the control block header. It's used by ACE_Malloc
* to keep track of each chunk of data when it's in the free
* list or in use.
*/
class ACE_Export ACE_Malloc_Header
{
public:
ACE_Malloc_Header (void);
/// Points to next block if on free list.
MALLOC_HEADER_PTR next_block_;
/// Initialize a malloc header pointer.
static void init_ptr (MALLOC_HEADER_PTR *ptr,
ACE_Malloc_Header *init,
void *base_addr);
/// Size of this header control block.
size_t size_;
# if !defined (ACE_PI_MALLOC_PADDING_SIZE)
# define ACE_PI_MALLOC_PADDING_SIZE ACE_MALLOC_ROUNDUP (ACE_MALLOC_HEADER_SIZE + sizeof (MALLOC_HEADER_PTR) + sizeof (size_t), ACE_MALLOC_ALIGN) - (sizeof (MALLOC_HEADER_PTR) + sizeof (size_t))
# endif /* !ACE_PI_MALLOC_PADDING_SIZE */
char padding_[(ACE_PI_MALLOC_PADDING_SIZE) ? ACE_PI_MALLOC_PADDING_SIZE : ACE_MALLOC_ALIGN];
/// Dump the state of the object.
void dump (void) const;
private:
// Disallow copy construction and assignment.
ACE_Malloc_Header (ACE_Malloc_Header const &);
void operator= (ACE_Malloc_Header const &);
};
/**
* @class ACE_Name_Node
*
* @brief This class supports "named memory regions" within ACE_Malloc.
*
* Internally, the named memory regions are stored as a
* doubly-linked list within the Memory_Pool. This makes
* it easy to iterate over the items in the list in both FIFO
* and LIFO order.
*/
class ACE_Export ACE_Name_Node
{
public:
// = Initialization methods.
/// Constructor.
ACE_Name_Node (const char *name,
char *name_ptr,
char *pointer,
ACE_Name_Node *head);
/// Copy constructor.
ACE_Name_Node (const ACE_Name_Node &);
/// Constructor.
ACE_Name_Node (void);
/// Constructor.
~ACE_Name_Node (void);
/// Initialize a name node pointer.
static void init_ptr (NAME_NODE_PTR *ptr,
ACE_Name_Node *init,
void *base_addr);
/// Return a pointer to the name of this node.
const char *name (void) const;
/// Assign a name;
void name (const char *);
/// Name of the Node.
CHAR_PTR name_;
/// Pointer to the contents.
CHAR_PTR pointer_;
/// Pointer to the next node in the doubly-linked list.
NAME_NODE_PTR next_;
/// Pointer to the previous node in the doubly-linked list.
NAME_NODE_PTR prev_;
/// Dump the state of the object.
void dump (void) const;
private:
// Disallow assignment.
void operator= (const ACE_Name_Node &);
};
/// Print out a bunch of size info for debugging.
static void print_alignment_info (void);
/// Reference counter.
int ref_counter_;
/// Head of the linked list of Name Nodes.
NAME_NODE_PTR name_head_;
/// Current head of the freelist.
MALLOC_HEADER_PTR freep_;
/// Name of lock thats ensures mutual exclusion.
char lock_name_[MAXNAMELEN];
#if defined (ACE_HAS_MALLOC_STATS)
/// Keep statistics about ACE_Malloc state and performance.
ACE_Malloc_Stats malloc_stats_;
#define ACE_PI_CONTROL_BLOCK_SIZE ((int)(sizeof (NAME_NODE_PTR) \
+ sizeof (MALLOC_HEADER_PTR) \
+ sizeof (int) \
+ MAXNAMELEN \
+ sizeof (ACE_Malloc_Stats)))
#else
#define ACE_PI_CONTROL_BLOCK_SIZE ((int)(sizeof (NAME_NODE_PTR) \
+ sizeof (MALLOC_HEADER_PTR) \
+ sizeof (int) \
+ MAXNAMELEN))
#endif /* ACE_HAS_MALLOC_STATS */
# if !defined (ACE_PI_CONTROL_BLOCK_ALIGN_BYTES)
# define ACE_PI_CONTROL_BLOCK_ALIGN_BYTES \
ACE_MALLOC_ROUNDUP (ACE_PI_CONTROL_BLOCK_SIZE, ACE_MALLOC_ALIGN) - ACE_PI_CONTROL_BLOCK_SIZE
# endif /* !ACE_PI_CONTROL_BLOCK_ALIGN_LONGS */
/// Force alignment.
char align_[(ACE_PI_CONTROL_BLOCK_ALIGN_BYTES) ? ACE_PI_CONTROL_BLOCK_ALIGN_BYTES : ACE_MALLOC_ALIGN];
/// Dummy node used to anchor the freelist. This needs to come last...
ACE_Malloc_Header base_;
/// Dump the state of the object.
void dump (void) const;
private:
// Disallow assignment.
void operator= (const ACE_Control_Block &);
};
ACE_END_VERSIONED_NAMESPACE_DECL
#if defined (__ACE_INLINE__)
#include "ace/PI_Malloc.inl"
#endif /* __ACE_INLINE__ */
#endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
#include /**/ "ace/post.h"
#endif /* ACE_PI_MALLOC_H */
|