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 BOOST_CONTAINER_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 BOOST_CONTAINER_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_CONTAINER_DLMALLOC_FOOTERS 229 #ifndef BOOST_CONTAINER_DLMALLOC_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