|
|
Go to the documentation of this file.
43 #ifdef SCIPdebugMessage
44 #define debugMessage SCIPdebugMessage
45 #define errorMessage SCIPerrorMessage
47 #define debugMessage while( FALSE ) printf
48 #define errorMessage printf
49 #define printErrorHeader(f,l) printf("[%s:%d] ERROR: ", f, l)
50 #define printError printf
53 #define warningMessage printf
54 #define printInfo printf
62 #define MAX(x,y) ((x) >= (y) ? (x) : (y))
63 #define MIN(x,y) ((x) <= (y) ? (x) : (y))
66 #ifndef SCIP_LONGINT_FORMAT
67 #if defined(_WIN32) || defined(_WIN64)
68 #define LONGINT_FORMAT "I64d"
70 #define LONGINT_FORMAT "lld"
73 #define LONGINT_FORMAT SCIP_LONGINT_FORMAT
76 #ifndef SCIP_MAXMEMSIZE
78 #define MAXMEMSIZE SIZE_MAX / 2
80 #define MAXMEMSIZE SCIP_MAXMEMSIZE
85 #if defined(_WIN32) || defined(_WIN64) || defined(__STDC__)
86 #define INLINE __inline
99 #if !defined(NDEBUG) && defined(NPARASCIP)
101 typedef struct Memlist MEMLIST;
113 static MEMLIST* memlist = NULL;
114 static size_t memused = 0;
123 MEMLIST* list = memlist;
126 while( list != NULL )
131 assert(used == memused);
134 #define checkMemlist()
139 void addMemlistEntry(
142 const char* filename,
148 assert(ptr != NULL && size > 0);
150 list = (MEMLIST*)malloc( sizeof(MEMLIST));
151 assert(list != NULL);
155 list->filename = strdup(filename);
156 assert(list->filename != NULL);
158 list->next = memlist;
166 void removeMemlistEntry(
168 const char* filename,
179 while( list != NULL && ptr != list->ptr )
181 listptr = &(list->next);
186 assert(ptr == list->ptr);
188 *listptr = list->next;
189 assert( list->size <= memused );
190 memused -= list->size;
191 free(list->filename);
197 printError( "Tried to free unknown pointer <%p>.\n", ptr);
210 while( list != NULL && ptr != list->ptr )
228 while( list != NULL )
230 printInfo( "%12p %8llu %s:%d\n", list->ptr, ( unsigned long long) list->size, list->filename, list->line);
234 printInfo( "Total: %8llu\n", ( unsigned long long) memused);
235 if( used != memused )
237 errorMessage( "Used memory in list sums up to %llu instead of %llu\n", ( unsigned long long)used, ( unsigned long long)memused);
247 if( memlist != NULL || memused > 0 )
259 return ( long long) memused;
282 printInfo( "Optimized version of memory shell linked - no memory diagnostics available.\n");
292 printInfo( "Optimized version of memory shell linked - no memory leakage check available.\n");
310 const char* filename,
316 debugMessage( "calloc %llu elements of %llu bytes [%s:%d]\n", ( unsigned long long)num, ( unsigned long long)typesize,
329 typesize = MAX(typesize, 1);
330 ptr = calloc(num, typesize);
335 printError( "Insufficient memory for allocation of %llu bytes.\n", ( unsigned long long)(num * typesize));
337 #if !defined(NDEBUG) && defined(NPARASCIP)
339 addMemlistEntry(ptr, num*typesize, filename, line);
348 const char* filename,
354 debugMessage( "malloc %llu bytes [%s:%d]\n", ( unsigned long long)size, filename, line);
371 printError( "Insufficient memory for allocation of %llu bytes.\n", ( unsigned long long)size);
373 #if !defined(NDEBUG) && defined(NPARASCIP)
375 addMemlistEntry(ptr, size, filename, line);
385 const char* filename,
392 debugMessage( "malloc %llu elements of %llu bytes [%s:%d]\n",
393 ( unsigned long long)num, ( unsigned long long)typesize, filename, line);
404 size = num * typesize;
411 printError( "Insufficient memory for allocation of %llu bytes.\n", ( unsigned long long)size);
413 #if !defined(NDEBUG) && defined(NPARASCIP)
415 addMemlistEntry(ptr, size, filename, line);
425 const char* filename,
431 #if !defined(NDEBUG) && defined(NPARASCIP)
433 removeMemlistEntry(ptr, filename, line);
446 newptr = realloc(ptr, size);
451 printError( "Insufficient memory for reallocation of %llu bytes.\n", ( unsigned long long)size);
453 #if !defined(NDEBUG) && defined(NPARASCIP)
455 addMemlistEntry(newptr, size, filename, line);
466 const char* filename,
473 #if !defined(NDEBUG) && defined(NPARASCIP)
475 removeMemlistEntry(ptr, filename, line);
487 size = num * typesize;
489 newptr = realloc(ptr, size);
494 printError( "Insufficient memory for reallocation of %llu bytes.\n", ( unsigned long long)size);
496 #if !defined(NDEBUG) && defined(NPARASCIP)
498 addMemlistEntry(newptr, size, filename, line);
513 memset(ptr, 0, size);
527 assert(source != NULL);
528 memcpy(ptr, source, size);
544 assert(source != NULL);
545 memmove(ptr, source, size);
553 const char* filename,
559 assert(source != NULL || size == 0);
573 const char* filename,
579 assert(source != NULL || num == 0);
591 const char* filename,
595 assert( ptr != NULL );
598 #if !defined(NDEBUG) && defined(NPARASCIP)
599 removeMemlistEntry(*ptr, filename, line);
614 const char* filename,
618 assert( ptr != NULL );
621 #if !defined(NDEBUG) && defined(NPARASCIP)
622 removeMemlistEntry(*ptr, filename, line);
642 #define CHUNKLENGTH_MIN 1024
643 #define CHUNKLENGTH_MAX 1048576
644 #define STORESIZE_MAX 8192
645 #define GARBAGE_SIZE 256
646 #define ALIGNMENT (sizeof(FREELIST))
736 assert(chunk != NULL);
737 assert(chunk->store <= chunk->storeend);
739 return (ptr >= ( void*)(chunk->store) && ptr < ( void*)(chunk->storeend));
758 assert(chkmem != NULL);
763 right = chkmem->nchunks-1;
764 while( left <= right )
766 middle = (left+right)/2;
767 assert(0 <= middle && middle < chkmem->nchunks);
768 chunk = chkmem->chunks[middle];
769 assert(chunk != NULL);
770 if( ptr < chunk->store )
772 else if( ptr >= chunk->storeend )
789 assert(chkmem != NULL);
810 assert(chunk != NULL);
811 assert(chunk->store != NULL);
812 assert(chunk->storeend == ( void*)(( char*)(chunk->store) + chunk->elemsize * chunk->storesize));
813 assert(chunk->chkmem != NULL);
814 assert(chunk->chkmem->elemsize == chunk->elemsize);
816 if( chunk->eagerfree == NULL )
817 assert(chunk->nexteager == NULL && chunk->preveager == NULL);
818 else if( chunk->preveager == NULL )
819 assert(chunk->chkmem->firsteager == chunk);
821 if( chunk->nexteager != NULL )
822 assert(chunk->nexteager->preveager == chunk);
823 if( chunk->preveager != NULL )
824 assert(chunk->preveager->nexteager == chunk);
827 eager = chunk->eagerfree;
828 while( eager != NULL )
834 assert(chunk->eagerfreesize == eagerfreesize);
851 assert(chkmem != NULL);
852 assert(chkmem->chunks != NULL || chkmem->chunkssize == 0);
853 assert(chkmem->nchunks <= chkmem->chunkssize);
860 for( i = 0; i < chkmem->nchunks; ++i )
862 chunk = chkmem->chunks[i];
863 assert(chunk != NULL);
867 storesize += chunk->storesize;
868 eagerfreesize += chunk->eagerfreesize;
870 assert(chkmem->nchunks == nchunks);
871 assert(chkmem->storesize == storesize);
872 assert(chkmem->eagerfreesize == eagerfreesize);
874 assert((chkmem->eagerfreesize == 0) ^ (chkmem->firsteager != NULL));
876 if( chkmem->firsteager != NULL )
877 assert(chkmem->firsteager->preveager == NULL);
879 lazy = chkmem->lazyfree;
880 while( lazy != NULL )
883 assert(chunk != NULL);
884 assert(chunk->chkmem == chkmem);
888 assert(chkmem->lazyfreesize == lazyfreesize);
891 #define checkChunk(chunk)
892 #define checkChkmem(chkmem)
911 assert(chkmem != NULL);
912 assert(chkmem->nchunks <= chkmem->chunkssize);
913 assert(chunk != NULL);
914 assert(chunk->store != NULL);
916 debugMessage( "linking chunk %p to chunk block %p [elemsize:%d, %d chunks]\n",
917 ( void*)chunk, ( void*)chkmem, chkmem->elemsize, chkmem->nchunks);
921 right = chkmem->nchunks;
922 while( left < right-1 )
924 middle = (left+right)/2;
925 assert(0 <= middle && middle < chkmem->nchunks);
926 assert(left < middle && middle < right);
927 curchunk = chkmem->chunks[middle];
928 assert(curchunk != NULL);
929 if( chunk->store < curchunk->store )
933 assert(chunk->store >= curchunk->storeend);
937 assert(-1 <= left && left < chkmem->nchunks);
938 assert(0 <= right && right <= chkmem->nchunks);
939 assert(left+1 == right);
940 assert(left == -1 || chkmem->chunks[left]->storeend <= chunk->store);
941 assert(right == chkmem->nchunks || chunk->storeend <= chkmem->chunks[right]->store);
944 if( chkmem->nchunks == chkmem->chunkssize )
946 chkmem->chunkssize = 2*(chkmem->nchunks+1);
948 if( chkmem->chunks == NULL )
951 assert(chkmem->nchunks < chkmem->chunkssize);
952 assert(chkmem->chunks != NULL);
955 for( i = chkmem->nchunks; i > right; --i )
957 chkmem->chunks[i] = chkmem->chunks[i-1];
958 chkmem->chunks[i]->arraypos = i;
962 chunk->arraypos = right;
963 chkmem->chunks[right] = chunk;
965 chkmem->storesize += chunk->storesize;
979 assert(chunk != NULL);
980 assert(chunk->eagerfree == NULL);
981 assert(chunk->nexteager == NULL);
982 assert(chunk->preveager == NULL);
984 chkmem = chunk->chkmem;
985 assert(chkmem != NULL);
986 assert(chkmem->elemsize == chunk->elemsize);
987 assert(0 <= chunk->arraypos && chunk->arraypos < chkmem->nchunks);
988 assert(chkmem->chunks[chunk->arraypos] == chunk);
990 debugMessage( "unlinking chunk %p from chunk block %p [elemsize:%d, %d chunks]\n",
991 ( void*)chunk, ( void*)chkmem, chkmem->elemsize, chkmem->nchunks);
994 for( i = chunk->arraypos; i < chkmem->nchunks-1; ++i )
996 chkmem->chunks[i] = chkmem->chunks[i+1];
997 chkmem->chunks[i]->arraypos = i;
1000 chkmem->storesize -= chunk->storesize;
1010 assert(chunk->chkmem == chkmem);
1011 assert(chunk->nexteager == NULL);
1012 assert(chunk->preveager == NULL);
1014 chunk->nexteager = chkmem->firsteager;
1015 chunk->preveager = NULL;
1016 if( chkmem->firsteager != NULL )
1018 assert(chkmem->firsteager->preveager == NULL);
1019 chkmem->firsteager->preveager = chunk;
1021 chkmem->firsteager = chunk;
1030 assert(chunk != NULL);
1031 assert(chunk->eagerfreesize == 0 || chunk->eagerfreesize == chunk->storesize);
1033 if( chunk->nexteager != NULL )
1034 chunk->nexteager->preveager = chunk->preveager;
1035 if( chunk->preveager != NULL )
1036 chunk->preveager->nexteager = chunk->nexteager;
1039 assert(chunk->chkmem->firsteager == chunk);
1040 chunk->chkmem->firsteager = chunk->nexteager;
1042 chunk->nexteager = NULL;
1043 chunk->preveager = NULL;
1044 chunk->eagerfree = NULL;
1061 assert(chkmem != NULL);
1063 debugMessage( "creating new chunk in chunk block %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize);
1066 if( chkmem->nchunks == 0 )
1067 storesize = chkmem->initchunksize;
1069 storesize = 2 * chkmem->lastchunksize;
1070 assert(storesize > 0);
1074 storesize = MAX(storesize, 1);
1075 chkmem->lastchunksize = storesize;
1079 assert( chkmem->elemsize < INT_MAX / storesize );
1080 assert( sizeof( CHUNK) < MAXMEMSIZE - ( size_t)(storesize * chkmem->elemsize) );
1082 if( newchunk == NULL )
1086 newchunk->store = ( void*) (( char*) newchunk + sizeof( CHUNK));
1087 newchunk->storeend = ( void*) (( char*) newchunk->store + storesize * chkmem->elemsize);
1088 newchunk->eagerfree = NULL;
1089 newchunk->nexteager = NULL;
1090 newchunk->preveager = NULL;
1091 newchunk->chkmem = chkmem;
1092 newchunk->elemsize = chkmem->elemsize;
1093 newchunk->storesize = storesize;
1094 newchunk->eagerfreesize = 0;
1095 newchunk->arraypos = -1;
1097 debugMessage( "allocated new chunk %p: %d elements with size %d\n", ( void*)newchunk, newchunk->storesize, newchunk->elemsize);
1100 for( i = 0; i < newchunk->storesize - 1; ++i )
1102 freelist = ( FREELIST*) (( char*) (newchunk->store) + i * chkmem->elemsize);
1103 freelist->next = ( FREELIST*) (( char*) (newchunk->store) + (i + 1) * chkmem->elemsize);
1106 freelist = ( FREELIST*) (( char*) (newchunk->store) + (newchunk->storesize - 1) * chkmem->elemsize);
1107 freelist->next = chkmem->lazyfree;
1108 chkmem->lazyfree = ( FREELIST*) (newchunk->store);
1109 chkmem->lazyfreesize += newchunk->storesize;
1125 assert(chunk != NULL);
1139 assert(chunk != NULL);
1140 assert(chunk->store != NULL);
1141 assert(chunk->eagerfree != NULL);
1142 assert(chunk->chkmem != NULL);
1143 assert(chunk->chkmem->chunks != NULL);
1144 assert(chunk->chkmem->firsteager != NULL);
1145 assert(chunk->eagerfreesize == chunk->storesize);
1147 debugMessage( "freeing chunk %p of chunk block %p [elemsize: %d]\n", ( void*)chunk, ( void*)chunk->chkmem, chunk->chkmem->elemsize);
1150 chunk->chkmem->eagerfreesize -= chunk->eagerfreesize;
1151 assert(chunk->chkmem->eagerfreesize >= 0);
1171 assert(chunk != NULL);
1172 assert(chunk->eagerfree != NULL);
1173 assert(chunk->eagerfreesize > 0);
1174 assert(chunk->chkmem != NULL);
1176 debugMessage( "allocating chunk element in chunk %p [elemsize: %d]\n", ( void*)chunk, chunk->chkmem->elemsize);
1179 ptr = chunk->eagerfree;
1180 chunk->eagerfree = ptr->next;
1181 chunk->eagerfreesize--;
1182 chunk->chkmem->eagerfreesize--;
1184 assert((chunk->eagerfreesize == 0 && chunk->eagerfree == NULL)
1185 || (chunk->eagerfreesize != 0 && chunk->eagerfree != NULL));
1186 assert(chunk->chkmem->eagerfreesize >= 0);
1189 if( chunk->eagerfree == NULL )
1191 assert(chunk->eagerfreesize == 0);
1207 assert(chunk != NULL);
1208 assert(chunk->chkmem != NULL);
1211 debugMessage( "freeing chunk element %p of chunk %p [elemsize: %d]\n", ( void*)ptr, ( void*)chunk, chunk->chkmem->elemsize);
1214 if( chunk->eagerfree == NULL )
1216 assert(chunk->eagerfreesize == 0);
1221 (( FREELIST*)ptr)->next = chunk->eagerfree;
1223 chunk->eagerfreesize++;
1224 chunk->chkmem->eagerfreesize++;
1244 if( chkmem == NULL )
1247 chkmem->lazyfree = NULL;
1248 chkmem->chunks = NULL;
1249 chkmem->firsteager = NULL;
1250 chkmem->nextchkmem = NULL;
1251 chkmem->elemsize = size;
1252 chkmem->chunkssize = 0;
1253 chkmem->nchunks = 0;
1254 chkmem->lastchunksize = 0;
1255 chkmem->storesize = 0;
1256 chkmem->lazyfreesize = 0;
1257 chkmem->eagerfreesize = 0;
1258 chkmem->initchunksize = initchunksize;
1259 chkmem->garbagefactor = garbagefactor;
1261 chkmem->filename = NULL;
1263 chkmem->ngarbagecalls = 0;
1264 chkmem->ngarbagefrees = 0;
1278 assert(chkmem != NULL);
1281 for( i = 0; i < chkmem->nchunks; ++i )
1284 chkmem->lazyfree = NULL;
1285 chkmem->firsteager = NULL;
1286 chkmem->nchunks = 0;
1287 chkmem->lastchunksize = 0;
1288 chkmem->storesize = 0;
1289 chkmem->lazyfreesize = 0;
1290 chkmem->eagerfreesize = 0;
1299 assert(chkmem != NULL);
1300 assert(*chkmem != NULL);
1320 assert(chkmem != NULL);
1323 if( chkmem->lazyfree == NULL )
1325 assert(chkmem->lazyfreesize == 0);
1328 if( chkmem->firsteager != NULL )
1337 assert(chkmem->lazyfree != NULL);
1338 assert(chkmem->lazyfreesize > 0);
1340 ptr = chkmem->lazyfree;
1341 chkmem->lazyfree = ptr->next;
1342 chkmem->lazyfreesize--;
1361 assert(chkmem != NULL);
1363 debugMessage( "garbage collection for chunk block %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize);
1366 if( chkmem->lazyfreesize + chkmem->eagerfreesize == chkmem->storesize )
1373 chkmem->ngarbagecalls++;
1377 while( chkmem->lazyfree != NULL )
1380 lazyfree = chkmem->lazyfree;
1381 chkmem->lazyfree = chkmem->lazyfree->next;
1382 chkmem->lazyfreesize--;
1385 chunk = findChunk(chkmem, ( void*)lazyfree);
1389 errorMessage( "chunk for lazy free chunk %p not found in chunk block %p\n", ( void*)lazyfree, ( void*)chkmem);
1392 assert(chunk != NULL);
1396 assert(chunk->eagerfreesize > 0);
1398 assert(chkmem->lazyfreesize == 0);
1401 chunk = chkmem->firsteager;
1402 while( chunk != NULL && chkmem->nchunks > 1 )
1404 nexteager = chunk->nexteager;
1405 if( chunk->eagerfreesize == chunk->storesize )
1408 chkmem->ngarbagefrees++;
1423 const char* filename,
1427 assert(chkmem != NULL);
1428 assert(ptr != NULL);
1437 printError( "Pointer %p does not belong to chunk block %p (size: %d).\n", ptr, chkmem, chkmem->elemsize);
1442 (( FREELIST*)ptr)->next = chkmem->lazyfree;
1444 chkmem->lazyfreesize++;
1447 if( chkmem->garbagefactor >= 0 && chkmem->nchunks > 0 && chkmem->lazyfreesize >= GARBAGE_SIZE
1448 && chkmem->lazyfreesize + chkmem->eagerfreesize
1449 > chkmem->garbagefactor * ( double)(chkmem->storesize) / ( double)(chkmem->nchunks) )
1463 const char* filename,
1470 chkmem = createChkmem(( int) size, initchunksize, garbagefactor);
1471 if( chkmem == NULL )
1474 printError( "Insufficient memory for chunk block.\n");
1476 debugMessage( "created chunk memory %p [elemsize: %d]\n", ( void*)chkmem, ( int)size);
1484 const char* filename,
1488 debugMessage( "clearing chunk memory %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize);
1490 if( chkmem != NULL )
1495 printError( "Tried to clear null chunk block.\n");
1502 const char* filename,
1506 assert(chkmem != NULL);
1508 debugMessage( "destroying chunk memory %p [elemsize: %d]\n", ( void*)*chkmem, (*chkmem)->elemsize);
1510 if( *chkmem != NULL )
1515 printError( "Tried to destroy null chunk block.\n");
1523 const char* filename,
1529 assert(chkmem != NULL);
1530 assert(( int)size == chkmem->elemsize);
1537 printError( "Insufficient memory for new chunk.\n");
1539 debugMessage( "alloced %8llu bytes in %p [%s:%d]\n", ( unsigned long long)size, ( void*)ptr, filename, line);
1551 const char* filename,
1557 assert(chkmem != NULL);
1558 assert(source != NULL);
1559 assert(( int)size == chkmem->elemsize);
1573 const char* filename,
1577 assert(chkmem != NULL);
1578 assert(( int)size == chkmem->elemsize);
1579 assert( ptr != NULL );
1583 debugMessage( "free %8d bytes in %p [%s:%d]\n", chkmem->elemsize, *ptr, filename, line);
1593 printError( "Tried to free null chunk pointer.\n");
1602 const char* filename,
1606 assert(chkmem != NULL);
1607 assert(( int)size == chkmem->elemsize);
1608 assert( ptr != NULL );
1612 debugMessage( "free %8d bytes in %p [%s:%d]\n", chkmem->elemsize, *ptr, filename, line);
1626 debugMessage( "garbage collection on chunk memory %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize);
1636 long long chkmemused;
1639 assert(chkmem != NULL);
1642 for( i = 0; i < chkmem->nchunks; ++i )
1643 chkmemused += ( long long)(chkmem->chunks[i]->elemsize) * ( long long)(chkmem->chunks[i]->storesize);
1657 #define CHKHASH_SIZE 1013
1684 assert(blkmem != NULL);
1685 assert(blkmem->chkmemhash != NULL);
1689 chkmem = blkmem->chkmemhash[i];
1690 while( chkmem != NULL )
1693 chkmem = chkmem->nextchkmem;
1698 #define checkBlkmem(blkmem)
1716 assert(blkmem != NULL);
1721 chkmem = blkmem->chkmemhash[i];
1723 chkmem = chkmem->nextchkmem;
1738 return (size % CHKHASH_SIZE);
1746 const char* filename,
1754 if( blkmem != NULL )
1757 blkmem->chkmemhash[i] = NULL;
1758 blkmem->initchunksize = initchunksize;
1759 blkmem->garbagefactor = garbagefactor;
1760 blkmem->memused = 0;
1765 printError( "Insufficient memory for block memory header.\n");
1774 const char* filename,
1782 if( blkmem != NULL )
1786 chkmem = blkmem->chkmemhash[i];
1787 while( chkmem != NULL )
1789 nextchkmem = chkmem->nextchkmem;
1791 chkmem = nextchkmem;
1793 blkmem->chkmemhash[i] = NULL;
1795 blkmem->memused = 0;
1800 printError( "Tried to clear null block memory.\n");
1807 const char* filename,
1811 assert(blkmem != NULL);
1813 if( *blkmem != NULL )
1817 assert(*blkmem == NULL);
1822 printError( "Tried to destroy null block memory.\n");
1831 const char* filename,
1839 assert( blkmem != NULL );
1846 chkmemptr = &(blkmem->chkmemhash[hashnumber]);
1847 while( *chkmemptr != NULL && (*chkmemptr)->elemsize != ( int)size )
1848 chkmemptr = &((*chkmemptr)->nextchkmem);
1851 if( *chkmemptr == NULL )
1853 *chkmemptr = createChkmem(( int)size, blkmem->initchunksize, blkmem->garbagefactor);
1854 if( *chkmemptr == NULL )
1857 printError( "Insufficient memory for chunk block.\n");
1862 (*chkmemptr)->line = line;
1871 printError( "Insufficient memory for new chunk.\n");
1873 debugMessage( "alloced %8llu bytes in %p [%s:%d]\n", ( unsigned long long)size, ptr, filename, line);
1875 blkmem->memused += ( long long) size;
1886 const char* filename,
1907 const char* filename,
1928 const char* filename,
1947 const char* filename,
1955 assert(oldsize == 0);
1970 if( oldsize == newsize )
1974 if( newptr != NULL )
1988 const char* filename,
1996 assert(oldnum == 0);
2009 if ( oldnum == newnum )
2013 if ( newptr != NULL )
2025 const char* filename,
2031 assert(source != NULL);
2046 const char* filename,
2052 assert(source != NULL);
2067 const char* filename,
2074 assert(ptr != NULL);
2075 assert(*ptr != NULL);
2081 debugMessage( "free %8llu bytes in %p [%s:%d]\n", ( unsigned long long)size, *ptr, filename, line);
2084 assert( blkmem->chkmemhash != NULL );
2085 chkmem = blkmem->chkmemhash[hashnumber];
2086 while( chkmem != NULL && chkmem->elemsize != ( int)size )
2087 chkmem = chkmem->nextchkmem;
2088 if( chkmem == NULL )
2091 printError( "Tried to free pointer <%p> in block memory <%p> of unknown size %llu.\n", *ptr, ( void*)blkmem, ( unsigned long long)size);
2094 assert(chkmem->elemsize == ( int)size);
2099 blkmem->memused -= ( long long) size;
2100 assert(blkmem->memused >= 0);
2110 const char* filename,
2114 assert( blkmem != NULL );
2115 assert( ptr != NULL );
2119 else if( size != 0 )
2122 printError( "Tried to free null block pointer.\n");
2132 const char* filename,
2136 assert( blkmem != NULL );
2137 assert( ptr != NULL );
2155 assert(blkmem != NULL);
2161 chkmemptr = &blkmem->chkmemhash[i];
2162 while( *chkmemptr != NULL )
2165 if( (*chkmemptr)->nchunks == 0 )
2169 nextchkmem = (*chkmemptr)->nextchkmem;
2171 *chkmemptr = nextchkmem;
2174 chkmemptr = &(*chkmemptr)->nextchkmem;
2184 assert( blkmem != NULL );
2186 return blkmem->memused;
2197 assert(blkmem != NULL);
2203 if( chkmem == NULL )
2206 return ( size_t)(chkmem->elemsize);
2216 int nunusedblocks = 0;
2217 int totalnchunks = 0;
2218 int totalneagerchunks = 0;
2219 int totalnelems = 0;
2220 int totalneagerelems = 0;
2221 int totalnlazyelems = 0;
2223 int totalngarbagecalls = 0;
2224 int totalngarbagefrees = 0;
2226 long long allocedmem = 0;
2227 long long freemem = 0;
2232 printInfo( " ElSize #Chunk #Eag #Elems #EagFr #LazFr #GCl #GFr Free MBytes First Allocator\n");
2234 printInfo( " ElSize #Chunk #Eag #Elems #EagFr #LazFr Free MBytes\n");
2237 assert(blkmem != NULL);
2241 chkmem = blkmem->chkmemhash[i];
2242 while( chkmem != NULL )
2247 int neagerchunks = 0;
2248 int neagerelems = 0;
2250 for( c = 0; c < chkmem->nchunks; ++c )
2252 chunk = chkmem->chunks[c];
2253 assert(chunk != NULL);
2254 assert(chunk->elemsize == chkmem->elemsize);
2255 assert(chunk->chkmem == chkmem);
2257 nelems += chunk->storesize;
2258 if( chunk->eagerfree != NULL )
2261 neagerelems += chunk->eagerfreesize;
2265 assert(nchunks == chkmem->nchunks);
2266 assert(nelems == chkmem->storesize);
2267 assert(neagerelems == chkmem->eagerfreesize);
2272 allocedmem += ( long long)chkmem->elemsize * ( long long)nelems;
2273 freemem += ( long long)chkmem->elemsize * (( long long)neagerelems + ( long long)chkmem->lazyfreesize);
2276 printInfo( "%7d %6d %4d %7d %7d %7d %5d %4d %5.1f%% %6.1f %s:%d\n",
2277 chkmem->elemsize, nchunks, neagerchunks, nelems,
2278 neagerelems, chkmem->lazyfreesize, chkmem->ngarbagecalls, chkmem->ngarbagefrees,
2279 100.0 * ( double) (neagerelems + chkmem->lazyfreesize) / ( double) (nelems),
2280 ( double)chkmem->elemsize * nelems / (1024.0*1024.0),
2281 chkmem->filename, chkmem->line);
2283 printInfo( "%7d %6d %4d %7d %7d %7d %5.1f%% %6.1f\n",
2284 chkmem->elemsize, nchunks, neagerchunks, nelems,
2285 neagerelems, chkmem->lazyfreesize,
2286 100.0 * ( double) (neagerelems + chkmem->lazyfreesize) / ( double) (nelems),
2287 ( double)chkmem->elemsize * nelems / (1024.0*1024.0));
2293 printInfo( "%7d <unused> %5d %4d %s:%d\n",
2294 chkmem->elemsize, chkmem->ngarbagecalls, chkmem->ngarbagefrees,
2295 chkmem->filename, chkmem->line);
2297 printInfo( "%7d <unused>\n", chkmem->elemsize);
2301 totalnchunks += nchunks;
2302 totalneagerchunks += neagerchunks;
2303 totalnelems += nelems;
2304 totalneagerelems += neagerelems;
2305 totalnlazyelems += chkmem->lazyfreesize;
2307 totalngarbagecalls += chkmem->ngarbagecalls;
2308 totalngarbagefrees += chkmem->ngarbagefrees;
2310 chkmem = chkmem->nextchkmem;
2314 printInfo( " Total %6d %4d %7d %7d %7d %5d %4d %5.1f%% %6.1f\n",
2315 totalnchunks, totalneagerchunks, totalnelems, totalneagerelems, totalnlazyelems,
2316 totalngarbagecalls, totalngarbagefrees,
2317 totalnelems > 0 ? 100.0 * ( double) (totalneagerelems + totalnlazyelems) / ( double) (totalnelems) : 0.0,
2318 ( double)allocedmem/(1024.0*1024.0));
2320 printInfo( " Total %6d %4d %7d %7d %7d %5.1f%% %6.1f\n",
2321 totalnchunks, totalneagerchunks, totalnelems, totalneagerelems, totalnlazyelems,
2322 totalnelems > 0 ? 100.0 * ( double) (totalneagerelems + totalnlazyelems) / ( double) (totalnelems) : 0.0,
2323 ( double)allocedmem/(1024.0*1024.0));
2326 nblocks + nunusedblocks, nunusedblocks, allocedmem, freemem);
2327 if( allocedmem > 0 )
2328 printInfo( " (%.1f%%)", 100.0 * ( double) freemem / ( double) allocedmem);
2338 long long allocedmem = 0;
2339 long long freemem = 0;
2343 assert(blkmem != NULL);
2347 chkmem = blkmem->chkmemhash[i];
2348 while( chkmem != NULL )
2353 int neagerelems = 0;
2355 for( c = 0; c < chkmem->nchunks; ++c )
2357 chunk = chkmem->chunks[c];
2358 assert(chunk != NULL);
2359 assert(chunk->elemsize == chkmem->elemsize);
2360 assert(chunk->chkmem == chkmem);
2362 nelems += chunk->storesize;
2363 if( chunk->eagerfree != NULL )
2364 neagerelems += chunk->eagerfreesize;
2367 assert(nchunks == chkmem->nchunks);
2368 assert(nelems == chkmem->storesize);
2369 assert(neagerelems == chkmem->eagerfreesize);
2373 allocedmem += ( long long)chkmem->elemsize * ( long long)nelems;
2374 freemem += ( long long)chkmem->elemsize * (( long long)neagerelems + ( long long)chkmem->lazyfreesize);
2376 if( nelems != neagerelems + chkmem->lazyfreesize )
2380 ((( long long)nelems - ( long long)neagerelems) - ( long long)chkmem->lazyfreesize)
2381 * ( long long)(chkmem->elemsize),
2382 (nelems - neagerelems) - chkmem->lazyfreesize, ( long long)(chkmem->elemsize),
2383 chkmem->filename, chkmem->line);
2385 printInfo( "%" LONGINT_FORMAT " bytes (%d elements of size %" LONGINT_FORMAT ") not freed.\n",
2386 ((nelems - neagerelems) - chkmem->lazyfreesize) * ( long long)(chkmem->elemsize),
2387 (nelems - neagerelems) - chkmem->lazyfreesize, ( long long)(chkmem->elemsize));
2391 chkmem = chkmem->nextchkmem;
2395 if( allocedmem != freemem )
2427 double arraygrowfac,
2430 const char* filename,
2436 assert( arraygrowinit > 0 );
2437 assert( arraygrowfac > 0.0 );
2440 if ( buffer != NULL )
2446 buffer-> clean = clean;
2455 printError( "Insufficient memory for buffer memory header.\n");
2464 const char* filename,
2470 if ( *buffer != NULL )
2472 for (i = 0; i < (*buffer)->ndata; ++i)
2474 assert( ! (*buffer)->used[i] );
2485 printError( "Tried to free null buffer memory.\n");
2495 assert( buffer != NULL );
2496 assert( arraygrowfac > 0.0 );
2507 assert( buffer != NULL );
2508 assert( arraygrowinit > 0 );
2513 #ifndef SCIP_NOBUFFERMEM
2527 assert( growfac >= 1.0 );
2529 if ( growfac == 1.0 )
2530 size = MAX(initsize, num);
2536 initsize = MAX(initsize, 4);
2541 while ( size < num && size > oldsize )
2544 size = (size_t)(growfac * size + initsize);
2548 if ( size <= oldsize )
2552 assert( size >= initsize );
2553 assert( size >= num );
2564 const char* filename,
2569 #ifndef SCIP_NOBUFFERMEM
2573 #ifndef SCIP_NOBUFFERMEM
2574 assert( buffer != NULL );
2593 printError( "Insufficient memory for reallocating buffer data storage.\n");
2600 printError( "Insufficient memory for reallocating buffer size storage.\n");
2607 printError( "Insufficient memory for reallocating buffer used storage.\n");
2612 for (i = buffer-> ndata; i < newsize; ++i)
2615 buffer-> size[i] = 0;
2618 buffer-> ndata = newsize;
2624 assert( ! buffer-> used[bufnum] );
2625 if ( buffer-> size[bufnum] < size )
2636 char* tmpptr = ( char*)(buffer-> data[bufnum]);
2637 size_t inc = buffer-> size[bufnum] / sizeof(*tmpptr);
2642 assert( newsize > buffer-> size[bufnum] );
2644 buffer-> size[bufnum] = newsize;
2646 if ( buffer-> data[bufnum] == NULL )
2649 printError( "Insufficient memory for reallocating buffer storage.\n");
2653 assert( buffer-> size[bufnum] >= size );
2659 char* tmpptr = ( char*)(buffer-> data[bufnum]);
2660 unsigned int inc = buffer-> size[bufnum] / sizeof(*tmpptr);
2663 while( --tmpptr >= ( char*)(buffer-> data[bufnum]) )
2664 assert(*tmpptr == '\0');
2668 ptr = buffer-> data[bufnum];
2672 debugMessage( "Allocated buffer %llu/%llu at %p of size %llu (required size: %llu) for pointer %p.\n",
2673 ( unsigned long long)bufnum, ( unsigned long long)(buffer-> ndata), buffer-> data[bufnum],
2674 ( unsigned long long)(buffer-> size[bufnum]), ( unsigned long long)size, ptr);
2694 const char* filename,
2715 const char* filename,
2736 const char* filename,
2755 const char* filename,
2760 #ifndef SCIP_NOBUFFERMEM
2764 #ifndef SCIP_NOBUFFERMEM
2765 assert( buffer != NULL );
2767 assert(!buffer-> clean);
2780 while ( bufnum > 0 && buffer-> data[bufnum] != ptr )
2784 assert( buffer-> data[bufnum] == newptr );
2785 assert( buffer-> used[bufnum] );
2786 assert( buffer-> size[bufnum] >= 1 );
2789 if ( size > buffer-> size[bufnum] )
2796 assert( newsize > buffer-> size[bufnum] );
2798 buffer-> size[bufnum] = newsize;
2799 if ( buffer-> data[bufnum] == NULL )
2802 printError( "Insufficient memory for reallocating buffer storage.\n");
2805 newptr = buffer-> data[bufnum];
2807 assert( buffer-> size[bufnum] >= size );
2808 assert( newptr == buffer-> data[bufnum] );
2810 debugMessage( "Reallocated buffer %llu/%llu at %p to size %llu (required size: %llu) for pointer %p.\n",
2811 ( unsigned long long)bufnum, ( unsigned long long)(buffer-> ndata), buffer-> data[bufnum],
2812 ( unsigned long long)(buffer-> size[bufnum]), ( unsigned long long)size, newptr);
2827 const char* filename,
2849 const char* filename,
2870 const char* filename,
2876 assert( source != NULL );
2894 const char* filename,
2900 assert( source != NULL );
2917 const char* filename,
2923 assert( buffer != NULL );
2926 assert( ptr != NULL );
2927 assert( *ptr != NULL );
2934 while ( bufnum > 0 && buffer-> data[bufnum] != *ptr )
2938 if ( bufnum == 0 && buffer-> data[bufnum] != *ptr )
2941 printError( "Tried to free unkown buffer pointer.\n");
2944 if ( ! buffer-> used[bufnum] )
2947 printError( "Tried to free buffer pointer already freed.\n");
2956 char* tmpptr = ( char*)(buffer-> data[bufnum]);
2957 unsigned int inc = buffer-> size[bufnum] / sizeof(*tmpptr);
2960 while( --tmpptr >= ( char*)(buffer-> data[bufnum]) )
2961 assert(*tmpptr == '\0');
2965 assert( buffer-> data[bufnum] == *ptr );
2971 debugMessage( "Freed buffer %llu/%llu at %p of size %llu for pointer %p, first free is %llu.\n",
2972 ( unsigned long long)bufnum, ( unsigned long long)(buffer-> ndata), buffer-> data[bufnum],
2973 ( unsigned long long)(buffer-> size[bufnum]), *ptr, ( unsigned long long)(buffer-> firstfree));
2982 const char* filename,
2986 assert( ptr != NULL );
2988 #ifndef SCIP_NOBUFFERMEM
2994 printError( "Tried to free null buffer pointer.\n");
3005 const char* filename,
3009 assert( ptr != NULL );
3013 #ifndef SCIP_NOBUFFERMEM
3026 assert( buffer != NULL );
3037 size_t totalmem = 0UL;
3040 assert( buffer != NULL );
3041 for (i = 0; i < buffer-> ndata; ++i)
3042 totalmem += buffer-> size[i];
3043 assert( totalmem == buffer-> totalmem );
3046 return ( long long) buffer-> totalmem;
3057 assert( buffer != NULL );
3060 for (i = 0; i < buffer-> ndata; ++i)
3062 printf( "[%c] %8llu bytes at %p\n", buffer-> used[i] ? '*' : ' ', ( unsigned long long)(buffer-> size[i]), buffer-> data[i]);
3063 totalmem += buffer-> size[i];
3065 printf( " %8llu bytes total in %llu buffers\n", ( unsigned long long)totalmem, ( unsigned long long)(buffer-> ndata));
void BMSdestroyBlockMemory_call(BMS_BLKMEM **blkmem, const char *filename, int line)
long long BMSgetMemoryUsed_call(void)
void * BMSallocChunkMemory_call(BMS_CHKMEM *chkmem, size_t size, const char *filename, int line)
#define BMScopyMemorySize(ptr, source, size)
struct BMS_ChkMem BMS_CHKMEM
int BMSisAligned(size_t size)
static INLINE void BMSfreeBlockMemory_work(BMS_BLKMEM *blkmem, void **ptr, size_t size, const char *filename, int line)
#define BMSfreeMemoryArrayNull(ptr)
void * BMSduplicateMemoryArray_call(const void *source, size_t num, size_t typesize, const char *filename, int line)
void BMSdisplayBlockMemory_call(const BMS_BLKMEM *blkmem)
void * BMSallocBlockMemoryArray_call(BMS_BLKMEM *blkmem, size_t num, size_t typesize, const char *filename, int line)
static void garbagecollectChkmem(BMS_CHKMEM *chkmem)
#define checkChunk(chunk)
void BMSfreeBufferMemoryNull_call(BMS_BUFMEM *buffer, void **ptr, const char *filename, int line)
void * BMSduplicateBufferMemoryArray_call(BMS_BUFMEM *buffer, const void *source, size_t num, size_t typesize, const char *filename, int line)
#define checkBlkmem(blkmem)
void * BMSallocBufferMemoryArray_call(BMS_BUFMEM *buffer, size_t num, size_t typesize, const char *filename, int line)
void * BMSduplicateChunkMemory_call(BMS_CHKMEM *chkmem, const void *source, size_t size, const char *filename, int line)
void * BMSallocClearBlockMemoryArray_call(BMS_BLKMEM *blkmem, size_t num, size_t typesize, const char *filename, int line)
void BMSdestroyChunkMemory_call(BMS_CHKMEM **chkmem, const char *filename, int line)
void * BMSallocBlockMemory_call(BMS_BLKMEM *blkmem, size_t size, const char *filename, int line)
size_t BMSgetBlockPointerSize_call(const BMS_BLKMEM *blkmem, const void *ptr)
static void * allocChkmemElement(BMS_CHKMEM *chkmem)
void BMSfreeChunkMemory_call(BMS_CHKMEM *chkmem, void **ptr, size_t size, const char *filename, int line)
static void * allocChunkElement(CHUNK *chunk)
static void unlinkEagerChunk(CHUNK *chunk)
void * BMSreallocBlockMemoryArray_call(BMS_BLKMEM *blkmem, void *ptr, size_t oldnum, size_t newnum, size_t typesize, const char *filename, int line)
void * BMSreallocBlockMemory_call(BMS_BLKMEM *blkmem, void *ptr, size_t oldsize, size_t newsize, const char *filename, int line)
#define printErrorHeader(f, l)
#define BMSfreeMemory(ptr)
static BMS_CHKMEM * findChkmem(const BMS_BLKMEM *blkmem, const void *ptr)
static int linkChunk(BMS_CHKMEM *chkmem, CHUNK *chunk)
void * BMSallocClearBufferMemoryArray_call(BMS_BUFMEM *buffer, size_t num, size_t typesize, const char *filename, int line)
long long BMSgetBufferMemoryUsed(const BMS_BUFMEM *buffer)
void BMSsetBufferMemoryArraygrowinit(BMS_BUFMEM *buffer, int arraygrowinit)
void * BMSreallocMemoryArray_call(void *ptr, size_t num, size_t typesize, const char *filename, int line)
static INLINE void * BMSallocBufferMemory_work(BMS_BUFMEM *buffer, size_t size, const char *filename, int line)
static INLINE void BMSfreeBufferMemory_work(BMS_BUFMEM *buffer, void **ptr, const char *filename, int line)
void * BMSallocBufferMemory_call(BMS_BUFMEM *buffer, size_t size, const char *filename, int line)
static void unlinkChunk(CHUNK *chunk)
static INLINE void * BMSallocBlockMemory_work(BMS_BLKMEM *blkmem, size_t size, const char *filename, int line)
void BMSgarbagecollectBlockMemory_call(BMS_BLKMEM *blkmem)
void * BMSduplicateMemory_call(const void *source, size_t size, const char *filename, int line)
long long BMSgetBlockMemoryUsed_call(const BMS_BLKMEM *blkmem)
void * BMSallocMemoryArray_call(size_t num, size_t typesize, const char *filename, int line)
void BMScheckEmptyBlockMemory_call(const BMS_BLKMEM *blkmem)
static int isPtrInChunk(const CHUNK *chunk, const void *ptr)
void BMSdestroyBufferMemory_call(BMS_BUFMEM **buffer, const char *filename, int line)
static void alignSize(size_t *size)
void * BMSduplicateBlockMemoryArray_call(BMS_BLKMEM *blkmem, const void *source, size_t num, size_t typesize, const char *filename, int line)
#define BMSduplicateMemoryArray(ptr, source, num)
static int isPtrInChkmem(const BMS_CHKMEM *chkmem, const void *ptr)
static void freeChkmemElement(BMS_CHKMEM *chkmem, void *ptr, const char *filename, int line)
void BMSgarbagecollectChunkMemory_call(BMS_CHKMEM *chkmem)
#define checkChkmem(chkmem)
void BMSsetBufferMemoryArraygrowfac(BMS_BUFMEM *buffer, double arraygrowfac)
void BMSclearMemory_call(void *ptr, size_t size)
long long BMSgetChunkMemoryUsed_call(const BMS_CHKMEM *chkmem)
static void freeChunkElement(CHUNK *chunk, void *ptr)
static void destroyChunk(CHUNK *chunk)
void BMSdisplayMemory_call(void)
void BMSfreeMemory_call(void **ptr, const char *filename, int line)
static int getHashNumber(int size)
void BMScopyMemory_call(void *ptr, const void *source, size_t size)
unsigned int arraygrowinit
BMS_BUFMEM * BMScreateBufferMemory_call(double arraygrowfac, int arraygrowinit, unsigned int clean, const char *filename, int line)
void BMSfreeBufferMemory_call(BMS_BUFMEM *buffer, void **ptr, const char *filename, int line)
void BMSfreeBlockMemory_call(BMS_BLKMEM *blkmem, void **ptr, size_t size, const char *filename, int line)
BMS_BLKMEM * BMScreateBlockMemory_call(int initchunksize, int garbagefactor, const char *filename, int line)
static int createChunk(BMS_CHKMEM *chkmem)
static void linkEagerChunk(BMS_CHKMEM *chkmem, CHUNK *chunk)
void BMSmoveMemory_call(void *ptr, const void *source, size_t size)
static void freeChunk(CHUNK *chunk)
void * BMSreallocBufferMemoryArray_call(BMS_BUFMEM *buffer, void *ptr, size_t num, size_t typesize, const char *filename, int line)
#define BMSclearMemorySize(ptr, size)
void BMSprintBufferMemory(BMS_BUFMEM *buffer)
void * BMSduplicateBlockMemory_call(BMS_BLKMEM *blkmem, const void *source, size_t size, const char *filename, int line)
void * BMSallocClearMemory_call(size_t num, size_t typesize, const char *filename, int line)
void BMScheckEmptyMemory_call(void)
void BMSclearChunkMemory_call(BMS_CHKMEM *chkmem, const char *filename, int line)
static void clearChkmem(BMS_CHKMEM *chkmem)
size_t BMSgetNUsedBufferMemory(BMS_BUFMEM *buffer)
size_t BMSgetPointerSize_call(const void *ptr)
void * BMSreallocMemory_call(void *ptr, size_t size, const char *filename, int line)
void * BMSduplicateBufferMemory_call(BMS_BUFMEM *buffer, const void *source, size_t size, const char *filename, int line)
#define BMSallocMemorySize(ptr, size)
public methods for message output
#define BMSreallocMemorySize(ptr, size)
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 BMSallocClearMemorySize(ptr, size)
#define BMSallocMemory(ptr)
#define BMSreallocMemoryArray(ptr, num)
static CHUNK * findChunk(const BMS_CHKMEM *chkmem, const void *ptr)
static INLINE void * BMSreallocBufferMemory_work(BMS_BUFMEM *buffer, void *ptr, size_t size, const char *filename, int line)
BMS_CHKMEM * BMScreateChunkMemory_call(size_t size, int initchunksize, int garbagefactor, const char *filename, int line)
void BMSfreeMemoryNull_call(void **ptr, const char *filename, int line)
void BMSfreeChunkMemoryNull_call(BMS_CHKMEM *chkmem, void **ptr, size_t size, const char *filename, int line)
static size_t calcMemoryGrowSize(size_t initsize, SCIP_Real growfac, size_t num)
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
static BMS_CHKMEM * createChkmem(int size, int initchunksize, int garbagefactor)
void * BMSreallocBufferMemory_call(BMS_BUFMEM *buffer, void *ptr, size_t size, const char *filename, int line)
void BMSclearBlockMemory_call(BMS_BLKMEM *blkmem, const char *filename, int line)
void BMSalignMemsize(size_t *size)
static void destroyChkmem(BMS_CHKMEM **chkmem)
memory allocation routines
|