37#define __STDC_LIMIT_MACROS
48#include "scip/config.h"
65#ifndef SCIP_THREADSAFE
69#ifdef ENABLE_MEMLIST_CHECKS
85#ifdef SCIPdebugMessage
86#define debugMessage SCIPdebugMessage
87#define errorMessage SCIPerrorMessage
89#define debugMessage while( FALSE ) printf
90#define errorMessage printf
91#define printErrorHeader(f,l) printf("[%s:%d] ERROR: ", f, l)
92#define printError printf
95#ifdef ENABLE_MEMLIST_CHECKS
96#define warningMessage printf
98#define printInfo printf
106#define MAX(x,y) ((x) >= (y) ? (x) : (y))
107#define MIN(x,y) ((x) <= (y) ? (x) : (y))
110#ifndef SCIP_LONGINT_FORMAT
111#if defined(_WIN32) || defined(_WIN64)
112#define LONGINT_FORMAT "I64d"
114#define LONGINT_FORMAT "lld"
117#define LONGINT_FORMAT SCIP_LONGINT_FORMAT
120#ifndef SCIP_MAXMEMSIZE
122#define MAXMEMSIZE SIZE_MAX / 2
124#define MAXMEMSIZE SCIP_MAXMEMSIZE
129#if defined(_WIN32) || defined(_WIN64) || defined(__STDC__)
130#define INLINE __inline
143#if !defined(NDEBUG) && defined(ENABLE_MEMLIST_CHECKS)
145typedef struct Memlist MEMLIST;
157static MEMLIST* memlist =
NULL;
158static size_t memused = 0;
167 MEMLIST* list = memlist;
170 while( list !=
NULL )
178#define checkMemlist()
186 const char* filename,
194 list = (MEMLIST*)malloc(
sizeof(MEMLIST));
199 list->filename = strdup(filename);
202 list->next = memlist;
212 const char* filename,
223 while( list !=
NULL && ptr != list->ptr )
225 listptr = &(list->next);
232 *listptr = list->next;
233 assert( list->size <= memused );
234 memused -= list->size;
235 free(list->filename);
241 printError(
"Tried to free unknown pointer <%p>.\n", ptr);
254 while( list !=
NULL && ptr != list->ptr )
272 while( list !=
NULL )
274 printInfo(
"%12p %8llu %s:%d\n", list->ptr, (
unsigned long long) list->size, list->filename, list->line);
278 printInfo(
"Total: %8llu\n", (
unsigned long long) memused);
279 if( used != memused )
281 errorMessage(
"Used memory in list sums up to %llu instead of %llu\n", (
unsigned long long)used, (
unsigned long long)memused);
291 if( memlist !=
NULL || memused > 0 )
293 warningMessage(
"Memory list not empty.\n");
303 return (
long long) memused;
308#define addMemlistEntry(ptr, size, filename, line) do { (void) (ptr); (void) (size); (void) (filename); (void) (line); } while(0)
309#define removeMemlistEntry(ptr, filename, line) do { (void) (ptr); (void) (filename); (void) (line); } while(0)
329 printInfo(
"Optimized, threadsafe version of memory shell linked - no memory diagnostics available.\n");
353 const char* filename,
361 debugMessage(
"calloc %llu elements of %llu bytes [%s:%d]\n", (
unsigned long long)num, (
unsigned long long)typesize,
374 typesize =
MAX(typesize, 1);
375 ptr = calloc(num, typesize);
380 printError(
"Insufficient memory for allocation of %llu bytes.\n", (
unsigned long long)(num) * (typesize));
391 const char* filename,
397 debugMessage(
"malloc %llu bytes [%s:%d]\n", (
unsigned long long)size, filename, line);
409 ptr = calloc(1, size);
414 printError(
"Insufficient memory for allocation of %llu bytes.\n", (
unsigned long long)size);
426 const char* filename,
433 debugMessage(
"malloc %llu elements of %llu bytes [%s:%d]\n",
434 (
unsigned long long)num, (
unsigned long long)typesize, filename, line);
445 size = num * typesize;
447 ptr = calloc(1, size);
452 printError(
"Insufficient memory for allocation of %llu bytes.\n", (
unsigned long long)size);
464 const char* filename,
483 newptr = realloc(ptr, size);
488 printError(
"Insufficient memory for reallocation of %llu bytes.\n", (
unsigned long long)size);
501 const char* filename,
520 size = num * typesize;
522 newptr = realloc(ptr, size);
527 printError(
"Insufficient memory for reallocation of %llu bytes.\n", (
unsigned long long)size);
544 memset(ptr, 0, size);
559 memcpy(ptr, source, size);
576 memmove(ptr, source, size);
584 const char* filename,
604 const char* filename,
622 const char* filename,
644 const char* filename,
665#define CHKHASH_POWER 10
666#define CHKHASH_SIZE (1<<CHKHASH_POWER)
673 long long memallocated;
674 long long maxmemused;
675 long long maxmemunused;
676 long long maxmemallocated;
693#define CHUNKLENGTH_MIN 1024
694#define CHUNKLENGTH_MAX 1048576
695#define STORESIZE_MAX 8192
696#define GARBAGE_SIZE 256
697#define ALIGNMENT (sizeof(FREELIST))
748#define CHUNK_LT(ptr,chunk) ptr < chunk->store
749#define CHUNK_GT(ptr,chunk) ptr >= chunk->storeend
794 assert(chunk->store <= chunk->storeend);
796 return (ptr >= (
void*)(chunk->store) && ptr < (
void*)(chunk->storeend));
815 if( rbTreeFindChunk(chkmem->rootchunk, ptr, &chunk) == 0 )
852 assert(chunk->storeend == (
void*)((
char*)(chunk->store) + chunk->elemsize * chunk->storesize));
854 assert(chunk->chkmem->elemsize == chunk->elemsize);
856 if( chunk->eagerfree ==
NULL )
858 else if( chunk->preveager ==
NULL )
859 assert(chunk->chkmem->firsteager == chunk);
861 if( chunk->nexteager !=
NULL )
862 assert(chunk->nexteager->preveager == chunk);
863 if( chunk->preveager !=
NULL )
864 assert(chunk->preveager->nexteager == chunk);
867 eager = chunk->eagerfree;
868 while( eager !=
NULL )
874 assert(chunk->eagerfreesize == eagerfreesize);
900 storesize += chunk->storesize;
901 eagerfreesize += chunk->eagerfreesize;
904 assert(chkmem->nchunks == nchunks);
905 assert(chkmem->storesize == storesize);
906 assert(chkmem->eagerfreesize == eagerfreesize);
908 assert(((
unsigned int) (chkmem->eagerfreesize == 0)) ^ ( (
unsigned int) (chkmem->firsteager !=
NULL)));
910 if( chkmem->firsteager !=
NULL )
911 assert(chkmem->firsteager->preveager ==
NULL);
913 lazy = chkmem->lazyfree;
918 assert(chunk->chkmem == chkmem);
922 assert(chkmem->lazyfreesize == lazyfreesize);
925#define checkChunk(chunk)
926#define checkChkmem(chkmem)
929#ifdef CHECKCLEANBUFFER
930#define CHECKCLEANBUFFER_TESTSIZE 1048576
933static uint8_t checkcleanbuffer_testblock[CHECKCLEANBUFFER_TESTSIZE];
948 if( !checkcleanbuffer_testblockinit )
951 checkcleanbuffer_testblockinit =
TRUE;
954 for( startptr = (uint8_t*)mem, endptr = (uint8_t*)(mem) + size;
955 startptr + CHECKCLEANBUFFER_TESTSIZE < endptr;
956 startptr += CHECKCLEANBUFFER_TESTSIZE )
958 assert(memcmp(startptr, checkcleanbuffer_testblock, CHECKCLEANBUFFER_TESTSIZE) == 0);
960 assert(memcmp(startptr, checkcleanbuffer_testblock, endptr - startptr) == 0);
980 debugMessage(
"linking chunk %p to chunk block %p [elemsize:%d, %d chunks]\n",
981 (
void*)chunk, (
void*)chkmem, chkmem->elemsize, chkmem->nchunks);
983 pos = rbTreeFindChunk(chkmem->rootchunk, chunk->store, &parent);
989 chkmem->storesize += chunk->storesize;
1007 chkmem = chunk->chkmem;
1009 assert(chkmem->elemsize == chunk->elemsize);
1011 debugMessage(
"unlinking chunk %p from chunk block %p [elemsize:%d, %d chunks]\n",
1012 (
void*)chunk, (
void*)chkmem, chkmem->elemsize, chkmem->nchunks);
1018 chkmem->storesize -= chunk->storesize;
1028 assert(chunk->chkmem == chkmem);
1032 chunk->nexteager = chkmem->firsteager;
1033 chunk->preveager =
NULL;
1034 if( chkmem->firsteager !=
NULL )
1036 assert(chkmem->firsteager->preveager ==
NULL);
1037 chkmem->firsteager->preveager = chunk;
1039 chkmem->firsteager = chunk;
1049 assert(chunk->eagerfreesize == 0 || chunk->eagerfreesize == chunk->storesize);
1051 if( chunk->nexteager !=
NULL )
1052 chunk->nexteager->preveager = chunk->preveager;
1053 if( chunk->preveager !=
NULL )
1054 chunk->preveager->nexteager = chunk->nexteager;
1057 assert(chunk->chkmem->firsteager == chunk);
1058 chunk->chkmem->firsteager = chunk->nexteager;
1060 chunk->nexteager =
NULL;
1061 chunk->preveager =
NULL;
1062 chunk->eagerfree =
NULL;
1082 debugMessage(
"creating new chunk in chunk block %p [elemsize: %d]\n", (
void*)chkmem, chkmem->elemsize);
1085 if( chkmem->nchunks == 0 )
1086 storesize = chkmem->initchunksize;
1088 storesize = 2 * chkmem->lastchunksize;
1093 storesize =
MAX(storesize, 1);
1094 chkmem->lastchunksize = storesize;
1098 assert( chkmem->elemsize < INT_MAX / storesize );
1101 if( newchunk ==
NULL )
1105 newchunk->store = (
void*) ((
char*) newchunk +
sizeof(
CHUNK));
1106 newchunk->storeend = (
void*) ((
char*) newchunk->store + (ptrdiff_t)storesize * chkmem->elemsize);
1107 newchunk->eagerfree =
NULL;
1108 newchunk->nexteager =
NULL;
1109 newchunk->preveager =
NULL;
1110 newchunk->chkmem = chkmem;
1111 newchunk->elemsize = chkmem->elemsize;
1112 newchunk->storesize = storesize;
1113 newchunk->eagerfreesize = 0;
1115 if( memsize !=
NULL )
1116 (*memsize) += ((
long long)((
long long)
sizeof(
CHUNK) + (
long long)storesize * chkmem->elemsize));
1118 debugMessage(
"allocated new chunk %p: %d elements with size %d\n", (
void*)newchunk, newchunk->storesize, newchunk->elemsize);
1123 for(
i = 0;
i < newchunk->storesize - 1; ++
i )
1125 freelist = (
FREELIST*) newchunk->store + (ptrdiff_t)
i * chkmem->elemsize / (ptrdiff_t)
sizeof(
FREELIST*);
1126 freelist->next = (
FREELIST*) newchunk->store + ((ptrdiff_t)
i + 1) * chkmem->elemsize / (ptrdiff_t)
sizeof(
FREELIST*);
1129 freelist = (
FREELIST*) newchunk->store + ((ptrdiff_t) newchunk->storesize - 1) * chkmem->elemsize / (ptrdiff_t)
sizeof(
FREELIST*);
1130 freelist->next = chkmem->lazyfree;
1131 chkmem->lazyfree = (
FREELIST*) (newchunk->store);
1132 chkmem->lazyfreesize += newchunk->storesize;
1154 if( memsize !=
NULL )
1155 (*memsize) -= ((
long long)
sizeof(
CHUNK) + (
long long)(*chunk)->storesize * (*chunk)->elemsize);
1174 assert((*chunk)->chkmem->firsteager !=
NULL);
1175 assert((*chunk)->eagerfreesize == (*chunk)->storesize);
1177 debugMessage(
"freeing chunk %p of chunk block %p [elemsize: %d]\n", (
void*)*chunk, (
void*)(*chunk)->chkmem, (*chunk)->chkmem->elemsize);
1180 (*chunk)->chkmem->eagerfreesize -= (*chunk)->eagerfreesize;
1181 assert((*chunk)->chkmem->eagerfreesize >= 0);
1203 assert(chunk->eagerfreesize > 0);
1206 debugMessage(
"allocating chunk element in chunk %p [elemsize: %d]\n", (
void*)chunk, chunk->chkmem->elemsize);
1209 ptr = chunk->eagerfree;
1210 chunk->eagerfree = ptr->next;
1211 chunk->eagerfreesize--;
1212 chunk->chkmem->eagerfreesize--;
1214 assert((chunk->eagerfreesize == 0 && chunk->eagerfree ==
NULL)
1215 || (chunk->eagerfreesize != 0 && chunk->eagerfree !=
NULL));
1216 assert(chunk->chkmem->eagerfreesize >= 0);
1219 if( chunk->eagerfree ==
NULL )
1221 assert(chunk->eagerfreesize == 0);
1241 debugMessage(
"freeing chunk element %p of chunk %p [elemsize: %d]\n", (
void*)ptr, (
void*)chunk, chunk->chkmem->elemsize);
1244 if( chunk->eagerfree ==
NULL )
1246 assert(chunk->eagerfreesize == 0);
1251 ((
FREELIST*)ptr)->next = chunk->eagerfree;
1253 chunk->eagerfreesize++;
1254 chunk->chkmem->eagerfreesize++;
1275 if( chkmem ==
NULL )
1278 chkmem->lazyfree =
NULL;
1279 chkmem->rootchunk =
NULL;
1280 chkmem->firsteager =
NULL;
1281 chkmem->nextchkmem =
NULL;
1282 chkmem->elemsize = size;
1283 chkmem->nchunks = 0;
1284 chkmem->lastchunksize = 0;
1285 chkmem->storesize = 0;
1286 chkmem->lazyfreesize = 0;
1287 chkmem->eagerfreesize = 0;
1288 chkmem->initchunksize = initchunksize;
1289 chkmem->garbagefactor = garbagefactor;
1291 chkmem->filename =
NULL;
1293 chkmem->ngarbagecalls = 0;
1294 chkmem->ngarbagefrees = 0;
1297 if( memsize !=
NULL )
1315 SCIPrbtreeDelete(&chkmem->rootchunk, chunk);
1316 destroyChunk(&chunk, memsize);
1319 chkmem->lazyfree =
NULL;
1320 chkmem->firsteager =
NULL;
1321 chkmem->nchunks = 0;
1322 chkmem->lastchunksize = 0;
1323 chkmem->storesize = 0;
1324 chkmem->lazyfreesize = 0;
1325 chkmem->eagerfreesize = 0;
1344 if( memsize !=
NULL )
1345 (*memsize) -= (
long long)(
sizeof(
BMS_CHKMEM));
1362 if( chkmem->lazyfree ==
NULL )
1364 assert(chkmem->lazyfreesize == 0);
1367 if( chkmem->firsteager !=
NULL )
1377 assert(chkmem->lazyfreesize > 0);
1379 ptr = chkmem->lazyfree;
1380 chkmem->lazyfree = ptr->next;
1381 chkmem->lazyfreesize--;
1403 debugMessage(
"garbage collection for chunk block %p [elemsize: %d]\n", (
void*)chkmem, chkmem->elemsize);
1406 if( chkmem->lazyfreesize + chkmem->eagerfreesize == chkmem->storesize )
1413 chkmem->ngarbagecalls++;
1417 while( chkmem->lazyfree !=
NULL )
1420 lazyfree = chkmem->lazyfree;
1421 chkmem->lazyfree = chkmem->lazyfree->next;
1422 chkmem->lazyfreesize--;
1425 chunk =
findChunk(chkmem, (
void*)lazyfree);
1429 errorMessage(
"chunk for lazy free chunk %p not found in chunk block %p\n", (
void*)lazyfree, (
void*)chkmem);
1436 assert(chunk->eagerfreesize > 0);
1438 assert(chkmem->lazyfreesize == 0);
1441 chunk = chkmem->firsteager;
1442 while( chunk !=
NULL && chkmem->nchunks > 1 )
1444 nexteager = chunk->nexteager;
1445 if( chunk->eagerfreesize == chunk->storesize )
1448 chkmem->ngarbagefrees++;
1464 const char* filename,
1471#if ( defined(CHECKMEM) || defined(CHECKCHKFREE) )
1476 printError(
"Pointer %p does not belong to chunk block %p (size: %d).\n", ptr, chkmem, chkmem->elemsize);
1481 ((
FREELIST*)ptr)->next = chkmem->lazyfree;
1483 chkmem->lazyfreesize++;
1486 if( chkmem->garbagefactor >= 0 && chkmem->nchunks > 0 && chkmem->lazyfreesize >=
GARBAGE_SIZE
1487 && chkmem->lazyfreesize + chkmem->eagerfreesize
1488 > chkmem->garbagefactor * (
double)(chkmem->storesize) / (
double)(chkmem->nchunks) )
1502 const char* filename,
1510 if( chkmem ==
NULL )
1513 printError(
"Insufficient memory for chunk block.\n");
1515 debugMessage(
"created chunk memory %p [elemsize: %d]\n", (
void*)chkmem, (
int)size);
1523 const char* filename,
1527 if( chkmem !=
NULL )
1529 debugMessage(
"clearing chunk memory %p [elemsize: %d]\n", (
void*)chkmem, chkmem->elemsize);
1535 printError(
"Tried to clear null chunk block.\n");
1542 const char* filename,
1548 if( *chkmem !=
NULL )
1550 debugMessage(
"destroying chunk memory %p [elemsize: %d]\n", (
void*)*chkmem, (*chkmem)->elemsize);
1556 printError(
"Tried to destroy null chunk block.\n");
1564 const char* filename,
1571 assert((
int)size == chkmem->elemsize);
1578 printError(
"Insufficient memory for new chunk.\n");
1580 debugMessage(
"alloced %8llu bytes in %p [%s:%d]\n", (
unsigned long long)size, (
void*)ptr, filename, line);
1592 const char* filename,
1600 assert((
int)size == chkmem->elemsize);
1614 const char* filename,
1619 assert((
int)size == chkmem->elemsize);
1624 debugMessage(
"free %8d bytes in %p [%s:%d]\n", chkmem->elemsize, *ptr, filename, line);
1634 printError(
"Tried to free null chunk pointer.\n");
1643 const char* filename,
1648 assert((
int)size == chkmem->elemsize);
1653 debugMessage(
"free %8d bytes in %p [%s:%d]\n", chkmem->elemsize, *ptr, filename, line);
1667 debugMessage(
"garbage collection on chunk memory %p [elemsize: %d]\n", (
void*)chkmem, chkmem->elemsize);
1679 return ((
long long)(chkmem->elemsize) * (
long long)(chkmem->storesize));
1705 long long tmpmemalloc = 0LL;
1706 long long tmpmemused = 0LL;
1713 chkmem = blkmem->chkmemhash[
i];
1714 while( chkmem !=
NULL )
1717 tmpmemalloc += ((chkmem->elemsize * chkmem->storesize) + chkmem->nchunks *
sizeof(
CHUNK) +
sizeof(
BMS_CHKMEM));
1718 tmpmemused += (chkmem->elemsize * (chkmem->storesize - chkmem->eagerfreesize - chkmem->lazyfreesize));
1719 chkmem = chkmem->nextchkmem;
1722 assert(tmpmemalloc == blkmem->memallocated);
1723 assert(tmpmemused == blkmem->memused);
1726#define checkBlkmem(blkmem)
1749 chkmem = blkmem->chkmemhash[
i];
1751 chkmem = chkmem->nextchkmem;
1765 return ((uint32_t)size * UINT32_C(0x9e3779b9)) >> (32-
CHKHASH_POWER);
1773 const char* filename,
1781 if( blkmem !=
NULL )
1784 blkmem->chkmemhash[
i] =
NULL;
1785 blkmem->initchunksize = initchunksize;
1786 blkmem->garbagefactor = garbagefactor;
1787 blkmem->memused = 0;
1788 blkmem->memallocated = 0;
1789 blkmem->maxmemused = 0;
1790 blkmem->maxmemunused = 0;
1791 blkmem->maxmemallocated = 0;
1796 printError(
"Insufficient memory for block memory header.\n");
1805 const char* filename,
1813 if( blkmem !=
NULL )
1817 chkmem = blkmem->chkmemhash[
i];
1818 while( chkmem !=
NULL )
1820 nextchkmem = chkmem->nextchkmem;
1822 chkmem = nextchkmem;
1824 blkmem->chkmemhash[
i] =
NULL;
1826 blkmem->memused = 0;
1827 assert(blkmem->memallocated == 0);
1832 printError(
"Tried to clear null block memory.\n");
1839 const char* filename,
1845 if( *blkmem !=
NULL )
1854 printError(
"Tried to destroy null block memory.\n");
1863 const char* filename,
1868 uint32_t hashnumber;
1874 if( size > INT_MAX )
1883 chkmemptr = &(blkmem->chkmemhash[hashnumber]);
1884 while( *chkmemptr !=
NULL && (*chkmemptr)->elemsize != (
int)size )
1885 chkmemptr = &((*chkmemptr)->nextchkmem);
1888 if( *chkmemptr ==
NULL )
1890 *chkmemptr =
createChkmem((
int)size, blkmem->initchunksize, blkmem->garbagefactor, &blkmem->memallocated);
1891 if( *chkmemptr ==
NULL )
1894 printError(
"Insufficient memory for chunk block.\n");
1899 (*chkmemptr)->line = line;
1907 (*chkmemptr)->line = line;
1917 printError(
"Insufficient memory for new chunk.\n");
1919 debugMessage(
"alloced %8llu bytes in %p [%s:%d]\n", (
unsigned long long)size, ptr, filename, line);
1922 blkmem->memused += (
long long) size;
1923 blkmem->maxmemused =
MAX(blkmem->maxmemused, blkmem->memused);
1924 blkmem->maxmemunused =
MAX(blkmem->maxmemunused, blkmem->memallocated - blkmem->memused);
1925 blkmem->maxmemallocated =
MAX(blkmem->maxmemallocated, blkmem->memallocated);
1927 assert(blkmem->memused >= 0);
1928 assert(blkmem->memallocated >= 0);
1939 const char* filename,
1959 const char* filename,
1977 const char* filename,
1998 const char* filename,
2017 const char* filename,
2040 if( oldsize == newsize )
2044 if( newptr !=
NULL )
2058 const char* filename,
2079 if ( oldnum == newnum )
2083 if ( newptr !=
NULL )
2095 const char* filename,
2116 const char* filename,
2137 const char* filename,
2142 uint32_t hashnumber;
2152 debugMessage(
"free %8llu bytes in %p [%s:%d]\n", (
unsigned long long)size, *ptr, filename, line);
2155 chkmem = blkmem->chkmemhash[hashnumber];
2156 while( chkmem !=
NULL && chkmem->elemsize != (
int)size )
2157 chkmem = chkmem->nextchkmem;
2158 if( chkmem ==
NULL )
2161 printError(
"Tried to free pointer <%p> in block memory <%p> of unknown size %llu.\n", *ptr, (
void*)blkmem, (
unsigned long long)size);
2164 assert(chkmem->elemsize == (
int)size);
2168 blkmem->memused -= (
long long) size;
2170 blkmem->maxmemunused =
MAX(blkmem->maxmemunused, blkmem->memallocated - blkmem->memused);
2172 assert(blkmem->memused >= 0);
2173 assert(blkmem->memallocated >= 0);
2185 const char* filename,
2194 else if( size != 0 )
2197 printError(
"Tried to free null block pointer.\n");
2207 const char* filename,
2236 chkmemptr = &blkmem->chkmemhash[
i];
2237 while( *chkmemptr !=
NULL )
2241 if( (*chkmemptr)->nchunks == 0 )
2245 assert((*chkmemptr)->lazyfreesize == 0);
2246 nextchkmem = (*chkmemptr)->nextchkmem;
2248 *chkmemptr = nextchkmem;
2252 chkmemptr = &(*chkmemptr)->nextchkmem;
2264 return blkmem->memallocated;
2274 return blkmem->memused;
2284 return blkmem->memallocated - blkmem->memused;
2294 return blkmem->maxmemused;
2304 return blkmem->maxmemunused;
2314 return blkmem->maxmemallocated;
2331 if( chkmem ==
NULL )
2334 return (
size_t)(chkmem->elemsize);
2344 int nunusedblocks = 0;
2345 int totalnchunks = 0;
2346 int totalneagerchunks = 0;
2347 int totalnelems = 0;
2348 int totalneagerelems = 0;
2349 int totalnlazyelems = 0;
2351 int totalngarbagecalls = 0;
2352 int totalngarbagefrees = 0;
2354 long long allocedmem = 0;
2355 long long freemem = 0;
2359 printInfo(
" ElSize #Chunk #Eag #Elems #EagFr #LazFr #GCl #GFr Free MBytes First Allocator\n");
2361 printInfo(
" ElSize #Chunk #Eag #Elems #EagFr #LazFr Free MBytes\n");
2368 chkmem = blkmem->chkmemhash[
i];
2369 while( chkmem !=
NULL )
2373 int neagerchunks = 0;
2374 int neagerelems = 0;
2378 assert(chunk != NULL);
2379 assert(chunk->elemsize == chkmem->elemsize);
2380 assert(chunk->chkmem == chkmem);
2382 nelems += chunk->storesize;
2383 if( chunk->eagerfree != NULL )
2386 neagerelems += chunk->eagerfreesize;
2390 assert(nchunks == chkmem->nchunks);
2391 assert(nelems == chkmem->storesize);
2392 assert(neagerelems == chkmem->eagerfreesize);
2397 allocedmem += (
long long)chkmem->elemsize * (
long long)nelems;
2398 freemem += (
long long)chkmem->elemsize * ((
long long)neagerelems + (
long long)chkmem->lazyfreesize);
2401 printInfo(
"%7d %6d %4d %7d %7d %7d %5d %4d %5.1f%% %6.1f %s:%d\n",
2402 chkmem->elemsize, nchunks, neagerchunks, nelems,
2403 neagerelems, chkmem->lazyfreesize, chkmem->ngarbagecalls, chkmem->ngarbagefrees,
2404 100.0 * (
double) (neagerelems + chkmem->lazyfreesize) / (
double) (nelems),
2405 (
double)chkmem->elemsize * nelems / (1024.0*1024.0),
2406 chkmem->filename, chkmem->line);
2408 printInfo(
"%7d %6d %4d %7d %7d %7d %5.1f%% %6.1f\n",
2409 chkmem->elemsize, nchunks, neagerchunks, nelems,
2410 neagerelems, chkmem->lazyfreesize,
2411 100.0 * (
double) (neagerelems + chkmem->lazyfreesize) / (
double) (nelems),
2412 (
double)chkmem->elemsize * nelems / (1024.0*1024.0));
2418 printInfo(
"%7d <unused> %5d %4d %s:%d\n",
2419 chkmem->elemsize, chkmem->ngarbagecalls, chkmem->ngarbagefrees,
2420 chkmem->filename, chkmem->line);
2422 printInfo(
"%7d <unused>\n", chkmem->elemsize);
2426 totalnchunks += nchunks;
2427 totalneagerchunks += neagerchunks;
2428 totalnelems += nelems;
2429 totalneagerelems += neagerelems;
2430 totalnlazyelems += chkmem->lazyfreesize;
2432 totalngarbagecalls += chkmem->ngarbagecalls;
2433 totalngarbagefrees += chkmem->ngarbagefrees;
2435 chkmem = chkmem->nextchkmem;
2439 printInfo(
" Total %6d %4d %7d %7d %7d %5d %4d %5.1f%% %6.1f\n",
2440 totalnchunks, totalneagerchunks, totalnelems, totalneagerelems, totalnlazyelems,
2441 totalngarbagecalls, totalngarbagefrees,
2442 totalnelems > 0 ? 100.0 * (
double) (totalneagerelems + totalnlazyelems) / (
double) (totalnelems) : 0.0,
2443 (
double)allocedmem/(1024.0*1024.0));
2445 printInfo(
" Total %6d %4d %7d %7d %7d %5.1f%% %6.1f\n",
2446 totalnchunks, totalneagerchunks, totalnelems, totalneagerelems, totalnlazyelems,
2447 totalnelems > 0 ? 100.0 * (
double) (totalneagerelems + totalnlazyelems) / (
double) (totalnelems) : 0.0,
2448 (
double)allocedmem/(1024.0*1024.0));
2451 nblocks + nunusedblocks, nunusedblocks, allocedmem, freemem);
2452 if( allocedmem > 0 )
2453 printInfo(
" (%.1f%%)", 100.0 * (
double) freemem / (
double) allocedmem);
2456 printInfo(
"Memory Peaks: Used Lazy Total\n");
2457 printInfo(
" %6.1f %6.1f %6.1f MBytes\n", (
double)blkmem->maxmemused / (1024.0 * 1024.0),
2458 (
double)blkmem->maxmemunused / (1024.0 * 1024.0), (
double)blkmem->maxmemallocated / (1024.0 * 1024.0));
2467 long long allocedmem = 0;
2468 long long freemem = 0;
2475 chkmem = blkmem->chkmemhash[
i];
2476 while( chkmem !=
NULL )
2480 int neagerelems = 0;
2484 assert(chunk != NULL);
2485 assert(chunk->elemsize == chkmem->elemsize);
2486 assert(chunk->chkmem == chkmem);
2488 nelems += chunk->storesize;
2489 if( chunk->eagerfree != NULL )
2490 neagerelems += chunk->eagerfreesize;
2493 assert(nchunks == chkmem->nchunks);
2495 assert(nelems == chkmem->storesize);
2496 assert(neagerelems == chkmem->eagerfreesize);
2500 allocedmem += (
long long)chkmem->elemsize * (
long long)nelems;
2501 freemem += (
long long)chkmem->elemsize * ((
long long)neagerelems + (
long long)chkmem->lazyfreesize);
2503 if( nelems != neagerelems + chkmem->lazyfreesize )
2507 (((
long long)nelems - (
long long)neagerelems) - (
long long)chkmem->lazyfreesize)
2508 * (
long long)(chkmem->elemsize),
2509 (nelems - neagerelems) - chkmem->lazyfreesize, (
long long)(chkmem->elemsize),
2510 chkmem->filename, chkmem->line);
2513 ((nelems - neagerelems) - chkmem->lazyfreesize) * (
long long)(chkmem->elemsize),
2514 (nelems - neagerelems) - chkmem->lazyfreesize, (
long long)(chkmem->elemsize));
2518 chkmem = chkmem->nextchkmem;
2522 if( allocedmem != freemem )
2527 return allocedmem - freemem;
2558 double arraygrowfac,
2561 const char* filename,
2567 assert( arraygrowinit > 0 );
2568 assert( arraygrowfac > 0.0 );
2571 if ( buffer !=
NULL )
2577 buffer->
clean = clean;
2586 printError(
"Insufficient memory for buffer memory header.\n");
2595 const char* filename,
2601 if ( *buffer !=
NULL )
2603 i = (*buffer)->ndata;
2607 assert( ! (*buffer)->used[
i] );
2621 printError(
"Tried to free null buffer memory.\n");
2632 assert( arraygrowfac > 0.0 );
2644 assert( arraygrowinit > 0 );
2649#ifndef SCIP_NOBUFFERMEM
2663 assert( growfac >= 1.0 );
2665 if ( growfac == 1.0 )
2666 size =
MAX(initsize, num);
2672 initsize =
MAX(initsize, 4);
2677 while ( size < num && size > oldsize )
2680 size = (size_t)(growfac * size + initsize);
2684 if ( size <= oldsize )
2688 assert( size >= initsize );
2700 const char* filename,
2705#ifndef SCIP_NOBUFFERMEM
2709#ifndef SCIP_NOBUFFERMEM
2729 printError(
"Insufficient memory for reallocating buffer data storage.\n");
2736 printError(
"Insufficient memory for reallocating buffer size storage.\n");
2743 printError(
"Insufficient memory for reallocating buffer used storage.\n");
2748 for (
i = buffer->
ndata;
i < newsize; ++
i)
2751 buffer->
size[
i] = 0;
2754 buffer->
ndata = newsize;
2761 if ( buffer->
size[bufnum] < size )
2772 char* tmpptr = (
char*)(buffer->
data[bufnum]);
2773 size_t inc = buffer->
size[bufnum] /
sizeof(*tmpptr);
2780 buffer->
size[bufnum] = newsize;
2782 if ( buffer->
data[bufnum] ==
NULL )
2785 printError(
"Insufficient memory for reallocating buffer storage.\n");
2791#ifdef CHECKCLEANBUFFER
2794 checkCleanmem(buffer->
data[bufnum], buffer->
size[bufnum]);
2797 ptr = buffer->
data[bufnum];
2801 debugMessage(
"Allocated buffer %llu/%llu at %p of size %llu (required size: %llu) for pointer %p.\n",
2802 (
unsigned long long)bufnum, (
unsigned long long)(buffer->
ndata), buffer->
data[bufnum],
2803 (
unsigned long long)(buffer->
size[bufnum]), (
unsigned long long)size, ptr);
2826 const char* filename,
2847 const char* filename,
2868 const char* filename,
2887 const char* filename,
2892#ifndef SCIP_NOBUFFERMEM
2896#ifndef SCIP_NOBUFFERMEM
2912 while ( bufnum > 0 && buffer->
data[bufnum] != ptr )
2921 if ( size > buffer->
size[bufnum] )
2930 buffer->
size[bufnum] = newsize;
2931 if ( buffer->
data[bufnum] ==
NULL )
2934 printError(
"Insufficient memory for reallocating buffer storage.\n");
2937 newptr = buffer->
data[bufnum];
2942 debugMessage(
"Reallocated buffer %llu/%llu at %p to size %llu (required size: %llu) for pointer %p.\n",
2943 (
unsigned long long)bufnum, (
unsigned long long)(buffer->
ndata), buffer->
data[bufnum],
2944 (
unsigned long long)(buffer->
size[bufnum]), (
unsigned long long)size, newptr);
2959 const char* filename,
2981 const char* filename,
3002 const char* filename,
3026 const char* filename,
3049 const char* filename,
3066 while ( bufnum > 0 && buffer->
data[bufnum] != *ptr )
3069#ifdef CHECKBUFFERORDER
3070 if ( bufnum < buffer->firstfree - 1 )
3072 warningMessage(
"[%s:%d]: freeing buffer in wrong order.\n", filename, line);
3077 if ( bufnum == 0 && buffer->
data[bufnum] != *ptr )
3080 printError(
"Tried to free unknown buffer pointer.\n");
3083 if ( ! buffer->
used[bufnum] )
3086 printError(
"Tried to free buffer pointer already freed.\n");
3091#ifdef CHECKCLEANBUFFER
3094 checkCleanmem(buffer->
data[bufnum], buffer->
size[bufnum]);
3103 debugMessage(
"Freed buffer %llu/%llu at %p of size %llu for pointer %p, first free is %llu.\n",
3104 (
unsigned long long)bufnum, (
unsigned long long)(buffer->
ndata), buffer->
data[bufnum],
3105 (
unsigned long long)(buffer->
size[bufnum]), *ptr, (
unsigned long long)(buffer->
firstfree));
3114 const char* filename,
3120#ifndef SCIP_NOBUFFERMEM
3126 printError(
"Tried to free null buffer pointer.\n");
3137 const char* filename,
3145#ifndef SCIP_NOBUFFERMEM
3169 size_t totalmem = 0UL;
3173 for (
i = 0;
i < buffer->
ndata; ++
i)
3174 totalmem += buffer->
size[
i];
3178 return (
long long) buffer->
totalmem;
3192 for (
i = 0;
i < buffer->
ndata; ++
i)
3194 printf(
"[%c] %8llu bytes at %p\n", buffer->
used[
i] ?
'*' :
' ', (
unsigned long long)(buffer->
size[
i]), buffer->
data[
i]);
3195 totalmem += buffer->
size[
i];
3197 printf(
" %8llu bytes total in %llu buffers\n", (
unsigned long long)totalmem, (
unsigned long long)(buffer->
ndata));
common defines and data types used in all packages of SCIP
static assert(heur !=NULL)
if(SCIPgetNContVars(scip)+SCIPgetNContImplVars(scip)==SCIPgetNVars(scip))
while(!lperror &&!cutoff &&lpsolstat==SCIP_LPSOLSTAT_OPTIMAL &&(divedepth< 10||(divedepth< maxdivedepth &&heurdata->nlpiterations< maxnlpiterations &&objval< searchbound)) &&!SCIPisStopped(scip))
assert(minobj< SCIPgetCutoffbound(scip))
static CHUNK * findChunk(const BMS_CHKMEM *chkmem, const void *ptr)
void BMSfreeChunkMemory_call(BMS_CHKMEM *chkmem, void **ptr, size_t size, const char *filename, int line)
void * BMSallocClearMemory_call(size_t num, size_t typesize, const char *filename, int line)
static int isPtrInChkmem(const BMS_CHKMEM *chkmem, const void *ptr)
void * BMSduplicateBufferMemory_call(BMS_BUFMEM *buffer, const void *source, size_t size, const char *filename, int line)
void * BMSduplicateMemoryArray_call(const void *source, size_t num, size_t typesize, const char *filename, int line)
#define removeMemlistEntry(ptr, filename, line)
void * BMSallocMemory_call(size_t size, const char *filename, int line)
void BMSfreeBlockMemoryNull_call(BMS_BLKMEM *blkmem, void **ptr, size_t size, const char *filename, int line)
#define CHUNK_LT(ptr, chunk)
static void destroyChunk(CHUNK **chunk, long long *memsize)
void BMSgarbagecollectChunkMemory_call(BMS_CHKMEM *chkmem)
size_t BMSgetBlockPointerSize_call(const BMS_BLKMEM *blkmem, const void *ptr)
void BMSdisplayMemory_call(void)
static void destroyChkmem(BMS_CHKMEM **chkmem, long long *memsize)
static INLINE void BMSfreeBlockMemory_work(BMS_BLKMEM *blkmem, void **ptr, size_t size, const char *filename, int line)
int BMSisAligned(size_t size)
void BMSclearBlockMemory_call(BMS_BLKMEM *blkmem, const char *filename, int line)
#define CHUNK_GT(ptr, chunk)
long long BMScheckEmptyBlockMemory_call(const BMS_BLKMEM *blkmem)
long long BMSgetBufferMemoryUsed(const BMS_BUFMEM *buffer)
void BMSfreeBufferMemory_call(BMS_BUFMEM *buffer, void **ptr, const char *filename, int line)
void BMSfreeMemory_call(void **ptr, const char *filename, int line)
size_t BMSgetPointerSize_call(const void *ptr)
void * BMSreallocBlockMemory_call(BMS_BLKMEM *blkmem, void *ptr, size_t oldsize, size_t newsize, const char *filename, int line)
void BMSfreeMemoryNull_call(void **ptr, const char *filename, int line)
void BMSsetBufferMemoryArraygrowinit(BMS_BUFMEM *buffer, int arraygrowinit)
static void unlinkChunk(CHUNK *chunk)
static uint32_t getHashNumber(size_t size)
void BMSdestroyBufferMemory_call(BMS_BUFMEM **buffer, const char *filename, int line)
#define addMemlistEntry(ptr, size, filename, line)
void BMSclearChunkMemory_call(BMS_CHKMEM *chkmem, const char *filename, int line)
void * BMSreallocBufferMemory_call(BMS_BUFMEM *buffer, void *ptr, size_t size, const char *filename, int line)
static INLINE void BMSfreeBufferMemory_work(BMS_BUFMEM *buffer, void **ptr, const char *filename, int line)
static size_t calcMemoryGrowSize(size_t initsize, SCIP_Real growfac, size_t num)
#define printErrorHeader(f, l)
void * BMSreallocMemoryArray_call(void *ptr, size_t num, size_t typesize, const char *filename, int line)
long long BMSgetBlockMemoryUsedMax_call(const BMS_BLKMEM *blkmem)
static BMS_CHKMEM * findChkmem(const BMS_BLKMEM *blkmem, const void *ptr)
static BMS_CHKMEM * createChkmem(int size, int initchunksize, int garbagefactor, long long *memsize)
void * BMSallocBufferMemoryArray_call(BMS_BUFMEM *buffer, size_t num, size_t typesize, const char *filename, int line)
void BMSmoveMemory_call(void *ptr, const void *source, size_t size)
static void freeChunk(CHUNK **chunk, long long *memsize)
static void freeChkmemElement(BMS_CHKMEM *chkmem, void *ptr, long long *memsize, const char *filename, int line)
static void freeChunkElement(CHUNK *chunk, void *ptr)
void * BMSallocBlockMemoryArray_call(BMS_BLKMEM *blkmem, size_t num, size_t typesize, const char *filename, int line)
static INLINE void * BMSallocBlockMemory_work(BMS_BLKMEM *blkmem, size_t size, const char *filename, int line)
void * BMSreallocBufferMemoryArray_call(BMS_BUFMEM *buffer, void *ptr, size_t num, size_t typesize, const char *filename, int line)
static void garbagecollectChkmem(BMS_CHKMEM *chkmem, long long *memsize)
void BMSdisplayBlockMemory_call(const BMS_BLKMEM *blkmem)
long long BMSgetBlockMemoryAllocated_call(const BMS_BLKMEM *blkmem)
void BMSclearMemory_call(void *ptr, size_t size)
long long BMSgetBlockMemoryUsed_call(const BMS_BLKMEM *blkmem)
void BMSfreeBufferMemoryNull_call(BMS_BUFMEM *buffer, void **ptr, const char *filename, int line)
void * BMSallocChunkMemory_call(BMS_CHKMEM *chkmem, size_t size, const char *filename, int line)
void * BMSreallocMemory_call(void *ptr, size_t size, const char *filename, int line)
BMS_BLKMEM * BMScreateBlockMemory_call(int initchunksize, int garbagefactor, const char *filename, int line)
void * BMSallocClearBlockMemoryArray_call(BMS_BLKMEM *blkmem, size_t num, size_t typesize, const char *filename, int line)
void * BMSduplicateBlockMemoryArray_call(BMS_BLKMEM *blkmem, const void *source, size_t num, size_t typesize, const char *filename, int line)
void * BMSduplicateMemory_call(const void *source, size_t size, const char *filename, int line)
BMS_BUFMEM * BMScreateBufferMemory_call(double arraygrowfac, int arraygrowinit, unsigned int clean, const char *filename, int line)
static INLINE void * BMSreallocBufferMemory_work(BMS_BUFMEM *buffer, void *ptr, size_t size, const char *filename, int line)
static void unlinkEagerChunk(CHUNK *chunk)
void BMSdestroyBlockMemory_call(BMS_BLKMEM **blkmem, const char *filename, int line)
static void linkEagerChunk(BMS_CHKMEM *chkmem, CHUNK *chunk)
void * BMSallocMemoryArray_call(size_t num, size_t typesize, const char *filename, int line)
long long BMSgetBlockMemoryUnused_call(const BMS_BLKMEM *blkmem)
void BMSprintBufferMemory(BMS_BUFMEM *buffer)
void * BMSduplicateChunkMemory_call(BMS_CHKMEM *chkmem, const void *source, size_t size, const char *filename, int line)
long long BMSgetMemoryUsed_call(void)
void BMScheckEmptyMemory_call(void)
static int linkChunk(BMS_CHKMEM *chkmem, CHUNK *chunk)
static void * allocChkmemElement(BMS_CHKMEM *chkmem, long long *memsize)
static void clearChkmem(BMS_CHKMEM *chkmem, long long *memsize)
#define checkBlkmem(blkmem)
void * BMSallocClearBlockMemory_call(BMS_BLKMEM *blkmem, size_t size, const char *filename, int line)
void * BMSallocBufferMemory_call(BMS_BUFMEM *buffer, size_t size, const char *filename, int line)
BMS_CHKMEM * BMScreateChunkMemory_call(size_t size, int initchunksize, int garbagefactor, const char *filename, int line)
static INLINE void * BMSallocBufferMemory_work(BMS_BUFMEM *buffer, size_t size, const char *filename, int line)
void * BMSallocBlockMemory_call(BMS_BLKMEM *blkmem, size_t size, const char *filename, int line)
void BMScopyMemory_call(void *ptr, const void *source, size_t size)
static void * allocChunkElement(CHUNK *chunk)
#define checkChkmem(chkmem)
static int createChunk(BMS_CHKMEM *chkmem, long long *memsize)
long long BMSgetChunkMemoryUsed_call(const BMS_CHKMEM *chkmem)
static static void alignSize(size_t *size)
void BMSfreeChunkMemoryNull_call(BMS_CHKMEM *chkmem, void **ptr, size_t size, const char *filename, int line)
void BMSsetBufferMemoryArraygrowfac(BMS_BUFMEM *buffer, double arraygrowfac)
static int isPtrInChunk(const CHUNK *chunk, const void *ptr)
void * BMSduplicateBufferMemoryArray_call(BMS_BUFMEM *buffer, const void *source, size_t num, size_t typesize, const char *filename, int line)
void BMSdestroyChunkMemory_call(BMS_CHKMEM **chkmem, const char *filename, int line)
void BMSgarbagecollectBlockMemory_call(BMS_BLKMEM *blkmem)
void BMSfreeBlockMemory_call(BMS_BLKMEM *blkmem, void **ptr, size_t size, const char *filename, int line)
void * BMSallocClearBufferMemoryArray_call(BMS_BUFMEM *buffer, size_t num, size_t typesize, const char *filename, int line)
long long BMSgetBlockMemoryUnusedMax_call(const BMS_BLKMEM *blkmem)
void * BMSduplicateBlockMemory_call(BMS_BLKMEM *blkmem, const void *source, size_t size, const char *filename, int line)
void BMSalignMemsize(size_t *size)
void * BMSreallocBlockMemoryArray_call(BMS_BLKMEM *blkmem, void *ptr, size_t oldnum, size_t newnum, size_t typesize, const char *filename, int line)
size_t BMSgetNUsedBufferMemory(BMS_BUFMEM *buffer)
long long BMSgetBlockMemoryAllocatedMax_call(const BMS_BLKMEM *blkmem)
#define checkChunk(chunk)
memory allocation routines
#define BMSallocClearMemorySize(ptr, size)
#define BMSfreeMemory(ptr)
#define BMSreallocMemoryArray(ptr, num)
struct BMS_ChkMem BMS_CHKMEM
#define BMSduplicateMemoryArray(ptr, source, num)
#define BMSreallocMemorySize(ptr, size)
#define BMScopyMemorySize(ptr, source, size)
#define BMSclearMemorySize(ptr, size)
struct BMS_BufMem BMS_BUFMEM
struct BMS_BlkMem BMS_BLKMEM
#define BMSfreeMemoryArrayNull(ptr)
#define BMSallocMemorySize(ptr, size)
#define BMSallocMemory(ptr)
public methods for message output
intrusive red black tree datastructure
#define SCIPrbtreeDelete(root, node)
#define SCIPrbtreeInsert(r, p, c, n)
#define SCIP_DEF_RBTREE_FIND(NAME, KEYTYPE, NODETYPE, LT, GT)
#define FOR_EACH_NODE(type, n, r, body)
unsigned int arraygrowinit