Brian Silverman | fad8f55 | 2018-08-04 23:36:19 -0700 | [diff] [blame^] | 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 |