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