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