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