|
Go to the documentation of this file. 26 #define __STDC_LIMIT_MACROS 47 #ifdef SCIPdebugMessage 48 #define debugMessage SCIPdebugMessage 49 #define errorMessage SCIPerrorMessage 51 #define debugMessage while( FALSE ) printf 52 #define errorMessage printf 53 #define printErrorHeader(f,l) printf("[%s:%d] ERROR: ", f, l) 54 #define printError printf 57 #define warningMessage printf 58 #define printInfo printf 66 #define MAX(x,y) ((x) >= (y) ? (x) : (y)) 67 #define MIN(x,y) ((x) <= (y) ? (x) : (y)) 70 #ifndef SCIP_LONGINT_FORMAT 71 #if defined(_WIN32) || defined(_WIN64) 72 #define LONGINT_FORMAT "I64d" 74 #define LONGINT_FORMAT "lld" 77 #define LONGINT_FORMAT SCIP_LONGINT_FORMAT 80 #ifndef SCIP_MAXMEMSIZE 82 #define MAXMEMSIZE SIZE_MAX / 2 84 #define MAXMEMSIZE SCIP_MAXMEMSIZE 89 #if defined(_WIN32) || defined(_WIN64) || defined(__STDC__) 90 #define INLINE __inline 103 #if !defined(NDEBUG) && defined(NPARASCIP) 105 typedef struct Memlist MEMLIST; 117 static MEMLIST* memlist = NULL; 118 static size_t memused = 0; 127 MEMLIST* list = memlist; 130 while( list != NULL ) 135 assert(used == memused); 138 #define checkMemlist() 143 void addMemlistEntry( 146 const char* filename, 152 assert(ptr != NULL && size > 0); 154 list = (MEMLIST*)malloc( sizeof(MEMLIST)); 155 assert(list != NULL); 159 list->filename = strdup(filename); 160 assert(list->filename != NULL); 162 list->next = memlist; 170 void removeMemlistEntry( 172 const char* filename, 183 while( list != NULL && ptr != list->ptr ) 185 listptr = &(list->next); 190 assert(ptr == list->ptr); 192 *listptr = list->next; 193 assert( list->size <= memused ); 194 memused -= list->size; 195 free(list->filename); 201 printError( "Tried to free unknown pointer <%p>.\n", ptr); 214 while( list != NULL && ptr != list->ptr ) 232 while( list != NULL ) 234 printInfo( "%12p %8llu %s:%d\n", list->ptr, ( unsigned long long) list->size, list->filename, list->line); 238 printInfo( "Total: %8llu\n", ( unsigned long long) memused); 239 if( used != memused ) 241 errorMessage( "Used memory in list sums up to %llu instead of %llu\n", ( unsigned long long)used, ( unsigned long long)memused); 251 if( memlist != NULL || memused > 0 ) 263 return ( long long) memused; 286 printInfo( "Optimized version of memory shell linked - no memory diagnostics available.\n"); 296 printInfo( "Optimized version of memory shell linked - no memory leakage check available.\n"); 314 const char* filename, 320 debugMessage( "calloc %llu elements of %llu bytes [%s:%d]\n", ( unsigned long long)num, ( unsigned long long)typesize, 333 typesize = MAX(typesize, 1); 334 ptr = calloc(num, typesize); 339 printError( "Insufficient memory for allocation of %llu bytes.\n", ( unsigned long long)(num * typesize)); 341 #if !defined(NDEBUG) && defined(NPARASCIP) 343 addMemlistEntry(ptr, num*typesize, filename, line); 352 const char* filename, 358 debugMessage( "malloc %llu bytes [%s:%d]\n", ( unsigned long long)size, filename, line); 375 printError( "Insufficient memory for allocation of %llu bytes.\n", ( unsigned long long)size); 377 #if !defined(NDEBUG) && defined(NPARASCIP) 379 addMemlistEntry(ptr, size, filename, line); 389 const char* filename, 396 debugMessage( "malloc %llu elements of %llu bytes [%s:%d]\n", 397 ( unsigned long long)num, ( unsigned long long)typesize, filename, line); 408 size = num * typesize; 415 printError( "Insufficient memory for allocation of %llu bytes.\n", ( unsigned long long)size); 417 #if !defined(NDEBUG) && defined(NPARASCIP) 419 addMemlistEntry(ptr, size, filename, line); 429 const char* filename, 435 #if !defined(NDEBUG) && defined(NPARASCIP) 437 removeMemlistEntry(ptr, filename, line); 450 newptr = realloc(ptr, size); 455 printError( "Insufficient memory for reallocation of %llu bytes.\n", ( unsigned long long)size); 457 #if !defined(NDEBUG) && defined(NPARASCIP) 459 addMemlistEntry(newptr, size, filename, line); 470 const char* filename, 477 #if !defined(NDEBUG) && defined(NPARASCIP) 479 removeMemlistEntry(ptr, filename, line); 491 size = num * typesize; 493 newptr = realloc(ptr, size); 498 printError( "Insufficient memory for reallocation of %llu bytes.\n", ( unsigned long long)size); 500 #if !defined(NDEBUG) && defined(NPARASCIP) 502 addMemlistEntry(newptr, size, filename, line); 517 memset(ptr, 0, size); 531 assert(source != NULL); 532 memcpy(ptr, source, size); 548 assert(source != NULL); 549 memmove(ptr, source, size); 557 const char* filename, 563 assert(source != NULL || size == 0); 577 const char* filename, 583 assert(source != NULL || num == 0); 595 const char* filename, 599 assert( ptr != NULL ); 602 #if !defined(NDEBUG) && defined(NPARASCIP) 603 removeMemlistEntry(*ptr, filename, line); 618 const char* filename, 622 assert( ptr != NULL ); 625 #if !defined(NDEBUG) && defined(NPARASCIP) 626 removeMemlistEntry(*ptr, filename, line); 646 #define CHUNKLENGTH_MIN 1024 647 #define CHUNKLENGTH_MAX 1048576 648 #define STORESIZE_MAX 8192 649 #define GARBAGE_SIZE 256 650 #define ALIGNMENT (sizeof(FREELIST)) 740 assert(chunk != NULL); 741 assert(chunk->store <= chunk->storeend); 743 return (ptr >= ( void*)(chunk->store) && ptr < ( void*)(chunk->storeend)); 762 assert(chkmem != NULL); 767 right = chkmem->nchunks-1; 768 while( left <= right ) 770 middle = (left+right)/2; 771 assert(0 <= middle && middle < chkmem->nchunks); 772 chunk = chkmem->chunks[middle]; 773 assert(chunk != NULL); 774 if( ptr < chunk->store ) 776 else if( ptr >= chunk->storeend ) 793 assert(chkmem != NULL); 814 assert(chunk != NULL); 815 assert(chunk->store != NULL); 816 assert(chunk->storeend == ( void*)(( char*)(chunk->store) + chunk->elemsize * chunk->storesize)); 817 assert(chunk->chkmem != NULL); 818 assert(chunk->chkmem->elemsize == chunk->elemsize); 820 if( chunk->eagerfree == NULL ) 821 assert(chunk->nexteager == NULL && chunk->preveager == NULL); 822 else if( chunk->preveager == NULL ) 823 assert(chunk->chkmem->firsteager == chunk); 825 if( chunk->nexteager != NULL ) 826 assert(chunk->nexteager->preveager == chunk); 827 if( chunk->preveager != NULL ) 828 assert(chunk->preveager->nexteager == chunk); 831 eager = chunk->eagerfree; 832 while( eager != NULL ) 838 assert(chunk->eagerfreesize == eagerfreesize); 855 assert(chkmem != NULL); 856 assert(chkmem->chunks != NULL || chkmem->chunkssize == 0); 857 assert(chkmem->nchunks <= chkmem->chunkssize); 864 for( i = 0; i < chkmem->nchunks; ++i ) 866 chunk = chkmem->chunks[i]; 867 assert(chunk != NULL); 871 storesize += chunk->storesize; 872 eagerfreesize += chunk->eagerfreesize; 874 assert(chkmem->nchunks == nchunks); 875 assert(chkmem->storesize == storesize); 876 assert(chkmem->eagerfreesize == eagerfreesize); 878 assert((chkmem->eagerfreesize == 0) ^ (chkmem->firsteager != NULL)); 880 if( chkmem->firsteager != NULL ) 881 assert(chkmem->firsteager->preveager == NULL); 883 lazy = chkmem->lazyfree; 884 while( lazy != NULL ) 887 assert(chunk != NULL); 888 assert(chunk->chkmem == chkmem); 892 assert(chkmem->lazyfreesize == lazyfreesize); 895 #define checkChunk(chunk) 896 #define checkChkmem(chkmem) 915 assert(chkmem != NULL); 916 assert(chkmem->nchunks <= chkmem->chunkssize); 917 assert(chunk != NULL); 918 assert(chunk->store != NULL); 920 debugMessage( "linking chunk %p to chunk block %p [elemsize:%d, %d chunks]\n", 921 ( void*)chunk, ( void*)chkmem, chkmem->elemsize, chkmem->nchunks); 925 right = chkmem->nchunks; 926 while( left < right-1 ) 928 middle = (left+right)/2; 929 assert(0 <= middle && middle < chkmem->nchunks); 930 assert(left < middle && middle < right); 931 curchunk = chkmem->chunks[middle]; 932 assert(curchunk != NULL); 933 if( chunk->store < curchunk->store ) 937 assert(chunk->store >= curchunk->storeend); 941 assert(-1 <= left && left < chkmem->nchunks); 942 assert(0 <= right && right <= chkmem->nchunks); 943 assert(left+1 == right); 944 assert(left == -1 || chkmem->chunks[left]->storeend <= chunk->store); 945 assert(right == chkmem->nchunks || chunk->storeend <= chkmem->chunks[right]->store); 948 if( chkmem->nchunks == chkmem->chunkssize ) 950 chkmem->chunkssize = 2*(chkmem->nchunks+1); 952 if( chkmem->chunks == NULL ) 955 assert(chkmem->nchunks < chkmem->chunkssize); 956 assert(chkmem->chunks != NULL); 959 for( i = chkmem->nchunks; i > right; --i ) 961 chkmem->chunks[i] = chkmem->chunks[i-1]; 962 chkmem->chunks[i]->arraypos = i; 966 chunk->arraypos = right; 967 chkmem->chunks[right] = chunk; 969 chkmem->storesize += chunk->storesize; 983 assert(chunk != NULL); 984 assert(chunk->eagerfree == NULL); 985 assert(chunk->nexteager == NULL); 986 assert(chunk->preveager == NULL); 988 chkmem = chunk->chkmem; 989 assert(chkmem != NULL); 990 assert(chkmem->elemsize == chunk->elemsize); 991 assert(0 <= chunk->arraypos && chunk->arraypos < chkmem->nchunks); 992 assert(chkmem->chunks[chunk->arraypos] == chunk); 994 debugMessage( "unlinking chunk %p from chunk block %p [elemsize:%d, %d chunks]\n", 995 ( void*)chunk, ( void*)chkmem, chkmem->elemsize, chkmem->nchunks); 998 for( i = chunk->arraypos; i < chkmem->nchunks-1; ++i ) 1000 chkmem->chunks[i] = chkmem->chunks[i+1]; 1001 chkmem->chunks[i]->arraypos = i; 1004 chkmem->storesize -= chunk->storesize; 1014 assert(chunk->chkmem == chkmem); 1015 assert(chunk->nexteager == NULL); 1016 assert(chunk->preveager == NULL); 1018 chunk->nexteager = chkmem->firsteager; 1019 chunk->preveager = NULL; 1020 if( chkmem->firsteager != NULL ) 1022 assert(chkmem->firsteager->preveager == NULL); 1023 chkmem->firsteager->preveager = chunk; 1025 chkmem->firsteager = chunk; 1034 assert(chunk != NULL); 1035 assert(chunk->eagerfreesize == 0 || chunk->eagerfreesize == chunk->storesize); 1037 if( chunk->nexteager != NULL ) 1038 chunk->nexteager->preveager = chunk->preveager; 1039 if( chunk->preveager != NULL ) 1040 chunk->preveager->nexteager = chunk->nexteager; 1043 assert(chunk->chkmem->firsteager == chunk); 1044 chunk->chkmem->firsteager = chunk->nexteager; 1046 chunk->nexteager = NULL; 1047 chunk->preveager = NULL; 1048 chunk->eagerfree = NULL; 1065 assert(chkmem != NULL); 1067 debugMessage( "creating new chunk in chunk block %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize); 1070 if( chkmem->nchunks == 0 ) 1071 storesize = chkmem->initchunksize; 1073 storesize = 2 * chkmem->lastchunksize; 1074 assert(storesize > 0); 1078 storesize = MAX(storesize, 1); 1079 chkmem->lastchunksize = storesize; 1083 assert( chkmem->elemsize < INT_MAX / storesize ); 1084 assert( sizeof( CHUNK) < MAXMEMSIZE - ( size_t)(storesize * chkmem->elemsize) ); 1086 if( newchunk == NULL ) 1090 newchunk->store = ( void*) (( char*) newchunk + sizeof( CHUNK)); 1091 newchunk->storeend = ( void*) (( char*) newchunk->store + storesize * chkmem->elemsize); 1092 newchunk->eagerfree = NULL; 1093 newchunk->nexteager = NULL; 1094 newchunk->preveager = NULL; 1095 newchunk->chkmem = chkmem; 1096 newchunk->elemsize = chkmem->elemsize; 1097 newchunk->storesize = storesize; 1098 newchunk->eagerfreesize = 0; 1099 newchunk->arraypos = -1; 1101 debugMessage( "allocated new chunk %p: %d elements with size %d\n", ( void*)newchunk, newchunk->storesize, newchunk->elemsize); 1104 for( i = 0; i < newchunk->storesize - 1; ++i ) 1106 freelist = ( FREELIST*) (( char*) (newchunk->store) + i * chkmem->elemsize); 1107 freelist->next = ( FREELIST*) (( char*) (newchunk->store) + (i + 1) * chkmem->elemsize); 1110 freelist = ( FREELIST*) (( char*) (newchunk->store) + (newchunk->storesize - 1) * chkmem->elemsize); 1111 freelist->next = chkmem->lazyfree; 1112 chkmem->lazyfree = ( FREELIST*) (newchunk->store); 1113 chkmem->lazyfreesize += newchunk->storesize; 1129 assert(chunk != NULL); 1143 assert(chunk != NULL); 1144 assert(chunk->store != NULL); 1145 assert(chunk->eagerfree != NULL); 1146 assert(chunk->chkmem != NULL); 1147 assert(chunk->chkmem->chunks != NULL); 1148 assert(chunk->chkmem->firsteager != NULL); 1149 assert(chunk->eagerfreesize == chunk->storesize); 1151 debugMessage( "freeing chunk %p of chunk block %p [elemsize: %d]\n", ( void*)chunk, ( void*)chunk->chkmem, chunk->chkmem->elemsize); 1154 chunk->chkmem->eagerfreesize -= chunk->eagerfreesize; 1155 assert(chunk->chkmem->eagerfreesize >= 0); 1175 assert(chunk != NULL); 1176 assert(chunk->eagerfree != NULL); 1177 assert(chunk->eagerfreesize > 0); 1178 assert(chunk->chkmem != NULL); 1180 debugMessage( "allocating chunk element in chunk %p [elemsize: %d]\n", ( void*)chunk, chunk->chkmem->elemsize); 1183 ptr = chunk->eagerfree; 1184 chunk->eagerfree = ptr->next; 1185 chunk->eagerfreesize--; 1186 chunk->chkmem->eagerfreesize--; 1188 assert((chunk->eagerfreesize == 0 && chunk->eagerfree == NULL) 1189 || (chunk->eagerfreesize != 0 && chunk->eagerfree != NULL)); 1190 assert(chunk->chkmem->eagerfreesize >= 0); 1193 if( chunk->eagerfree == NULL ) 1195 assert(chunk->eagerfreesize == 0); 1211 assert(chunk != NULL); 1212 assert(chunk->chkmem != NULL); 1215 debugMessage( "freeing chunk element %p of chunk %p [elemsize: %d]\n", ( void*)ptr, ( void*)chunk, chunk->chkmem->elemsize); 1218 if( chunk->eagerfree == NULL ) 1220 assert(chunk->eagerfreesize == 0); 1225 (( FREELIST*)ptr)->next = chunk->eagerfree; 1227 chunk->eagerfreesize++; 1228 chunk->chkmem->eagerfreesize++; 1248 if( chkmem == NULL ) 1251 chkmem->lazyfree = NULL; 1252 chkmem->chunks = NULL; 1253 chkmem->firsteager = NULL; 1254 chkmem->nextchkmem = NULL; 1255 chkmem->elemsize = size; 1256 chkmem->chunkssize = 0; 1257 chkmem->nchunks = 0; 1258 chkmem->lastchunksize = 0; 1259 chkmem->storesize = 0; 1260 chkmem->lazyfreesize = 0; 1261 chkmem->eagerfreesize = 0; 1262 chkmem->initchunksize = initchunksize; 1263 chkmem->garbagefactor = garbagefactor; 1265 chkmem->filename = NULL; 1267 chkmem->ngarbagecalls = 0; 1268 chkmem->ngarbagefrees = 0; 1282 assert(chkmem != NULL); 1285 for( i = 0; i < chkmem->nchunks; ++i ) 1288 chkmem->lazyfree = NULL; 1289 chkmem->firsteager = NULL; 1290 chkmem->nchunks = 0; 1291 chkmem->lastchunksize = 0; 1292 chkmem->storesize = 0; 1293 chkmem->lazyfreesize = 0; 1294 chkmem->eagerfreesize = 0; 1303 assert(chkmem != NULL); 1304 assert(*chkmem != NULL); 1324 assert(chkmem != NULL); 1327 if( chkmem->lazyfree == NULL ) 1329 assert(chkmem->lazyfreesize == 0); 1332 if( chkmem->firsteager != NULL ) 1341 assert(chkmem->lazyfree != NULL); 1342 assert(chkmem->lazyfreesize > 0); 1344 ptr = chkmem->lazyfree; 1345 chkmem->lazyfree = ptr->next; 1346 chkmem->lazyfreesize--; 1365 assert(chkmem != NULL); 1367 debugMessage( "garbage collection for chunk block %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize); 1370 if( chkmem->lazyfreesize + chkmem->eagerfreesize == chkmem->storesize ) 1377 chkmem->ngarbagecalls++; 1381 while( chkmem->lazyfree != NULL ) 1384 lazyfree = chkmem->lazyfree; 1385 chkmem->lazyfree = chkmem->lazyfree->next; 1386 chkmem->lazyfreesize--; 1389 chunk = findChunk(chkmem, ( void*)lazyfree); 1393 errorMessage( "chunk for lazy free chunk %p not found in chunk block %p\n", ( void*)lazyfree, ( void*)chkmem); 1396 assert(chunk != NULL); 1400 assert(chunk->eagerfreesize > 0); 1402 assert(chkmem->lazyfreesize == 0); 1405 chunk = chkmem->firsteager; 1406 while( chunk != NULL && chkmem->nchunks > 1 ) 1408 nexteager = chunk->nexteager; 1409 if( chunk->eagerfreesize == chunk->storesize ) 1412 chkmem->ngarbagefrees++; 1427 const char* filename, 1431 assert(chkmem != NULL); 1432 assert(ptr != NULL); 1441 printError( "Pointer %p does not belong to chunk block %p (size: %d).\n", ptr, chkmem, chkmem->elemsize); 1446 (( FREELIST*)ptr)->next = chkmem->lazyfree; 1448 chkmem->lazyfreesize++; 1451 if( chkmem->garbagefactor >= 0 && chkmem->nchunks > 0 && chkmem->lazyfreesize >= GARBAGE_SIZE 1452 && chkmem->lazyfreesize + chkmem->eagerfreesize 1453 > chkmem->garbagefactor * ( double)(chkmem->storesize) / ( double)(chkmem->nchunks) ) 1467 const char* filename, 1474 chkmem = createChkmem(( int) size, initchunksize, garbagefactor); 1475 if( chkmem == NULL ) 1478 printError( "Insufficient memory for chunk block.\n"); 1480 debugMessage( "created chunk memory %p [elemsize: %d]\n", ( void*)chkmem, ( int)size); 1488 const char* filename, 1492 debugMessage( "clearing chunk memory %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize); 1494 if( chkmem != NULL ) 1499 printError( "Tried to clear null chunk block.\n"); 1506 const char* filename, 1510 assert(chkmem != NULL); 1512 debugMessage( "destroying chunk memory %p [elemsize: %d]\n", ( void*)*chkmem, (*chkmem)->elemsize); 1514 if( *chkmem != NULL ) 1519 printError( "Tried to destroy null chunk block.\n"); 1527 const char* filename, 1533 assert(chkmem != NULL); 1534 assert(( int)size == chkmem->elemsize); 1541 printError( "Insufficient memory for new chunk.\n"); 1543 debugMessage( "alloced %8llu bytes in %p [%s:%d]\n", ( unsigned long long)size, ( void*)ptr, filename, line); 1555 const char* filename, 1561 assert(chkmem != NULL); 1562 assert(source != NULL); 1563 assert(( int)size == chkmem->elemsize); 1577 const char* filename, 1581 assert(chkmem != NULL); 1582 assert(( int)size == chkmem->elemsize); 1583 assert( ptr != NULL ); 1587 debugMessage( "free %8d bytes in %p [%s:%d]\n", chkmem->elemsize, *ptr, filename, line); 1597 printError( "Tried to free null chunk pointer.\n"); 1606 const char* filename, 1610 assert(chkmem != NULL); 1611 assert(( int)size == chkmem->elemsize); 1612 assert( ptr != NULL ); 1616 debugMessage( "free %8d bytes in %p [%s:%d]\n", chkmem->elemsize, *ptr, filename, line); 1630 debugMessage( "garbage collection on chunk memory %p [elemsize: %d]\n", ( void*)chkmem, chkmem->elemsize); 1640 long long chkmemused; 1643 assert(chkmem != NULL); 1646 for( i = 0; i < chkmem->nchunks; ++i ) 1647 chkmemused += ( long long)(chkmem->chunks[i]->elemsize) * ( long long)(chkmem->chunks[i]->storesize); 1661 #define CHKHASH_SIZE 1013 1688 assert(blkmem != NULL); 1689 assert(blkmem->chkmemhash != NULL); 1693 chkmem = blkmem->chkmemhash[i]; 1694 while( chkmem != NULL ) 1697 chkmem = chkmem->nextchkmem; 1702 #define checkBlkmem(blkmem) 1720 assert(blkmem != NULL); 1725 chkmem = blkmem->chkmemhash[i]; 1727 chkmem = chkmem->nextchkmem; 1750 const char* filename, 1758 if( blkmem != NULL ) 1761 blkmem->chkmemhash[i] = NULL; 1762 blkmem->initchunksize = initchunksize; 1763 blkmem->garbagefactor = garbagefactor; 1764 blkmem->memused = 0; 1769 printError( "Insufficient memory for block memory header.\n"); 1778 const char* filename, 1786 if( blkmem != NULL ) 1790 chkmem = blkmem->chkmemhash[i]; 1791 while( chkmem != NULL ) 1793 nextchkmem = chkmem->nextchkmem; 1795 chkmem = nextchkmem; 1797 blkmem->chkmemhash[i] = NULL; 1799 blkmem->memused = 0; 1804 printError( "Tried to clear null block memory.\n"); 1811 const char* filename, 1815 assert(blkmem != NULL); 1817 if( *blkmem != NULL ) 1821 assert(*blkmem == NULL); 1826 printError( "Tried to destroy null block memory.\n"); 1835 const char* filename, 1843 assert( blkmem != NULL ); 1850 chkmemptr = &(blkmem->chkmemhash[hashnumber]); 1851 while( *chkmemptr != NULL && (*chkmemptr)->elemsize != ( int)size ) 1852 chkmemptr = &((*chkmemptr)->nextchkmem); 1855 if( *chkmemptr == NULL ) 1857 *chkmemptr = createChkmem(( int)size, blkmem->initchunksize, blkmem->garbagefactor); 1858 if( *chkmemptr == NULL ) 1861 printError( "Insufficient memory for chunk block.\n"); 1866 (*chkmemptr)->line = line; 1875 printError( "Insufficient memory for new chunk.\n"); 1877 debugMessage( "alloced %8llu bytes in %p [%s:%d]\n", ( unsigned long long)size, ptr, filename, line); 1879 blkmem->memused += ( long long) size; 1890 const char* filename, 1911 const char* filename, 1932 const char* filename, 1951 const char* filename, 1959 assert(oldsize == 0); 1974 if( oldsize == newsize ) 1978 if( newptr != NULL ) 1992 const char* filename, 2000 assert(oldnum == 0); 2013 if ( oldnum == newnum ) 2017 if ( newptr != NULL ) 2029 const char* filename, 2035 assert(source != NULL); 2050 const char* filename, 2056 assert(source != NULL); 2071 const char* filename, 2078 assert(ptr != NULL); 2079 assert(*ptr != NULL); 2085 debugMessage( "free %8llu bytes in %p [%s:%d]\n", ( unsigned long long)size, *ptr, filename, line); 2088 assert( blkmem->chkmemhash != NULL ); 2089 chkmem = blkmem->chkmemhash[hashnumber]; 2090 while( chkmem != NULL && chkmem->elemsize != ( int)size ) 2091 chkmem = chkmem->nextchkmem; 2092 if( chkmem == NULL ) 2095 printError( "Tried to free pointer <%p> in block memory <%p> of unknown size %llu.\n", *ptr, ( void*)blkmem, ( unsigned long long)size); 2098 assert(chkmem->elemsize == ( int)size); 2103 blkmem->memused -= ( long long) size; 2104 assert(blkmem->memused >= 0); 2114 const char* filename, 2118 assert( blkmem != NULL ); 2119 assert( ptr != NULL ); 2123 else if( size != 0 ) 2126 printError( "Tried to free null block pointer.\n"); 2136 const char* filename, 2140 assert( blkmem != NULL ); 2141 assert( ptr != NULL ); 2159 assert(blkmem != NULL); 2165 chkmemptr = &blkmem->chkmemhash[i]; 2166 while( *chkmemptr != NULL ) 2169 if( (*chkmemptr)->nchunks == 0 ) 2173 nextchkmem = (*chkmemptr)->nextchkmem; 2175 *chkmemptr = nextchkmem; 2178 chkmemptr = &(*chkmemptr)->nextchkmem; 2188 assert( blkmem != NULL ); 2190 return blkmem->memused; 2201 assert(blkmem != NULL); 2207 if( chkmem == NULL ) 2210 return ( size_t)(chkmem->elemsize); 2220 int nunusedblocks = 0; 2221 int totalnchunks = 0; 2222 int totalneagerchunks = 0; 2223 int totalnelems = 0; 2224 int totalneagerelems = 0; 2225 int totalnlazyelems = 0; 2227 int totalngarbagecalls = 0; 2228 int totalngarbagefrees = 0; 2230 long long allocedmem = 0; 2231 long long freemem = 0; 2236 printInfo( " ElSize #Chunk #Eag #Elems #EagFr #LazFr #GCl #GFr Free MBytes First Allocator\n"); 2238 printInfo( " ElSize #Chunk #Eag #Elems #EagFr #LazFr Free MBytes\n"); 2241 assert(blkmem != NULL); 2245 chkmem = blkmem->chkmemhash[i]; 2246 while( chkmem != NULL ) 2251 int neagerchunks = 0; 2252 int neagerelems = 0; 2254 for( c = 0; c < chkmem->nchunks; ++c ) 2256 chunk = chkmem->chunks[c]; 2257 assert(chunk != NULL); 2258 assert(chunk->elemsize == chkmem->elemsize); 2259 assert(chunk->chkmem == chkmem); 2261 nelems += chunk->storesize; 2262 if( chunk->eagerfree != NULL ) 2265 neagerelems += chunk->eagerfreesize; 2269 assert(nchunks == chkmem->nchunks); 2270 assert(nelems == chkmem->storesize); 2271 assert(neagerelems == chkmem->eagerfreesize); 2276 allocedmem += ( long long)chkmem->elemsize * ( long long)nelems; 2277 freemem += ( long long)chkmem->elemsize * (( long long)neagerelems + ( long long)chkmem->lazyfreesize); 2280 printInfo( "%7d %6d %4d %7d %7d %7d %5d %4d %5.1f%% %6.1f %s:%d\n", 2281 chkmem->elemsize, nchunks, neagerchunks, nelems, 2282 neagerelems, chkmem->lazyfreesize, chkmem->ngarbagecalls, chkmem->ngarbagefrees, 2283 100.0 * ( double) (neagerelems + chkmem->lazyfreesize) / ( double) (nelems), 2284 ( double)chkmem->elemsize * nelems / (1024.0*1024.0), 2285 chkmem->filename, chkmem->line); 2287 printInfo( "%7d %6d %4d %7d %7d %7d %5.1f%% %6.1f\n", 2288 chkmem->elemsize, nchunks, neagerchunks, nelems, 2289 neagerelems, chkmem->lazyfreesize, 2290 100.0 * ( double) (neagerelems + chkmem->lazyfreesize) / ( double) (nelems), 2291 ( double)chkmem->elemsize * nelems / (1024.0*1024.0)); 2297 printInfo( "%7d <unused> %5d %4d %s:%d\n", 2298 chkmem->elemsize, chkmem->ngarbagecalls, chkmem->ngarbagefrees, 2299 chkmem->filename, chkmem->line); 2301 printInfo( "%7d <unused>\n", chkmem->elemsize); 2305 totalnchunks += nchunks; 2306 totalneagerchunks += neagerchunks; 2307 totalnelems += nelems; 2308 totalneagerelems += neagerelems; 2309 totalnlazyelems += chkmem->lazyfreesize; 2311 totalngarbagecalls += chkmem->ngarbagecalls; 2312 totalngarbagefrees += chkmem->ngarbagefrees; 2314 chkmem = chkmem->nextchkmem; 2318 printInfo( " Total %6d %4d %7d %7d %7d %5d %4d %5.1f%% %6.1f\n", 2319 totalnchunks, totalneagerchunks, totalnelems, totalneagerelems, totalnlazyelems, 2320 totalngarbagecalls, totalngarbagefrees, 2321 totalnelems > 0 ? 100.0 * ( double) (totalneagerelems + totalnlazyelems) / ( double) (totalnelems) : 0.0, 2322 ( double)allocedmem/(1024.0*1024.0)); 2324 printInfo( " Total %6d %4d %7d %7d %7d %5.1f%% %6.1f\n", 2325 totalnchunks, totalneagerchunks, totalnelems, totalneagerelems, totalnlazyelems, 2326 totalnelems > 0 ? 100.0 * ( double) (totalneagerelems + totalnlazyelems) / ( double) (totalnelems) : 0.0, 2327 ( double)allocedmem/(1024.0*1024.0)); 2330 nblocks + nunusedblocks, nunusedblocks, allocedmem, freemem); 2331 if( allocedmem > 0 ) 2332 printInfo( " (%.1f%%)", 100.0 * ( double) freemem / ( double) allocedmem); 2342 long long allocedmem = 0; 2343 long long freemem = 0; 2347 assert(blkmem != NULL); 2351 chkmem = blkmem->chkmemhash[i]; 2352 while( chkmem != NULL ) 2357 int neagerelems = 0; 2359 for( c = 0; c < chkmem->nchunks; ++c ) 2361 chunk = chkmem->chunks[c]; 2362 assert(chunk != NULL); 2363 assert(chunk->elemsize == chkmem->elemsize); 2364 assert(chunk->chkmem == chkmem); 2366 nelems += chunk->storesize; 2367 if( chunk->eagerfree != NULL ) 2368 neagerelems += chunk->eagerfreesize; 2371 assert(nchunks == chkmem->nchunks); 2372 assert(nelems == chkmem->storesize); 2373 assert(neagerelems == chkmem->eagerfreesize); 2377 allocedmem += ( long long)chkmem->elemsize * ( long long)nelems; 2378 freemem += ( long long)chkmem->elemsize * (( long long)neagerelems + ( long long)chkmem->lazyfreesize); 2380 if( nelems != neagerelems + chkmem->lazyfreesize ) 2384 ((( long long)nelems - ( long long)neagerelems) - ( long long)chkmem->lazyfreesize) 2385 * ( long long)(chkmem->elemsize), 2386 (nelems - neagerelems) - chkmem->lazyfreesize, ( long long)(chkmem->elemsize), 2387 chkmem->filename, chkmem->line); 2389 printInfo( "%" LONGINT_FORMAT " bytes (%d elements of size %" LONGINT_FORMAT ") not freed.\n", 2390 ((nelems - neagerelems) - chkmem->lazyfreesize) * ( long long)(chkmem->elemsize), 2391 (nelems - neagerelems) - chkmem->lazyfreesize, ( long long)(chkmem->elemsize)); 2395 chkmem = chkmem->nextchkmem; 2399 if( allocedmem != freemem ) 2431 double arraygrowfac, 2434 const char* filename, 2440 assert( arraygrowinit > 0 ); 2441 assert( arraygrowfac > 0.0 ); 2444 if ( buffer != NULL ) 2450 buffer-> clean = clean; 2459 printError( "Insufficient memory for buffer memory header.\n"); 2468 const char* filename, 2474 if ( *buffer != NULL ) 2476 i = (*buffer)->ndata; 2480 assert( ! (*buffer)->used[i] ); 2494 printError( "Tried to free null buffer memory.\n"); 2504 assert( buffer != NULL ); 2505 assert( arraygrowfac > 0.0 ); 2516 assert( buffer != NULL ); 2517 assert( arraygrowinit > 0 ); 2522 #ifndef SCIP_NOBUFFERMEM 2536 assert( growfac >= 1.0 ); 2538 if ( growfac == 1.0 ) 2539 size = MAX(initsize, num); 2545 initsize = MAX(initsize, 4); 2550 while ( size < num && size > oldsize ) 2553 size = (size_t)(growfac * size + initsize); 2557 if ( size <= oldsize ) 2561 assert( size >= initsize ); 2562 assert( size >= num ); 2573 const char* filename, 2578 #ifndef SCIP_NOBUFFERMEM 2582 #ifndef SCIP_NOBUFFERMEM 2583 assert( buffer != NULL ); 2602 printError( "Insufficient memory for reallocating buffer data storage.\n"); 2609 printError( "Insufficient memory for reallocating buffer size storage.\n"); 2616 printError( "Insufficient memory for reallocating buffer used storage.\n"); 2621 for (i = buffer-> ndata; i < newsize; ++i) 2624 buffer-> size[i] = 0; 2627 buffer-> ndata = newsize; 2633 assert( ! buffer-> used[bufnum] ); 2634 if ( buffer-> size[bufnum] < size ) 2645 char* tmpptr = ( char*)(buffer-> data[bufnum]); 2646 size_t inc = buffer-> size[bufnum] / sizeof(*tmpptr); 2651 assert( newsize > buffer-> size[bufnum] ); 2653 buffer-> size[bufnum] = newsize; 2655 if ( buffer-> data[bufnum] == NULL ) 2658 printError( "Insufficient memory for reallocating buffer storage.\n"); 2662 assert( buffer-> size[bufnum] >= size ); 2668 char* tmpptr = ( char*)(buffer-> data[bufnum]); 2669 unsigned int inc = buffer-> size[bufnum] / sizeof(*tmpptr); 2672 while( --tmpptr >= ( char*)(buffer-> data[bufnum]) ) 2673 assert(*tmpptr == '\0'); 2677 ptr = buffer-> data[bufnum]; 2681 debugMessage( "Allocated buffer %llu/%llu at %p of size %llu (required size: %llu) for pointer %p.\n", 2682 ( unsigned long long)bufnum, ( unsigned long long)(buffer-> ndata), buffer-> data[bufnum], 2683 ( unsigned long long)(buffer-> size[bufnum]), ( unsigned long long)size, ptr); 2703 const char* filename, 2724 const char* filename, 2745 const char* filename, 2764 const char* filename, 2769 #ifndef SCIP_NOBUFFERMEM 2773 #ifndef SCIP_NOBUFFERMEM 2774 assert( buffer != NULL ); 2776 assert(!buffer-> clean); 2789 while ( bufnum > 0 && buffer-> data[bufnum] != ptr ) 2793 assert( buffer-> data[bufnum] == newptr ); 2794 assert( buffer-> used[bufnum] ); 2795 assert( buffer-> size[bufnum] >= 1 ); 2798 if ( size > buffer-> size[bufnum] ) 2805 assert( newsize > buffer-> size[bufnum] ); 2807 buffer-> size[bufnum] = newsize; 2808 if ( buffer-> data[bufnum] == NULL ) 2811 printError( "Insufficient memory for reallocating buffer storage.\n"); 2814 newptr = buffer-> data[bufnum]; 2816 assert( buffer-> size[bufnum] >= size ); 2817 assert( newptr == buffer-> data[bufnum] ); 2819 debugMessage( "Reallocated buffer %llu/%llu at %p to size %llu (required size: %llu) for pointer %p.\n", 2820 ( unsigned long long)bufnum, ( unsigned long long)(buffer-> ndata), buffer-> data[bufnum], 2821 ( unsigned long long)(buffer-> size[bufnum]), ( unsigned long long)size, newptr); 2836 const char* filename, 2858 const char* filename, 2879 const char* filename, 2885 assert( source != NULL ); 2903 const char* filename, 2909 assert( source != NULL ); 2926 const char* filename, 2932 assert( buffer != NULL ); 2935 assert( ptr != NULL ); 2936 assert( *ptr != NULL ); 2943 while ( bufnum > 0 && buffer-> data[bufnum] != *ptr ) 2947 if ( bufnum == 0 && buffer-> data[bufnum] != *ptr ) 2950 printError( "Tried to free unkown buffer pointer.\n"); 2953 if ( ! buffer-> used[bufnum] ) 2956 printError( "Tried to free buffer pointer already freed.\n"); 2965 char* tmpptr = ( char*)(buffer-> data[bufnum]); 2966 unsigned int inc = buffer-> size[bufnum] / sizeof(*tmpptr); 2969 while( --tmpptr >= ( char*)(buffer-> data[bufnum]) ) 2970 assert(*tmpptr == '\0'); 2974 assert( buffer-> data[bufnum] == *ptr ); 2980 debugMessage( "Freed buffer %llu/%llu at %p of size %llu for pointer %p, first free is %llu.\n", 2981 ( unsigned long long)bufnum, ( unsigned long long)(buffer-> ndata), buffer-> data[bufnum], 2982 ( unsigned long long)(buffer-> size[bufnum]), *ptr, ( unsigned long long)(buffer-> firstfree)); 2991 const char* filename, 2995 assert( ptr != NULL ); 2997 #ifndef SCIP_NOBUFFERMEM 3003 printError( "Tried to free null buffer pointer.\n"); 3014 const char* filename, 3018 assert( ptr != NULL ); 3022 #ifndef SCIP_NOBUFFERMEM 3035 assert( buffer != NULL ); 3046 size_t totalmem = 0UL; 3049 assert( buffer != NULL ); 3050 for (i = 0; i < buffer-> ndata; ++i) 3051 totalmem += buffer-> size[i]; 3052 assert( totalmem == buffer-> totalmem ); 3055 return ( long long) buffer-> totalmem; 3066 assert( buffer != NULL ); 3069 for (i = 0; i < buffer-> ndata; ++i) 3071 printf( "[%c] %8llu bytes at %p\n", buffer-> used[i] ? '*' : ' ', ( unsigned long long)(buffer-> size[i]), buffer-> data[i]); 3072 totalmem += buffer-> size[i]; 3074 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
#define BMSallocClearMemorySize(ptr, size)
int BMSisAligned(size_t size)
static INLINE void BMSfreeBlockMemory_work(BMS_BLKMEM *blkmem, void **ptr, 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)
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)
#define BMSclearMemorySize(ptr, size)
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)
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)
#define BMSallocMemorySize(ptr, size)
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)
#define BMSallocMemory(ptr)
void * BMSallocBufferMemory_call(BMS_BUFMEM *buffer, size_t size, const char *filename, int line)
static void unlinkChunk(CHUNK *chunk)
#define BMSreallocMemorySize(ptr, size)
static INLINE void * BMSallocBlockMemory_work(BMS_BLKMEM *blkmem, size_t size, const char *filename, int line)
#define BMSreallocMemoryArray(ptr, num)
#define BMSfreeMemory(ptr)
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)
#define BMSfreeMemoryArrayNull(ptr)
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)
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)
public methods for message output
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)
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
|