Chris@102
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
Chris@102
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@102
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
6 //
|
Chris@102
|
7 // See http://www.boost.org/libs/container for documentation.
|
Chris@102
|
8 //
|
Chris@102
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
10 #ifndef BOOST_CONTAINER_ALLOC_LIB_EXT_H
|
Chris@102
|
11 #define BOOST_CONTAINER_ALLOC_LIB_EXT_H
|
Chris@102
|
12
|
Chris@102
|
13 #include <stddef.h>
|
Chris@102
|
14
|
Chris@102
|
15 #ifdef _MSC_VER
|
Chris@102
|
16 #pragma warning (push)
|
Chris@102
|
17 #pragma warning (disable : 4127)
|
Chris@102
|
18
|
Chris@102
|
19 /*
|
Chris@102
|
20 we need to import/export our code only if the user has specifically
|
Chris@102
|
21 asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
|
Chris@102
|
22 libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK
|
Chris@102
|
23 if they want just this one to be dynamically liked:
|
Chris@102
|
24 */
|
Chris@102
|
25 #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
Chris@102
|
26
|
Chris@102
|
27 /* export if this is our own source, otherwise import: */
|
Chris@102
|
28 #ifdef BOOST_CONTAINER_SOURCE
|
Chris@102
|
29 # define BOOST_CONTAINER_DECL __declspec(dllexport)
|
Chris@102
|
30 #else
|
Chris@102
|
31 # define BOOST_CONTAINER_DECL __declspec(dllimport)
|
Chris@102
|
32 #endif /* BOOST_CONTAINER_SOURCE */
|
Chris@102
|
33 #endif /* DYN_LINK */
|
Chris@102
|
34 #endif /* _MSC_VER */
|
Chris@102
|
35
|
Chris@102
|
36 /* if BOOST_CONTAINER_DECL isn't defined yet define it now: */
|
Chris@102
|
37 #ifndef BOOST_CONTAINER_DECL
|
Chris@102
|
38 #define BOOST_CONTAINER_DECL
|
Chris@102
|
39 #endif
|
Chris@102
|
40
|
Chris@102
|
41 #ifdef __cplusplus
|
Chris@102
|
42 extern "C" {
|
Chris@102
|
43 #endif
|
Chris@102
|
44
|
Chris@102
|
45 /*!An forward iterator to traverse the elements of a memory chain container.*/
|
Chris@102
|
46 typedef struct multialloc_node_impl
|
Chris@102
|
47 {
|
Chris@102
|
48 struct multialloc_node_impl *next_node_ptr;
|
Chris@102
|
49 } boost_cont_memchain_node;
|
Chris@102
|
50
|
Chris@102
|
51
|
Chris@102
|
52 /*!An forward iterator to traverse the elements of a memory chain container.*/
|
Chris@102
|
53 typedef struct multialloc_it_impl
|
Chris@102
|
54 {
|
Chris@102
|
55 boost_cont_memchain_node *node_ptr;
|
Chris@102
|
56 } boost_cont_memchain_it;
|
Chris@102
|
57
|
Chris@102
|
58 /*!Memory chain: A container holding memory portions allocated by boost_cont_multialloc_nodes
|
Chris@102
|
59 and boost_cont_multialloc_arrays functions.*/
|
Chris@102
|
60 typedef struct boost_cont_memchain_impl
|
Chris@102
|
61 {
|
Chris@102
|
62 size_t num_mem;
|
Chris@102
|
63 boost_cont_memchain_node root_node;
|
Chris@102
|
64 boost_cont_memchain_node *last_node_ptr;
|
Chris@102
|
65 } boost_cont_memchain;
|
Chris@102
|
66
|
Chris@102
|
67 /*!Advances the iterator one position so that it points to the next element in the memory chain*/
|
Chris@102
|
68 #define BOOST_CONTAINER_MEMIT_NEXT(IT) (IT.node_ptr = IT.node_ptr->next_node_ptr)
|
Chris@102
|
69
|
Chris@102
|
70 /*!Returns the address of the memory chain currently pointed by the iterator*/
|
Chris@102
|
71 #define BOOST_CONTAINER_MEMIT_ADDR(IT) ((void*)IT.node_ptr)
|
Chris@102
|
72
|
Chris@102
|
73 /*!Initializer for an iterator pointing to the position before the first element*/
|
Chris@102
|
74 #define BOOST_CONTAINER_MEMCHAIN_BEFORE_BEGIN_IT(PMEMCHAIN) { &((PMEMCHAIN)->root_node) }
|
Chris@102
|
75
|
Chris@102
|
76 /*!Initializer for an iterator pointing to the first element*/
|
Chris@102
|
77 #define BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(PMEMCHAIN) {(PMEMCHAIN)->root_node.next_node_ptr }
|
Chris@102
|
78
|
Chris@102
|
79 /*!Initializer for an iterator pointing to the last element*/
|
Chris@102
|
80 #define BOOST_CONTAINER_MEMCHAIN_LAST_IT(PMEMCHAIN) {(PMEMCHAIN)->last_node_ptr }
|
Chris@102
|
81
|
Chris@102
|
82 /*!Initializer for an iterator pointing to one past the last element (end iterator)*/
|
Chris@102
|
83 #define BOOST_CONTAINER_MEMCHAIN_END_IT(PMEMCHAIN) {(boost_cont_memchain_node *)0 }
|
Chris@102
|
84
|
Chris@102
|
85 /*!True if IT is the end iterator, false otherwise*/
|
Chris@102
|
86 #define BOOST_CONTAINER_MEMCHAIN_IS_END_IT(PMEMCHAIN, IT) (!(IT).node_ptr)
|
Chris@102
|
87
|
Chris@102
|
88 /*!The address of the first memory portion hold by the memory chain*/
|
Chris@102
|
89 #define BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(PMEMCHAIN)((void*)((PMEMCHAIN)->root_node.next_node_ptr))
|
Chris@102
|
90
|
Chris@102
|
91 /*!The address of the last memory portion hold by the memory chain*/
|
Chris@102
|
92 #define BOOST_CONTAINER_MEMCHAIN_LASTMEM(PMEMCHAIN) ((void*)((PMEMCHAIN)->last_node_ptr))
|
Chris@102
|
93
|
Chris@102
|
94 /*!The number of memory portions hold by the memory chain*/
|
Chris@102
|
95 #define BOOST_CONTAINER_MEMCHAIN_SIZE(PMEMCHAIN) ((PMEMCHAIN)->num_mem)
|
Chris@102
|
96
|
Chris@102
|
97 /*!Initializes the memory chain from the first memory portion, the last memory
|
Chris@102
|
98 portion and number of portions obtained from another memory chain*/
|
Chris@102
|
99 #define BOOST_CONTAINER_MEMCHAIN_INIT_FROM(PMEMCHAIN, FIRST, LAST, NUM)\
|
Chris@102
|
100 (PMEMCHAIN)->last_node_ptr = (boost_cont_memchain_node *)(LAST), \
|
Chris@102
|
101 (PMEMCHAIN)->root_node.next_node_ptr = (boost_cont_memchain_node *)(FIRST), \
|
Chris@102
|
102 (PMEMCHAIN)->num_mem = (NUM);\
|
Chris@102
|
103 /**/
|
Chris@102
|
104
|
Chris@102
|
105 /*!Default initializes a memory chain. Postconditions: begin iterator is end iterator,
|
Chris@102
|
106 the number of portions is zero.*/
|
Chris@102
|
107 #define BOOST_CONTAINER_MEMCHAIN_INIT(PMEMCHAIN)\
|
Chris@102
|
108 ((PMEMCHAIN)->root_node.next_node_ptr = 0, (PMEMCHAIN)->last_node_ptr = &((PMEMCHAIN)->root_node), (PMEMCHAIN)->num_mem = 0)\
|
Chris@102
|
109 /**/
|
Chris@102
|
110
|
Chris@102
|
111 /*!True if the memory chain is empty (holds no memory portions*/
|
Chris@102
|
112 #define BOOST_CONTAINER_MEMCHAIN_EMPTY(PMEMCHAIN)\
|
Chris@102
|
113 ((PMEMCHAIN)->num_mem == 0)\
|
Chris@102
|
114 /**/
|
Chris@102
|
115
|
Chris@102
|
116 /*!Inserts a new memory portions in the front of the chain*/
|
Chris@102
|
117 #define BOOST_CONTAINER_MEMCHAIN_PUSH_BACK(PMEMCHAIN, MEM)\
|
Chris@102
|
118 do{\
|
Chris@102
|
119 boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
Chris@102
|
120 boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
|
Chris@102
|
121 ____chain____->last_node_ptr->next_node_ptr = ____tmp_mem____;\
|
Chris@102
|
122 ____tmp_mem____->next_node_ptr = 0;\
|
Chris@102
|
123 ____chain____->last_node_ptr = ____tmp_mem____;\
|
Chris@102
|
124 ++____chain____->num_mem;\
|
Chris@102
|
125 }while(0)\
|
Chris@102
|
126 /**/
|
Chris@102
|
127
|
Chris@102
|
128 /*!Inserts a new memory portions in the back of the chain*/
|
Chris@102
|
129 #define BOOST_CONTAINER_MEMCHAIN_PUSH_FRONT(PMEMCHAIN, MEM)\
|
Chris@102
|
130 do{\
|
Chris@102
|
131 boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
Chris@102
|
132 boost_cont_memchain_node *____tmp_mem____ = (boost_cont_memchain_node *)(MEM);\
|
Chris@102
|
133 boost_cont_memchain *____root____ = &((PMEMCHAIN)->root_node);\
|
Chris@102
|
134 if(!____chain____->root_node.next_node_ptr){\
|
Chris@102
|
135 ____chain____->last_node_ptr = ____tmp_mem____;\
|
Chris@102
|
136 }\
|
Chris@102
|
137 boost_cont_memchain_node *____old_first____ = ____root____->next_node_ptr;\
|
Chris@102
|
138 ____tmp_mem____->next_node_ptr = ____old_first____;\
|
Chris@102
|
139 ____root____->next_node_ptr = ____tmp_mem____;\
|
Chris@102
|
140 ++____chain____->num_mem;\
|
Chris@102
|
141 }while(0)\
|
Chris@102
|
142 /**/
|
Chris@102
|
143
|
Chris@102
|
144 /*!Erases the memory portion after the portion pointed by BEFORE_IT from the memory chain*/
|
Chris@102
|
145 /*!Precondition: BEFORE_IT must be a valid iterator of the memory chain and it can't be the end iterator*/
|
Chris@102
|
146 #define BOOST_CONTAINER_MEMCHAIN_ERASE_AFTER(PMEMCHAIN, BEFORE_IT)\
|
Chris@102
|
147 do{\
|
Chris@102
|
148 boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
Chris@102
|
149 boost_cont_memchain_node *____prev_node____ = (BEFORE_IT).node_ptr;\
|
Chris@102
|
150 boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
|
Chris@102
|
151 if(____chain____->last_node_ptr == ____erase_node____){\
|
Chris@102
|
152 ____chain____->last_node_ptr = &____chain____->root_node;\
|
Chris@102
|
153 }\
|
Chris@102
|
154 ____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
|
Chris@102
|
155 --____chain____->num_mem;\
|
Chris@102
|
156 }while(0)\
|
Chris@102
|
157 /**/
|
Chris@102
|
158
|
Chris@102
|
159 /*!Erases the first portion from the memory chain.
|
Chris@102
|
160 Precondition: the memory chain must not be empty*/
|
Chris@102
|
161 #define BOOST_CONTAINER_MEMCHAIN_POP_FRONT(PMEMCHAIN)\
|
Chris@102
|
162 do{\
|
Chris@102
|
163 boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
Chris@102
|
164 boost_cont_memchain_node *____prev_node____ = &____chain____->root_node;\
|
Chris@102
|
165 boost_cont_memchain_node *____erase_node____ = ____prev_node____->next_node_ptr;\
|
Chris@102
|
166 if(____chain____->last_node_ptr == ____erase_node____){\
|
Chris@102
|
167 ____chain____->last_node_ptr = &____chain____->root_node;\
|
Chris@102
|
168 }\
|
Chris@102
|
169 ____prev_node____->next_node_ptr = ____erase_node____->next_node_ptr;\
|
Chris@102
|
170 --____chain____->num_mem;\
|
Chris@102
|
171 }while(0)\
|
Chris@102
|
172 /**/
|
Chris@102
|
173
|
Chris@102
|
174 /*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
|
Chris@102
|
175 /*
|
Chris@102
|
176 #define BOOST_CONTAINER_MEMCHAIN_SPLICE_BACK(PMEMCHAIN, PMEMCHAIN2)\
|
Chris@102
|
177 do{\
|
Chris@102
|
178 boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
Chris@102
|
179 boost_cont_memchain *____chain2____ = (PMEMCHAIN2);\
|
Chris@102
|
180 if(!____chain2____->root_node.next_node_ptr){\
|
Chris@102
|
181 break;\
|
Chris@102
|
182 }\
|
Chris@102
|
183 else if(!____chain____->first_mem){\
|
Chris@102
|
184 ____chain____->first_mem = ____chain2____->first_mem;\
|
Chris@102
|
185 ____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
|
Chris@102
|
186 ____chain____->num_mem = ____chain2____->num_mem;\
|
Chris@102
|
187 BOOST_CONTAINER_MEMCHAIN_INIT(*____chain2____);\
|
Chris@102
|
188 }\
|
Chris@102
|
189 else{\
|
Chris@102
|
190 ____chain____->last_node_ptr->next_node_ptr = ____chain2____->first_mem;\
|
Chris@102
|
191 ____chain____->last_node_ptr = ____chain2____->last_node_ptr;\
|
Chris@102
|
192 ____chain____->num_mem += ____chain2____->num_mem;\
|
Chris@102
|
193 }\
|
Chris@102
|
194 }while(0)\*/
|
Chris@102
|
195 /**/
|
Chris@102
|
196
|
Chris@102
|
197 /*!Joins two memory chains inserting the portions of the second chain at the back of the first chain*/
|
Chris@102
|
198 #define BOOST_CONTAINER_MEMCHAIN_INCORPORATE_AFTER(PMEMCHAIN, BEFORE_IT, FIRST, BEFORELAST, NUM)\
|
Chris@102
|
199 do{\
|
Chris@102
|
200 boost_cont_memchain *____chain____ = (PMEMCHAIN);\
|
Chris@102
|
201 boost_cont_memchain_node *____pnode____ = (BEFORE_IT).node_ptr;\
|
Chris@102
|
202 boost_cont_memchain_node *____next____ = ____pnode____->next_node_ptr;\
|
Chris@102
|
203 boost_cont_memchain_node *____first____ = (boost_cont_memchain_node *)(FIRST);\
|
Chris@102
|
204 boost_cont_memchain_node *____blast____ = (boost_cont_memchain_node *)(BEFORELAST);\
|
Chris@102
|
205 size_t ____num____ = (NUM);\
|
Chris@102
|
206 if(!____num____){\
|
Chris@102
|
207 break;\
|
Chris@102
|
208 }\
|
Chris@102
|
209 if(____pnode____ == ____chain____->last_node_ptr){\
|
Chris@102
|
210 ____chain____->last_node_ptr = ____blast____;\
|
Chris@102
|
211 }\
|
Chris@102
|
212 ____pnode____->next_node_ptr = ____first____;\
|
Chris@102
|
213 ____blast____->next_node_ptr = ____next____;\
|
Chris@102
|
214 ____chain____->num_mem += ____num____;\
|
Chris@102
|
215 }while(0)\
|
Chris@102
|
216 /**/
|
Chris@102
|
217
|
Chris@102
|
218 BOOST_CONTAINER_DECL size_t boost_cont_size(const void *p);
|
Chris@102
|
219
|
Chris@102
|
220 BOOST_CONTAINER_DECL void* boost_cont_malloc(size_t bytes);
|
Chris@102
|
221
|
Chris@102
|
222 BOOST_CONTAINER_DECL void boost_cont_free(void* mem);
|
Chris@102
|
223
|
Chris@102
|
224 BOOST_CONTAINER_DECL void* boost_cont_memalign(size_t bytes, size_t alignment);
|
Chris@102
|
225
|
Chris@102
|
226 /*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
Chris@102
|
227 must be contiguous.*/
|
Chris@102
|
228 #define DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1))
|
Chris@102
|
229
|
Chris@102
|
230 /*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
|
Chris@102
|
231 should be selected by those functions.*/
|
Chris@102
|
232 #define DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0))
|
Chris@102
|
233
|
Chris@102
|
234 BOOST_CONTAINER_DECL int boost_cont_multialloc_nodes
|
Chris@102
|
235 (size_t n_elements, size_t elem_size, size_t contiguous_elements, boost_cont_memchain *pchain);
|
Chris@102
|
236
|
Chris@102
|
237 BOOST_CONTAINER_DECL int boost_cont_multialloc_arrays
|
Chris@102
|
238 (size_t n_elements, const size_t *sizes, size_t sizeof_element, size_t contiguous_elements, boost_cont_memchain *pchain);
|
Chris@102
|
239
|
Chris@102
|
240 BOOST_CONTAINER_DECL void boost_cont_multidealloc(boost_cont_memchain *pchain);
|
Chris@102
|
241
|
Chris@102
|
242 BOOST_CONTAINER_DECL size_t boost_cont_footprint();
|
Chris@102
|
243
|
Chris@102
|
244 BOOST_CONTAINER_DECL size_t boost_cont_allocated_memory();
|
Chris@102
|
245
|
Chris@102
|
246 BOOST_CONTAINER_DECL size_t boost_cont_chunksize(const void *p);
|
Chris@102
|
247
|
Chris@102
|
248 BOOST_CONTAINER_DECL int boost_cont_all_deallocated();
|
Chris@102
|
249
|
Chris@102
|
250 typedef struct boost_cont_malloc_stats_impl
|
Chris@102
|
251 {
|
Chris@102
|
252 size_t max_system_bytes;
|
Chris@102
|
253 size_t system_bytes;
|
Chris@102
|
254 size_t in_use_bytes;
|
Chris@102
|
255 } boost_cont_malloc_stats_t;
|
Chris@102
|
256
|
Chris@102
|
257 BOOST_CONTAINER_DECL boost_cont_malloc_stats_t boost_cont_malloc_stats();
|
Chris@102
|
258
|
Chris@102
|
259 BOOST_CONTAINER_DECL size_t boost_cont_in_use_memory();
|
Chris@102
|
260
|
Chris@102
|
261 BOOST_CONTAINER_DECL int boost_cont_trim(size_t pad);
|
Chris@102
|
262
|
Chris@102
|
263 BOOST_CONTAINER_DECL int boost_cont_mallopt
|
Chris@102
|
264 (int parameter_number, int parameter_value);
|
Chris@102
|
265
|
Chris@102
|
266 BOOST_CONTAINER_DECL int boost_cont_grow
|
Chris@102
|
267 (void* oldmem, size_t minbytes, size_t maxbytes, size_t *received);
|
Chris@102
|
268
|
Chris@102
|
269 BOOST_CONTAINER_DECL int boost_cont_shrink
|
Chris@102
|
270 (void* oldmem, size_t minbytes, size_t maxbytes, size_t *received, int do_commit);
|
Chris@102
|
271
|
Chris@102
|
272 BOOST_CONTAINER_DECL void* boost_cont_alloc
|
Chris@102
|
273 (size_t minbytes, size_t preferred_bytes, size_t *received_bytes);
|
Chris@102
|
274
|
Chris@102
|
275 BOOST_CONTAINER_DECL int boost_cont_malloc_check();
|
Chris@102
|
276
|
Chris@102
|
277 typedef unsigned int allocation_type;
|
Chris@102
|
278
|
Chris@102
|
279 enum
|
Chris@102
|
280 {
|
Chris@102
|
281 // constants for allocation commands
|
Chris@102
|
282 BOOST_CONTAINER_ALLOCATE_NEW = 0X01,
|
Chris@102
|
283 BOOST_CONTAINER_EXPAND_FWD = 0X02,
|
Chris@102
|
284 BOOST_CONTAINER_EXPAND_BWD = 0X04,
|
Chris@102
|
285 BOOST_CONTAINER_SHRINK_IN_PLACE = 0X08,
|
Chris@102
|
286 BOOST_CONTAINER_NOTHROW_ALLOCATION = 0X10,
|
Chris@102
|
287 // BOOST_CONTAINER_ZERO_MEMORY = 0X20,
|
Chris@102
|
288 BOOST_CONTAINER_TRY_SHRINK_IN_PLACE = 0X40,
|
Chris@102
|
289 BOOST_CONTAINER_EXPAND_BOTH = BOOST_CONTAINER_EXPAND_FWD | BOOST_CONTAINER_EXPAND_BWD,
|
Chris@102
|
290 BOOST_CONTAINER_EXPAND_OR_NEW = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH
|
Chris@102
|
291 };
|
Chris@102
|
292
|
Chris@102
|
293 //#define BOOST_CONTAINERDLMALLOC__FOOTERS
|
Chris@102
|
294 #ifndef BOOST_CONTAINERDLMALLOC__FOOTERS
|
Chris@102
|
295 enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t) };
|
Chris@102
|
296 #else
|
Chris@102
|
297 enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2 };
|
Chris@102
|
298 #endif
|
Chris@102
|
299
|
Chris@102
|
300 typedef struct boost_cont_command_ret_impl
|
Chris@102
|
301 {
|
Chris@102
|
302 void *first;
|
Chris@102
|
303 int second;
|
Chris@102
|
304 }boost_cont_command_ret_t;
|
Chris@102
|
305
|
Chris@102
|
306 BOOST_CONTAINER_DECL boost_cont_command_ret_t boost_cont_allocation_command
|
Chris@102
|
307 ( allocation_type command
|
Chris@102
|
308 , size_t sizeof_object
|
Chris@102
|
309 , size_t limit_objects
|
Chris@102
|
310 , size_t preferred_objects
|
Chris@102
|
311 , size_t *received_objects
|
Chris@102
|
312 , void *reuse_ptr
|
Chris@102
|
313 );
|
Chris@102
|
314
|
Chris@102
|
315 BOOST_CONTAINER_DECL int boost_cont_mallopt(int param_number, int value);
|
Chris@102
|
316
|
Chris@102
|
317 #ifdef __cplusplus
|
Chris@102
|
318 } //extern "C" {
|
Chris@102
|
319 #endif
|
Chris@102
|
320
|
Chris@102
|
321 #ifdef _MSC_VER
|
Chris@102
|
322 #pragma warning (pop)
|
Chris@102
|
323 #endif
|
Chris@102
|
324
|
Chris@102
|
325
|
Chris@102
|
326 #endif //#define BOOST_CONTAINERDLMALLOC__EXT_H
|