1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the library */ 4 /* BMS --- Block Memory Shell */ 5 /* */ 6 /* Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB) */ 7 /* */ 8 /* Licensed under the Apache License, Version 2.0 (the "License"); */ 9 /* you may not use this file except in compliance with the License. */ 10 /* You may obtain a copy of the License at */ 11 /* */ 12 /* http://www.apache.org/licenses/LICENSE-2.0 */ 13 /* */ 14 /* Unless required by applicable law or agreed to in writing, software */ 15 /* distributed under the License is distributed on an "AS IS" BASIS, */ 16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ 17 /* See the License for the specific language governing permissions and */ 18 /* limitations under the License. */ 19 /* */ 20 /* You should have received a copy of the Apache-2.0 license */ 21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 /**@file memory.h 26 * @brief memory allocation routines 27 * @author Tobias Achterberg 28 * @author Gerald Gamrath 29 * @author Marc Pfetsch 30 */ 31 32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 33 34 #ifndef __BMS_MEMORY_H__ 35 #define __BMS_MEMORY_H__ 36 37 #include <limits.h> 38 #include <stdlib.h> 39 #include <stddef.h> 40 41 /* 42 * include build configuration flags 43 */ 44 #include "scip/config.h" 45 #include "scip/scip_export.h" 46 47 #ifdef __cplusplus 48 49 50 /* special thanks to Daniel Junglas for following template and macros */ 51 52 template<typename T> T* docast(T*, void *v); 53 template<typename T> T* docast(T*, void *v) { return reinterpret_cast<T*>(v); } 54 55 /* For C++11, we can easily check whether the types for memory functions like BMSduplicateXYZArray() are equal. */ 56 #if __cplusplus > 199711L 57 #include <type_traits> 58 59 /* the following adds a type check for the parameters, used in ASSIGNCHECK below */ 60 template<typename T1, typename T2> T1* docastcheck(T1* v1, void* v, T2* v2) 61 { 62 typedef typename std::remove_const<T1>::type t1; 63 typedef typename std::remove_const<T2>::type t2; 64 static_assert(std::is_same<t1, t2>::value, "need equal types"); 65 return reinterpret_cast<T1*>(v); 66 } 67 #else 68 /* for older compilers do nothing */ 69 template<typename T1, typename T2> T1* docastcheck(T1* v1, void* v, T2* v2) { return reinterpret_cast<T1*>(v); } 70 #endif 71 72 73 extern "C" { 74 75 #define ASSIGN(pointerstarstar, voidstarfunction) (*(pointerstarstar) = docast(*(pointerstarstar), (voidstarfunction))) 76 #define ASSIGNCHECK(pointerstarstar, voidstarfunction, origpointer) (*(pointerstarstar) = docastcheck(*(pointerstarstar), (voidstarfunction), (origpointer))) 77 78 #else 79 80 #define ASSIGN(pointerstarstar, voidstarfunction) (*(pointerstarstar) = (voidstarfunction)) 81 #define ASSIGNCHECK(pointerstarstar, voidstarfunction, origpointer) (*(pointerstarstar) = (voidstarfunction)) 82 83 #endif 84 85 /* 86 * Define the macro SCIP_EXPORT depending if the OS is Windows or not 87 */ 88 #ifndef SCIP_EXPORT 89 90 #if defined(_WIN32) || defined(_WIN64) 91 #define SCIP_EXPORT __declspec(dllexport) 92 #elif defined(__GNUC__) && __GNUC__ >= 4 93 #define SCIP_EXPORT __attribute__((__visibility__("default"))) 94 #else 95 #define SCIP_EXPORT 96 #endif 97 98 #endif 99 100 /* define if not already existing to make file independent from def.h */ 101 #ifndef SCIP_UNUSED 102 #define SCIP_UNUSED(x) ((void) (x)) 103 #endif 104 105 106 /************************************************************************************* 107 * Standard Memory Management 108 * 109 * In debug mode, these methods extend malloc() and free() by logging all currently 110 * allocated memory elements in an allocation list. This can be used as a simple leak 111 * detection. 112 *************************************************************************************/ 113 114 /* Note: values that are passed as a size_t parameter are first converted to ptrdiff_t to be sure that negative numbers 115 * are extended to the larger size. Then they are converted to size_t. Thus, negative numbers are converted to very 116 * large size_t values. This is then checked within the functions. */ 117 118 #define BMSallocMemory(ptr) ASSIGN((ptr), BMSallocMemory_call( sizeof(**(ptr)), __FILE__, __LINE__ )) 119 #define BMSallocClearMemory(ptr) ASSIGN((ptr), BMSallocClearMemory_call((size_t)(1), sizeof(**(ptr)), __FILE__, __LINE__ )) 120 #define BMSallocMemorySize(ptr,size) ASSIGN((ptr), BMSallocMemory_call( (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )) 121 #define BMSallocMemoryCPP(size) BMSallocMemory_call( (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ) 122 #define BMSallocClearMemorySize(ptr,size) ASSIGN((ptr), BMSallocClearMemory_call((size_t)(1), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )) 123 #define BMSallocMemoryArray(ptr,num) ASSIGN((ptr), BMSallocMemoryArray_call((size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ )) 124 #define BMSallocMemoryArrayCPP(num,size) BMSallocMemoryArray_call( (size_t)(ptrdiff_t)(num), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ) 125 #define BMSallocClearMemoryArray(ptr,num) ASSIGN((ptr), BMSallocClearMemory_call((size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ )) 126 #define BMSreallocMemorySize(ptr,size) ASSIGN((ptr), BMSreallocMemory_call((void*)(*(ptr)), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )) 127 #define BMSreallocMemoryArray(ptr,num) ASSIGN((ptr), BMSreallocMemoryArray_call( *(ptr), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ )) 128 129 #define BMSclearMemory(ptr) BMSclearMemory_call( (void*)(ptr), sizeof(*(ptr)) ) 130 #define BMSclearMemoryArray(ptr, num) BMSclearMemory_call( (void*)(ptr), (size_t)(ptrdiff_t)(num)*sizeof(*(ptr)) ) 131 #define BMSclearMemorySize(ptr, size) BMSclearMemory_call( (void*)(ptr), (size_t)(ptrdiff_t)(size) ) 132 133 #define BMScopyMemory(ptr, source) BMScopyMemory_call( (void*)(ptr), (const void*)(source), sizeof(*(ptr)) ) 134 #define BMScopyMemoryArray(ptr, source, num) BMScopyMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(num)*sizeof(*(ptr)) ) 135 #define BMScopyMemorySize(ptr, source, size) BMScopyMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(size) ) 136 137 #define BMSmoveMemory(ptr, source) BMSmoveMemory_call( (void*)(ptr), (const void*)(source), sizeof(*(ptr)) ) 138 #define BMSmoveMemoryArray(ptr, source, num) BMSmoveMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(num) * sizeof(*(ptr)) ) 139 #define BMSmoveMemorySize(ptr, source, size) BMSmoveMemory_call( (void*)(ptr), (const void*)(source), (size_t)(ptrdiff_t)(size) ) 140 141 #define BMSduplicateMemory(ptr, source) ASSIGN((ptr), BMSduplicateMemory_call( (const void*)(source), sizeof(**(ptr)), __FILE__, __LINE__ )) 142 #define BMSduplicateMemorySize(ptr, source, size) ASSIGN((ptr), BMSduplicateMemory_call( (const void*)(source), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ )) 143 #define BMSduplicateMemoryArray(ptr, source, num) ASSIGNCHECK((ptr), BMSduplicateMemoryArray_call( (const void*)(source), (size_t)(ptrdiff_t)(num), \ 144 sizeof(**(ptr)), __FILE__, __LINE__ ), source) 145 #define BMSfreeMemory(ptr) BMSfreeMemory_call( (void**)(ptr), __FILE__, __LINE__ ) 146 #define BMSfreeMemoryNull(ptr) BMSfreeMemoryNull_call( (void**)(ptr), __FILE__, __LINE__ ) 147 #define BMSfreeMemoryArray(ptr) BMSfreeMemory_call( (void**)(ptr), __FILE__, __LINE__ ) 148 #define BMSfreeMemoryArrayNull(ptr) BMSfreeMemoryNull_call( (void**)(ptr), __FILE__, __LINE__ ) 149 #define BMSfreeMemorySize(ptr) BMSfreeMemory_call( (void**)(ptr), __FILE__, __LINE__ ) 150 #define BMSfreeMemorySizeNull(ptr) BMSfreeMemoryNull_call( (void**)(ptr), __FILE__, __LINE__ ) 151 152 #ifndef NDEBUG 153 #define BMSgetPointerSize(ptr) BMSgetPointerSize_call(ptr) 154 #define BMSdisplayMemory() BMSdisplayMemory_call() 155 #define BMScheckEmptyMemory() BMScheckEmptyMemory_call() 156 #define BMSgetMemoryUsed() BMSgetMemoryUsed_call() 157 #else 158 #define BMSgetPointerSize(ptr) 0 159 #define BMSdisplayMemory() /**/ 160 #define BMScheckEmptyMemory() /**/ 161 #define BMSgetMemoryUsed() 0LL 162 #endif 163 164 /** allocates array and initializes it with 0; returns NULL if memory allocation failed */ 165 SCIP_EXPORT 166 void* BMSallocClearMemory_call( 167 size_t num, /**< number of memory element to allocate */ 168 size_t typesize, /**< size of memory element to allocate */ 169 const char* filename, /**< source file where the allocation is performed */ 170 int line /**< line number in source file where the allocation is performed */ 171 ); 172 173 /** allocates memory; returns NULL if memory allocation failed */ 174 SCIP_EXPORT 175 void* BMSallocMemory_call( 176 size_t size, /**< size of memory element to allocate */ 177 const char* filename, /**< source file where the allocation is performed */ 178 int line /**< line number in source file where the allocation is performed */ 179 ); 180 181 /** allocates array; returns NULL if memory allocation failed */ 182 SCIP_EXPORT 183 void* BMSallocMemoryArray_call( 184 size_t num, /**< number of components of array to allocate */ 185 size_t typesize, /**< size of each component */ 186 const char* filename, /**< source file where the allocation is performed */ 187 int line /**< line number in source file where the allocation is performed */ 188 ); 189 190 /** allocates memory; returns NULL if memory allocation failed */ 191 SCIP_EXPORT 192 void* BMSreallocMemory_call( 193 void* ptr, /**< pointer to memory to reallocate */ 194 size_t size, /**< new size of memory element */ 195 const char* filename, /**< source file where the reallocation is performed */ 196 int line /**< line number in source file where the reallocation is performed */ 197 ); 198 199 /** reallocates array; returns NULL if memory allocation failed */ 200 SCIP_EXPORT 201 void* BMSreallocMemoryArray_call( 202 void* ptr, /**< pointer to memory to reallocate */ 203 size_t num, /**< number of components of array to allocate */ 204 size_t typesize, /**< size of each component */ 205 const char* filename, /**< source file where the reallocation is performed */ 206 int line /**< line number in source file where the reallocation is performed */ 207 ); 208 209 /** clears a memory element (i.e. fills it with zeros) */ 210 SCIP_EXPORT 211 void BMSclearMemory_call( 212 void* ptr, /**< pointer to memory element */ 213 size_t size /**< size of memory element */ 214 ); 215 216 /** copies the contents of one memory element into another memory element */ 217 SCIP_EXPORT 218 void BMScopyMemory_call( 219 void* ptr, /**< pointer to target memory element */ 220 const void* source, /**< pointer to source memory element */ 221 size_t size /**< size of memory element to copy */ 222 ); 223 224 /** moves the contents of one memory element into another memory element, should be used if both elements overlap, 225 * otherwise BMScopyMemory is faster 226 */ 227 SCIP_EXPORT 228 void BMSmoveMemory_call( 229 void* ptr, /**< pointer to target memory element */ 230 const void* source, /**< pointer to source memory element */ 231 size_t size /**< size of memory element to copy */ 232 ); 233 234 /** allocates memory and copies the contents of the given memory element into the new memory element */ 235 SCIP_EXPORT 236 void* BMSduplicateMemory_call( 237 const void* source, /**< pointer to source memory element */ 238 size_t size, /**< size of memory element to copy */ 239 const char* filename, /**< source file where the duplication is performed */ 240 int line /**< line number in source file where the duplication is performed */ 241 ); 242 243 /** allocates array and copies the contents of the given source array into the new array */ 244 SCIP_EXPORT 245 void* BMSduplicateMemoryArray_call( 246 const void* source, /**< pointer to source memory element */ 247 size_t num, /**< number of components of array to allocate */ 248 size_t typesize, /**< size of each component */ 249 const char* filename, /**< source file where the duplication is performed */ 250 int line /**< line number in source file where the duplication is performed */ 251 ); 252 253 /** frees an allocated memory element and sets pointer to NULL */ 254 SCIP_EXPORT 255 void BMSfreeMemory_call( 256 void** ptr, /**< pointer to pointer to memory element */ 257 const char* filename, /**< source file where the deallocation is performed */ 258 int line /**< line number in source file where the deallocation is performed */ 259 ); 260 261 /** frees an allocated memory element if pointer is not NULL and sets pointer to NULL */ 262 SCIP_EXPORT 263 void BMSfreeMemoryNull_call( 264 void** ptr, /**< pointer to pointer to memory element */ 265 const char* filename, /**< source file where the deallocation is performed */ 266 int line /**< line number in source file where the deallocation is performed */ 267 ); 268 269 /** returns the size of an allocated memory element */ 270 SCIP_EXPORT 271 size_t BMSgetPointerSize_call( 272 const void* ptr /**< pointer to allocated memory */ 273 ); 274 275 /** outputs information about currently allocated memory to the screen */ 276 SCIP_EXPORT 277 void BMSdisplayMemory_call( 278 void 279 ); 280 281 /** displays a warning message on the screen, if allocated memory exists */ 282 SCIP_EXPORT 283 void BMScheckEmptyMemory_call( 284 void 285 ); 286 287 /** returns total number of allocated bytes */ 288 SCIP_EXPORT 289 long long BMSgetMemoryUsed_call( 290 void 291 ); 292 293 294 295 296 /******************************************************************** 297 * Chunk Memory Management 298 * 299 * Efficient memory management for multiple objects of the same size 300 ********************************************************************/ 301 302 typedef struct BMS_ChkMem BMS_CHKMEM; /**< collection of memory chunks of the same element size */ 303 304 305 #ifndef BMS_NOBLOCKMEM 306 307 #define BMScreateChunkMemory(sz,isz,gbf) BMScreateChunkMemory_call( (sz), (isz), (gbf), __FILE__, __LINE__ ) 308 #define BMSclearChunkMemory(mem) BMSclearChunkMemory_call( (mem), __FILE__, __LINE__ ) 309 #define BMSdestroyChunkMemory(mem) BMSdestroyChunkMemory_call( (mem), __FILE__, __LINE__ ) 310 311 #define BMSallocChunkMemory(mem,ptr) ASSIGN((ptr), BMSallocChunkMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__)) 312 #define BMSduplicateChunkMemory(mem, ptr, source) ASSIGN((ptr), BMSduplicateChunkMemory_call((mem), (const void*)(source), \ 313 sizeof(**(ptr)), __FILE__, __LINE__ )) 314 #define BMSfreeChunkMemory(mem,ptr) BMSfreeChunkMemory_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ ) 315 #define BMSfreeChunkMemoryNull(mem,ptr) BMSfreeChunkMemoryNull_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ ) 316 #define BMSgarbagecollectChunkMemory(mem) BMSgarbagecollectChunkMemory_call(mem) 317 #define BMSgetChunkMemoryUsed(mem) BMSgetChunkMemoryUsed_call(mem) 318 319 #else 320 321 /* block memory management mapped to standard memory management */ 322 323 #define BMScreateChunkMemory(sz,isz,gbf) (void*)(0x01) /* dummy to not return a NULL pointer */ 324 #define BMSclearChunkMemory(mem) /**/ 325 #define BMSclearChunkMemoryNull(mem) /**/ 326 #define BMSdestroyChunkMemory(mem) /**/ 327 #define BMSdestroyChunkMemoryNull(mem) /**/ 328 #define BMSallocChunkMemory(mem,ptr) BMSallocMemory(ptr) 329 #define BMSduplicateChunkMemory(mem, ptr, source) BMSduplicateMemory(ptr,source) 330 #define BMSfreeChunkMemory(mem,ptr) BMSfreeMemory(ptr) 331 #define BMSfreeChunkMemoryNull(mem,ptr) BMSfreeMemoryNull(ptr) 332 #define BMSgarbagecollectChunkMemory(mem) /**/ 333 #define BMSgetChunkMemoryUsed(mem) 0LL 334 335 #endif 336 337 338 /** aligns the given byte size corresponding to the minimal alignment for chunk and block memory */ 339 SCIP_EXPORT 340 void BMSalignMemsize( 341 size_t* size /**< pointer to the size to align */ 342 ); 343 344 /** checks whether the given size meets the alignment conditions for chunk and block memory */ 345 SCIP_EXPORT 346 int BMSisAligned( 347 size_t size /**< size to check for alignment */ 348 ); 349 350 /** creates a new chunk block data structure */ 351 SCIP_EXPORT 352 BMS_CHKMEM* BMScreateChunkMemory_call( 353 size_t size, /**< element size of the chunk block */ 354 int initchunksize, /**< number of elements in the first chunk of the chunk block */ 355 int garbagefactor, /**< garbage collector is called, if at least garbagefactor * avg. chunksize 356 * elements are free (-1: disable garbage collection) */ 357 const char* filename, /**< source file of the function call */ 358 int line /**< line number in source file of the function call */ 359 ); 360 361 /** clears a chunk block data structure */ 362 SCIP_EXPORT 363 void BMSclearChunkMemory_call( 364 BMS_CHKMEM* chkmem, /**< chunk block */ 365 const char* filename, /**< source file of the function call */ 366 int line /**< line number in source file of the function call */ 367 ); 368 369 /** destroys and frees a chunk block data structure */ 370 SCIP_EXPORT 371 void BMSdestroyChunkMemory_call( 372 BMS_CHKMEM** chkmem, /**< pointer to chunk block */ 373 const char* filename, /**< source file of the function call */ 374 int line /**< line number in source file of the function call */ 375 ); 376 377 /** allocates a memory element of the given chunk block */ 378 SCIP_EXPORT 379 void* BMSallocChunkMemory_call( 380 BMS_CHKMEM* chkmem, /**< chunk block */ 381 size_t size, /**< size of memory element to allocate (only needed for sanity check) */ 382 const char* filename, /**< source file of the function call */ 383 int line /**< line number in source file of the function call */ 384 ); 385 386 /** duplicates a given memory element by allocating a new element of the same chunk block and copying the data */ 387 SCIP_EXPORT 388 void* BMSduplicateChunkMemory_call( 389 BMS_CHKMEM* chkmem, /**< chunk block */ 390 const void* source, /**< source memory element */ 391 size_t size, /**< size of memory element to allocate (only needed for sanity check) */ 392 const char* filename, /**< source file of the function call */ 393 int line /**< line number in source file of the function call */ 394 ); 395 396 /** frees a memory element of the given chunk block and sets pointer to NULL */ 397 SCIP_EXPORT 398 void BMSfreeChunkMemory_call( 399 BMS_CHKMEM* chkmem, /**< chunk block */ 400 void** ptr, /**< pointer to pointer to memory element to free */ 401 size_t size, /**< size of memory element to allocate (only needed for sanity check) */ 402 const char* filename, /**< source file of the function call */ 403 int line /**< line number in source file of the function call */ 404 ); 405 406 /** frees a memory element of the given chunk block if pointer is not NULL and sets pointer to NULL */ 407 SCIP_EXPORT 408 void BMSfreeChunkMemoryNull_call( 409 BMS_CHKMEM* chkmem, /**< chunk block */ 410 void** ptr, /**< pointer to pointer to memory element to free */ 411 size_t size, /**< size of memory element to allocate (only needed for sanity check) */ 412 const char* filename, /**< source file of the function call */ 413 int line /**< line number in source file of the function call */ 414 ); 415 416 /** calls garbage collection of chunk block and frees chunks without allocated memory elements */ 417 SCIP_EXPORT 418 void BMSgarbagecollectChunkMemory_call( 419 BMS_CHKMEM* chkmem /**< chunk block */ 420 ); 421 422 /** returns the number of allocated bytes in the chunk block */ 423 SCIP_EXPORT 424 long long BMSgetChunkMemoryUsed_call( 425 const BMS_CHKMEM* chkmem /**< chunk block */ 426 ); 427 428 429 430 431 /*********************************************************** 432 * Block Memory Management 433 * 434 * Efficient memory management for objects of varying sizes 435 ***********************************************************/ 436 437 typedef struct BMS_BlkMem BMS_BLKMEM; /**< block memory: collection of chunk blocks */ 438 439 #ifndef BMS_NOBLOCKMEM 440 441 /* block memory methods for faster memory access */ 442 443 /* Note: values that are passed as a size_t parameter are first converted to ptrdiff_t to be sure that negative numbers 444 * are extended to the larger size. Then they are converted to size_t. Thus, negative numbers are converted to very 445 * large size_t values. This is then checked within the functions. */ 446 447 #define BMScreateBlockMemory(csz,gbf) BMScreateBlockMemory_call( (csz), (gbf), __FILE__, __LINE__ ) 448 #define BMSclearBlockMemory(mem) BMSclearBlockMemory_call( (mem), __FILE__, __LINE__ ) 449 #define BMSdestroyBlockMemory(mem) BMSdestroyBlockMemory_call( (mem), __FILE__, __LINE__ ) 450 451 #define BMSallocBlockMemory(mem,ptr) ASSIGN((ptr), BMSallocBlockMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__)) 452 #define BMSallocClearBlockMemory(mem,ptr) ASSIGN((ptr), BMSallocClearBlockMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__)) 453 #define BMSallocBlockMemorySize(mem,ptr,size) ASSIGN((ptr), BMSallocBlockMemory_call((mem), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__)) 454 #define BMSallocBlockMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocBlockMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__)) 455 #define BMSallocClearBlockMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocClearBlockMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__)) 456 #define BMSreallocBlockMemorySize(mem,ptr,oldsize,newsize) ASSIGN((ptr), BMSreallocBlockMemory_call((mem), (void*)(*(ptr)), \ 457 (size_t)(ptrdiff_t)(oldsize), (size_t)(ptrdiff_t)(newsize), __FILE__, __LINE__)) 458 #define BMSreallocBlockMemoryArray(mem,ptr,oldnum,newnum) ASSIGN((ptr), BMSreallocBlockMemoryArray_call((mem), (void*)(*(ptr)), \ 459 (size_t)(ptrdiff_t)(oldnum), (size_t)(ptrdiff_t)(newnum), sizeof(**(ptr)), __FILE__, __LINE__)) 460 #define BMSduplicateBlockMemory(mem, ptr, source) ASSIGN((ptr), BMSduplicateBlockMemory_call((mem), (const void*)(source), \ 461 sizeof(**(ptr)), __FILE__, __LINE__ )) 462 #define BMSduplicateBlockMemoryArray(mem, ptr, source, num) ASSIGNCHECK((ptr), BMSduplicateBlockMemoryArray_call( (mem), (const void*)(source), \ 463 (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__ ), source) 464 465 #define BMSfreeBlockMemory(mem,ptr) BMSfreeBlockMemory_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ ) 466 #define BMSfreeBlockMemoryNull(mem,ptr) BMSfreeBlockMemoryNull_call( (mem), (void**)(ptr), sizeof(**(ptr)), __FILE__, __LINE__ ) 467 #define BMSfreeBlockMemoryArray(mem,ptr,num) BMSfreeBlockMemory_call( (mem), (void**)(ptr), (num)*sizeof(**(ptr)), __FILE__, __LINE__ ) 468 #define BMSfreeBlockMemoryArrayNull(mem,ptr,num) BMSfreeBlockMemoryNull_call( (mem), (void**)(ptr), (num)*sizeof(**(ptr)), __FILE__, __LINE__ ) 469 #define BMSfreeBlockMemorySize(mem,ptr,size) BMSfreeBlockMemory_call( (mem), (void**)(ptr), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ) 470 #define BMSfreeBlockMemorySizeNull(mem,ptr,size) BMSfreeBlockMemory_call( (mem), (void**)(ptr), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__ ) 471 472 #define BMSgarbagecollectBlockMemory(mem) BMSgarbagecollectBlockMemory_call(mem) 473 #define BMSgetBlockMemoryAllocated(mem) BMSgetBlockMemoryAllocated_call(mem) 474 #define BMSgetBlockMemoryUsed(mem) BMSgetBlockMemoryUsed_call(mem) 475 #define BMSgetBlockMemoryUnused(mem) BMSgetBlockMemoryUnused_call(mem) 476 #define BMSgetBlockMemoryUsedMax(mem) BMSgetBlockMemoryUsedMax_call(mem) 477 #define BMSgetBlockMemoryUnusedMax(mem) BMSgetBlockMemoryUnusedMax_call(mem) 478 #define BMSgetBlockMemoryAllocatedMax(mem) BMSgetBlockMemoryAllocatedMax_call(mem) 479 #define BMSgetBlockPointerSize(mem,ptr) BMSgetBlockPointerSize_call((mem), (ptr)) 480 #define BMSdisplayBlockMemory(mem) BMSdisplayBlockMemory_call(mem) 481 #define BMSblockMemoryCheckEmpty(mem) BMScheckEmptyBlockMemory_call(mem) 482 483 #else 484 485 /* block memory management mapped to standard memory management */ 486 487 #define BMScreateBlockMemory(csz,gbf) (SCIP_UNUSED(csz), SCIP_UNUSED(gbf), (void*)(0x01)) /* dummy to not return a NULL pointer */ 488 #define BMSclearBlockMemory(mem) SCIP_UNUSED(mem) 489 #define BMSclearBlockMemoryNull(mem) SCIP_UNUSED(mem) 490 #define BMSdestroyBlockMemory(mem) SCIP_UNUSED(mem) 491 #define BMSdestroyBlockMemoryNull(mem) SCIP_UNUSED(mem) 492 #define BMSallocBlockMemory(mem,ptr) (SCIP_UNUSED(mem), BMSallocMemory(ptr)) 493 #define BMSallocClearBlockMemory(mem,ptr) (SCIP_UNUSED(mem), BMSallocClearMemory(ptr)) 494 #define BMSallocBlockMemoryArray(mem,ptr,num) (SCIP_UNUSED(mem), BMSallocMemoryArray(ptr,num)) 495 #define BMSallocClearBlockMemoryArray(mem,ptr,num) (SCIP_UNUSED(mem), BMSallocClearMemoryArray(ptr,num)) 496 #define BMSallocBlockMemorySize(mem,ptr,size) (SCIP_UNUSED(mem), BMSallocMemorySize(ptr,size)) 497 #define BMSreallocBlockMemoryArray(mem,ptr,oldnum,newnum) (SCIP_UNUSED(mem), SCIP_UNUSED(oldnum), BMSreallocMemoryArray(ptr,newnum)) 498 #define BMSreallocBlockMemorySize(mem,ptr,oldsize,newsize) (SCIP_UNUSED(mem), SCIP_UNUSED(oldsize), BMSreallocMemorySize(ptr,newsize)) 499 #define BMSduplicateBlockMemory(mem, ptr, source) (SCIP_UNUSED(mem), BMSduplicateMemory(ptr,source)) 500 #define BMSduplicateBlockMemoryArray(mem, ptr, source, num) (SCIP_UNUSED(mem), BMSduplicateMemoryArray(ptr,source,num)) 501 #define BMSfreeBlockMemory(mem,ptr) (SCIP_UNUSED(mem), BMSfreeMemory(ptr)) 502 #define BMSfreeBlockMemoryNull(mem,ptr) (SCIP_UNUSED(mem), BMSfreeMemoryNull(ptr)) 503 #define BMSfreeBlockMemoryArray(mem,ptr,num) (SCIP_UNUSED(mem), SCIP_UNUSED(num), BMSfreeMemoryArray(ptr)) 504 #define BMSfreeBlockMemoryArrayNull(mem,ptr,num) (SCIP_UNUSED(mem), SCIP_UNUSED(num), BMSfreeMemoryArrayNull(ptr)) 505 #define BMSfreeBlockMemorySize(mem,ptr,size) (SCIP_UNUSED(mem), SCIP_UNUSED(size), BMSfreeMemory(ptr)) 506 #define BMSfreeBlockMemorySizeNull(mem,ptr,size) (SCIP_UNUSED(mem), SCIP_UNUSED(size), BMSfreeMemoryNull(ptr)) 507 #define BMSgarbagecollectBlockMemory(mem) SCIP_UNUSED(mem) 508 #define BMSgetBlockMemoryAllocated(mem) (SCIP_UNUSED(mem), 0LL) 509 #define BMSgetBlockMemoryUsed(mem) (SCIP_UNUSED(mem), 0LL) 510 #define BMSgetBlockMemoryUnused(mem) (SCIP_UNUSED(mem), 0LL) 511 #define BMSgetBlockMemoryUsedMax(mem) (SCIP_UNUSED(mem), 0LL) 512 #define BMSgetBlockMemoryUnusedMax(mem) (SCIP_UNUSED(mem), 0LL) 513 #define BMSgetBlockMemoryAllocatedMax(mem) (SCIP_UNUSED(mem), 0LL) 514 #define BMSgetBlockPointerSize(mem,ptr) (SCIP_UNUSED(mem), SCIP_UNUSED(ptr), 0) 515 #define BMSdisplayBlockMemory(mem) SCIP_UNUSED(mem) 516 #define BMSblockMemoryCheckEmpty(mem) (SCIP_UNUSED(mem), 0LL) 517 518 #endif 519 520 521 /** creates a block memory allocation data structure */ 522 SCIP_EXPORT 523 BMS_BLKMEM* BMScreateBlockMemory_call( 524 int initchunksize, /**< number of elements in the first chunk of each chunk block */ 525 int garbagefactor, /**< garbage collector is called, if at least garbagefactor * avg. chunksize 526 * elements are free (-1: disable garbage collection) */ 527 const char* filename, /**< source file of the function call */ 528 int line /**< line number in source file of the function call */ 529 ); 530 531 /** frees all chunk blocks in the block memory */ 532 SCIP_EXPORT 533 void BMSclearBlockMemory_call( 534 BMS_BLKMEM* blkmem, /**< block memory */ 535 const char* filename, /**< source file of the function call */ 536 int line /**< line number in source file of the function call */ 537 ); 538 539 /** clears and deletes block memory */ 540 SCIP_EXPORT 541 void BMSdestroyBlockMemory_call( 542 BMS_BLKMEM** blkmem, /**< pointer to block memory */ 543 const char* filename, /**< source file of the function call */ 544 int line /**< line number in source file of the function call */ 545 ); 546 547 /** allocates memory in the block memory pool */ 548 SCIP_EXPORT 549 void* BMSallocBlockMemory_call( 550 BMS_BLKMEM* blkmem, /**< block memory */ 551 size_t size, /**< size of memory element to allocate */ 552 const char* filename, /**< source file of the function call */ 553 int line /**< line number in source file of the function call */ 554 ); 555 556 /** allocates memory in the block memory pool and clears it */ 557 SCIP_EXPORT 558 void* BMSallocClearBlockMemory_call( 559 BMS_BLKMEM* blkmem, /**< block memory */ 560 size_t size, /**< size of memory element to allocate */ 561 const char* filename, /**< source file of the function call */ 562 int line /**< line number in source file of the function call */ 563 ); 564 565 /** allocates array in the block memory pool */ 566 SCIP_EXPORT 567 void* BMSallocBlockMemoryArray_call( 568 BMS_BLKMEM* blkmem, /**< block memory */ 569 size_t num, /**< size of array to be allocated */ 570 size_t typesize, /**< size of each component */ 571 const char* filename, /**< source file of the function call */ 572 int line /**< line number in source file of the function call */ 573 ); 574 575 /** allocates array in the block memory pool and clears it */ 576 SCIP_EXPORT 577 void* BMSallocClearBlockMemoryArray_call( 578 BMS_BLKMEM* blkmem, /**< block memory */ 579 size_t num, /**< size of array to be allocated */ 580 size_t typesize, /**< size of each component */ 581 const char* filename, /**< source file of the function call */ 582 int line /**< line number in source file of the function call */ 583 ); 584 585 /** resizes memory element in the block memory pool and copies the data */ 586 SCIP_EXPORT 587 void* BMSreallocBlockMemory_call( 588 BMS_BLKMEM* blkmem, /**< block memory */ 589 void* ptr, /**< memory element to reallocated */ 590 size_t oldsize, /**< old size of memory element */ 591 size_t newsize, /**< new size of memory element */ 592 const char* filename, /**< source file of the function call */ 593 int line /**< line number in source file of the function call */ 594 ); 595 596 /** resizes array in the block memory pool and copies the data */ 597 SCIP_EXPORT 598 void* BMSreallocBlockMemoryArray_call( 599 BMS_BLKMEM* blkmem, /**< block memory */ 600 void* ptr, /**< memory element to reallocated */ 601 size_t oldnum, /**< old size of array */ 602 size_t newnum, /**< new size of array */ 603 size_t typesize, /**< size of each component */ 604 const char* filename, /**< source file of the function call */ 605 int line /**< line number in source file of the function call */ 606 ); 607 608 /** duplicates memory element in the block memory pool and copies the data */ 609 SCIP_EXPORT 610 void* BMSduplicateBlockMemory_call( 611 BMS_BLKMEM* blkmem, /**< block memory */ 612 const void* source, /**< memory element to duplicate */ 613 size_t size, /**< size of memory elements */ 614 const char* filename, /**< source file of the function call */ 615 int line /**< line number in source file of the function call */ 616 ); 617 618 /** duplicates array in the block memory pool and copies the data */ 619 SCIP_EXPORT 620 void* BMSduplicateBlockMemoryArray_call( 621 BMS_BLKMEM* blkmem, /**< block memory */ 622 const void* source, /**< memory element to duplicate */ 623 size_t num, /**< size of array to be duplicated */ 624 size_t typesize, /**< size of each component */ 625 const char* filename, /**< source file of the function call */ 626 int line /**< line number in source file of the function call */ 627 ); 628 629 /** frees memory element in the block memory pool and sets pointer to NULL */ 630 SCIP_EXPORT 631 void BMSfreeBlockMemory_call( 632 BMS_BLKMEM* blkmem, /**< block memory */ 633 void** ptr, /**< pointer to pointer to memory element to free */ 634 size_t size, /**< size of memory element */ 635 const char* filename, /**< source file of the function call */ 636 int line /**< line number in source file of the function call */ 637 ); 638 639 /** frees memory element in the block memory pool if pointer is not NULL and sets pointer to NULL */ 640 SCIP_EXPORT 641 void BMSfreeBlockMemoryNull_call( 642 BMS_BLKMEM* blkmem, /**< block memory */ 643 void** ptr, /**< pointer to pointer to memory element to free */ 644 size_t size, /**< size of memory element */ 645 const char* filename, /**< source file of the function call */ 646 int line /**< line number in source file of the function call */ 647 ); 648 649 /** calls garbage collection of block memory, frees chunks without allocated memory elements, and frees 650 * chunk blocks without any chunks 651 */ 652 SCIP_EXPORT 653 void BMSgarbagecollectBlockMemory_call( 654 BMS_BLKMEM* blkmem /**< block memory */ 655 ); 656 657 /** returns the number of allocated bytes in the block memory */ 658 SCIP_EXPORT 659 long long BMSgetBlockMemoryAllocated_call( 660 const BMS_BLKMEM* blkmem /**< block memory */ 661 ); 662 663 /** returns the number of used bytes in the block memory */ 664 SCIP_EXPORT 665 long long BMSgetBlockMemoryUsed_call( 666 const BMS_BLKMEM* blkmem /**< block memory */ 667 ); 668 669 /** returns the number of allocated but not used bytes in the block memory */ 670 SCIP_EXPORT 671 long long BMSgetBlockMemoryUnused_call( 672 const BMS_BLKMEM* blkmem /**< block memory */ 673 ); 674 675 /** returns the maximal number of used bytes in the block memory */ 676 SCIP_EXPORT 677 long long BMSgetBlockMemoryUsedMax_call( 678 const BMS_BLKMEM* blkmem /**< block memory */ 679 ); 680 681 /** returns the maximal number of allocated but not used bytes in the block memory */ 682 SCIP_EXPORT 683 long long BMSgetBlockMemoryUnusedMax_call( 684 const BMS_BLKMEM* blkmem /**< block memory */ 685 ); 686 687 /** returns the maximal number of allocated bytes in the block memory */ 688 long long BMSgetBlockMemoryAllocatedMax_call( 689 const BMS_BLKMEM* blkmem /**< block memory */ 690 ); 691 692 /** returns the size of the given memory element; returns 0, if the element is not member of the block memory */ 693 SCIP_EXPORT 694 size_t BMSgetBlockPointerSize_call( 695 const BMS_BLKMEM* blkmem, /**< block memory */ 696 const void* ptr /**< memory element */ 697 ); 698 699 /** outputs allocation diagnostics of block memory */ 700 SCIP_EXPORT 701 void BMSdisplayBlockMemory_call( 702 const BMS_BLKMEM* blkmem /**< block memory */ 703 ); 704 705 /** outputs error messages, if there are allocated elements in the block memory and returns number of unfreed bytes */ 706 SCIP_EXPORT 707 long long BMScheckEmptyBlockMemory_call( 708 const BMS_BLKMEM* blkmem /**< block memory */ 709 ); 710 711 712 713 714 715 /*********************************************************** 716 * Buffer Memory Management 717 * 718 * Efficient memory management for temporary objects 719 ***********************************************************/ 720 721 typedef struct BMS_BufMem BMS_BUFMEM; /**< buffer memory for temporary objects */ 722 723 /* Note: values that are passed as a size_t parameter are first converted to ptrdiff_t to be sure that negative numbers 724 * are extended to the larger size. Then they are converted to size_t. Thus, negative numbers are converted to very 725 * large size_t values. This is then checked within the functions. */ 726 727 #define BMSallocBufferMemory(mem,ptr) ASSIGN((ptr), BMSallocBufferMemory_call((mem), sizeof(**(ptr)), __FILE__, __LINE__)) 728 #define BMSallocBufferMemorySize(mem,ptr,size) ASSIGN((ptr), BMSallocBufferMemory_call((mem), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__)) 729 #define BMSreallocBufferMemorySize(mem,ptr,size) \ 730 ASSIGN((ptr), BMSreallocBufferMemory_call((mem), (void*)(*(ptr)), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__)) 731 #define BMSallocBufferMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocBufferMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__)) 732 #define BMSallocClearBufferMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSallocClearBufferMemoryArray_call((mem), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__)) 733 #define BMSreallocBufferMemoryArray(mem,ptr,num) ASSIGN((ptr), BMSreallocBufferMemoryArray_call((mem), (void*)(*(ptr)), (size_t)(ptrdiff_t)(num), \ 734 sizeof(**(ptr)), __FILE__, __LINE__)) 735 #define BMSduplicateBufferMemory(mem,ptr,source,size) \ 736 ASSIGN((ptr), BMSduplicateBufferMemory_call((mem), (const void*)(source), (size_t)(ptrdiff_t)(size), __FILE__, __LINE__)) 737 #define BMSduplicateBufferMemoryArray(mem,ptr,source,num) ASSIGNCHECK((ptr), BMSduplicateBufferMemoryArray_call((mem), \ 738 (const void*)(source), (size_t)(ptrdiff_t)(num), sizeof(**(ptr)), __FILE__, __LINE__), source) 739 740 #define BMSfreeBufferMemory(mem,ptr) BMSfreeBufferMemory_call((mem), (void**)(ptr), __FILE__, __LINE__) 741 #define BMSfreeBufferMemoryNull(mem,ptr) BMSfreeBufferMemoryNull_call((mem), (void**)(ptr), __FILE__, __LINE__) 742 #define BMSfreeBufferMemoryArray(mem,ptr) BMSfreeBufferMemory_call((mem), (void**)(ptr), __FILE__, __LINE__) 743 #define BMSfreeBufferMemoryArrayNull(mem,ptr) BMSfreeBufferMemoryNull_call((mem), (void**)(ptr), __FILE__, __LINE__) 744 #define BMSfreeBufferMemorySize(mem,ptr) BMSfreeBufferMemory_call((mem), (void**)(ptr), __FILE__, __LINE__); 745 #define BMSfreeBufferMemorySizeNull(mem,ptr) BMSfreeBufferMemoryNull_call((mem), (void**)(ptr), __FILE__, __LINE__) 746 747 #define BMScreateBufferMemory(fac,init,clean) BMScreateBufferMemory_call((fac), (init), (clean), __FILE__, __LINE__) 748 #define BMSdestroyBufferMemory(mem) BMSdestroyBufferMemory_call((mem), __FILE__, __LINE__) 749 750 751 /** creates memory buffer storage */ 752 SCIP_EXPORT 753 BMS_BUFMEM* BMScreateBufferMemory_call( 754 double arraygrowfac, /**< memory growing factor for dynamically allocated arrays */ 755 int arraygrowinit, /**< initial size of dynamically allocated arrays */ 756 unsigned int clean, /**< should the memory blocks in the buffer be initialized to zero? */ 757 const char* filename, /**< source file of the function call */ 758 int line /**< line number in source file of the function call */ 759 ); 760 761 /** destroys buffer memory */ 762 SCIP_EXPORT 763 void BMSdestroyBufferMemory_call( 764 BMS_BUFMEM** buffer, /**< pointer to memory buffer storage */ 765 const char* filename, /**< source file of the function call */ 766 int line /**< line number in source file of the function call */ 767 ); 768 769 /** set arraygrowfac */ 770 SCIP_EXPORT 771 void BMSsetBufferMemoryArraygrowfac( 772 BMS_BUFMEM* buffer, /**< pointer to memory buffer storage */ 773 double arraygrowfac /**< memory growing factor for dynamically allocated arrays */ 774 ); 775 776 /** set arraygrowinit */ 777 SCIP_EXPORT 778 void BMSsetBufferMemoryArraygrowinit( 779 BMS_BUFMEM* buffer, /**< pointer to memory buffer storage */ 780 int arraygrowinit /**< initial size of dynamically allocated arrays */ 781 ); 782 783 /** allocates the next unused buffer */ 784 SCIP_EXPORT 785 void* BMSallocBufferMemory_call( 786 BMS_BUFMEM* buffer, /**< memory buffer storage */ 787 size_t size, /**< minimal required size of the buffer */ 788 const char* filename, /**< source file of the function call */ 789 int line /**< line number in source file of the function call */ 790 ); 791 792 /** allocates the next unused buffer array */ 793 SCIP_EXPORT 794 void* BMSallocBufferMemoryArray_call( 795 BMS_BUFMEM* buffer, /**< memory buffer storage */ 796 size_t num, /**< size of array to be allocated */ 797 size_t typesize, /**< size of components */ 798 const char* filename, /**< source file of the function call */ 799 int line /**< line number in source file of the function call */ 800 ); 801 802 /** allocates the next unused buffer and clears it */ 803 SCIP_EXPORT 804 void* BMSallocClearBufferMemoryArray_call( 805 BMS_BUFMEM* buffer, /**< memory buffer storage */ 806 size_t num, /**< size of array to be allocated */ 807 size_t typesize, /**< size of components */ 808 const char* filename, /**< source file of the function call */ 809 int line /**< line number in source file of the function call */ 810 ); 811 812 /** reallocates the buffer to at least the given size */ 813 SCIP_EXPORT 814 void* BMSreallocBufferMemory_call( 815 BMS_BUFMEM* buffer, /**< memory buffer storage */ 816 void* ptr, /**< pointer to the allocated memory buffer */ 817 size_t size, /**< minimal required size of the buffer */ 818 const char* filename, /**< source file of the function call */ 819 int line /**< line number in source file of the function call */ 820 ); 821 822 /** reallocates an array in the buffer to at least the given size */ 823 SCIP_EXPORT 824 void* BMSreallocBufferMemoryArray_call( 825 BMS_BUFMEM* buffer, /**< memory buffer storage */ 826 void* ptr, /**< pointer to the allocated memory buffer */ 827 size_t num, /**< size of array to be allocated */ 828 size_t typesize, /**< size of components */ 829 const char* filename, /**< source file of the function call */ 830 int line /**< line number in source file of the function call */ 831 ); 832 833 /** allocates the next unused buffer and copies the given memory into the buffer */ 834 SCIP_EXPORT 835 void* BMSduplicateBufferMemory_call( 836 BMS_BUFMEM* buffer, /**< memory buffer storage */ 837 const void* source, /**< memory block to copy into the buffer */ 838 size_t size, /**< minimal required size of the buffer */ 839 const char* filename, /**< source file of the function call */ 840 int line /**< line number in source file of the function call */ 841 ); 842 843 /** allocates an array in the next unused buffer and copies the given memory into the buffer */ 844 SCIP_EXPORT 845 void* BMSduplicateBufferMemoryArray_call( 846 BMS_BUFMEM* buffer, /**< memory buffer storage */ 847 const void* source, /**< memory block to copy into the buffer */ 848 size_t num, /**< size of array to be allocated */ 849 size_t typesize, /**< size of components */ 850 const char* filename, /**< source file of the function call */ 851 int line /**< line number in source file of the function call */ 852 ); 853 854 /** frees a buffer and sets pointer to NULL */ 855 SCIP_EXPORT 856 void BMSfreeBufferMemory_call( 857 BMS_BUFMEM* buffer, /**< memory buffer storage */ 858 void** ptr, /**< pointer to pointer to the allocated memory buffer */ 859 const char* filename, /**< source file of the function call */ 860 int line /**< line number in source file of the function call */ 861 ); 862 863 /** frees a buffer if pointer is not NULL and sets pointer to NULL */ 864 SCIP_EXPORT 865 void BMSfreeBufferMemoryNull_call( 866 BMS_BUFMEM* buffer, /**< memory buffer storage */ 867 void** ptr, /**< pointer to pointer to the allocated memory buffer */ 868 const char* filename, /**< source file of the function call */ 869 int line /**< line number in source file of the function call */ 870 ); 871 872 /** gets number of used buffers */ 873 SCIP_EXPORT 874 size_t BMSgetNUsedBufferMemory( 875 BMS_BUFMEM* buffer /**< memory buffer storage */ 876 ); 877 878 /** returns the number of allocated bytes in the buffer memory */ 879 SCIP_EXPORT 880 long long BMSgetBufferMemoryUsed( 881 const BMS_BUFMEM* bufmem /**< buffer memory */ 882 ); 883 884 /** outputs statistics about currently allocated buffers to the screen */ 885 SCIP_EXPORT 886 void BMSprintBufferMemory( 887 BMS_BUFMEM* buffer /**< memory buffer storage */ 888 ); 889 890 891 #ifdef __cplusplus 892 } 893 #endif 894 895 #endif 896