Changeset c1f38e6c
- Timestamp:
- Aug 6, 2020, 6:56:35 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 0c30ecc, da3b790
- Parents:
- c8e4b23d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
rc8e4b23d rc1f38e6c 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 5 22:21:27202013 // Update Count : 8 5312 // Last Modified On : Thu Aug 6 09:08:58 2020 13 // Update Count : 861 14 14 // 15 15 … … 95 95 96 96 #ifdef __CFA_DEBUG__ 97 static unsigned int alloc Free;// running total of allocations minus frees97 static unsigned int allocUnfreed; // running total of allocations minus frees 98 98 99 99 static void prtUnfreed() { 100 if ( alloc Free!= 0 ) {100 if ( allocUnfreed != 0 ) { 101 101 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT. 102 102 char helpText[512]; 103 103 int len = snprintf( helpText, sizeof(helpText), "CFA warning (UNIX pid:%ld) : program terminating with %u(0x%x) bytes of storage allocated but not freed.\n" 104 104 "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n", 105 (long int)getpid(), alloc Free, allocFree); // always print the UNIX pid105 (long int)getpid(), allocUnfreed, allocUnfreed ); // always print the UNIX pid 106 106 __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug 107 107 } // if … … 110 110 extern "C" { 111 111 void heapAppStart() { // called by __cfaabi_appready_startup 112 alloc Free= 0;112 allocUnfreed = 0; 113 113 } // heapAppStart 114 114 … … 226 226 #define __STATISTICS__ 227 227 228 // Bucket sizemust be multiple of 16.228 // Size of array must harmonize with NoBucketSizes and individual bucket sizes must be multiple of 16. 229 229 // Smaller multiples of 16 and powers of 2 are common allocation sizes, so make them generate the minimum required bucket size. 230 230 // malloc(0) returns 0p, so no bucket is necessary for 0 bytes returning an address that can be freed. … … 249 249 }; 250 250 251 static_assert( NoBucketSizes == sizeof(bucketSizes) / sizeof(bucketSizes[0] ), "size of bucket array wrong" );251 static_assert( NoBucketSizes == sizeof(bucketSizes) / sizeof(bucketSizes[0] ), "size of bucket array wrong" ); 252 252 253 253 #ifdef FASTLOOKUP … … 267 267 #ifdef __STATISTICS__ 268 268 // Heap statistics counters. 269 static unsigned int malloc_calls; 270 static unsigned long long int malloc_storage; 271 static unsigned int aalloc_calls; 272 static unsigned long long int aalloc_storage; 273 static unsigned int calloc_calls; 274 static unsigned long long int calloc_storage; 275 static unsigned int memalign_calls; 276 static unsigned long long int memalign_storage; 277 static unsigned int amemalign_calls; 278 static unsigned long long int amemalign_storage; 279 static unsigned int cmemalign_calls; 280 static unsigned long long int cmemalign_storage; 281 static unsigned int resize_calls; 282 static unsigned long long int resize_storage; 283 static unsigned int realloc_calls; 284 static unsigned long long int realloc_storage; 285 static unsigned int free_calls; 286 static unsigned long long int free_storage; 287 static unsigned int mmap_calls; 269 288 static unsigned long long int mmap_storage; 270 static unsigned int m map_calls;289 static unsigned int munmap_calls; 271 290 static unsigned long long int munmap_storage; 272 static unsigned int munmap_calls;291 static unsigned int sbrk_calls; 273 292 static unsigned long long int sbrk_storage; 274 static unsigned int sbrk_calls;275 static unsigned long long int malloc_storage;276 static unsigned int malloc_calls;277 static unsigned long long int free_storage;278 static unsigned int free_calls;279 static unsigned long long int aalloc_storage;280 static unsigned int aalloc_calls;281 static unsigned long long int calloc_storage;282 static unsigned int calloc_calls;283 static unsigned long long int memalign_storage;284 static unsigned int memalign_calls;285 static unsigned long long int amemalign_storage;286 static unsigned int amemalign_calls;287 static unsigned long long int cmemalign_storage;288 static unsigned int cmemalign_calls;289 static unsigned long long int resize_storage;290 static unsigned int resize_calls;291 static unsigned long long int realloc_storage;292 static unsigned int realloc_calls;293 293 // Statistics file descriptor (changed by malloc_stats_fd). 294 294 static int statfd = STDERR_FILENO; // default stderr … … 410 410 411 411 412 // static inline void noMemory() {413 // abort( "Heap memory exhausted at %zu bytes.\n"414 // "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",415 // ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );416 // } // noMemory417 418 419 412 static inline void checkAlign( size_t alignment ) { 420 413 if ( alignment < libAlign() || ! libPow2( alignment ) ) { … … 441 434 header = realHeader( header ); // backup from fake to real header 442 435 } else { 443 alignment = 0;436 alignment = libAlign(); // => no fake header 444 437 } // if 445 438 } // fakeHeader … … 542 535 // #endif // FASTLOOKUP 543 536 // bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search 544 assert( freeElem <= &freeLists[maxBucketsUsed] ); // subscripting error ?545 assert( tsize <= freeElem->blockSize ); // search failure ?537 verify( freeElem <= &freeLists[maxBucketsUsed] ); // subscripting error ? 538 verify( tsize <= freeElem->blockSize ); // search failure ? 546 539 tsize = freeElem->blockSize; // total space needed for request 547 540 … … 599 592 block->header.kind.real.size = size; // store allocation size 600 593 void * addr = &(block->data); // adjust off header to user bytes 594 verify( ((uintptr_t)addr & (libAlign() - 1)) == 0 ); // minimum alignment ? 601 595 602 596 #ifdef __CFA_DEBUG__ 603 assert( ((uintptr_t)addr & (libAlign() - 1)) == 0 ); // minimum alignment ? 604 __atomic_add_fetch( &allocFree, tsize, __ATOMIC_SEQ_CST ); 597 __atomic_add_fetch( &allocUnfreed, tsize, __ATOMIC_SEQ_CST ); 605 598 if ( traceHeap() ) { 606 599 enum { BufferSize = 64 }; 607 600 char helpText[BufferSize]; 608 601 int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", addr, size, tsize ); 609 // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", addr, size );610 602 __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug 611 603 } // if … … 659 651 660 652 #ifdef __CFA_DEBUG__ 661 __atomic_add_fetch( &alloc Free, -size, __ATOMIC_SEQ_CST );653 __atomic_add_fetch( &allocUnfreed, -size, __ATOMIC_SEQ_CST ); 662 654 if ( traceHeap() ) { 663 655 enum { BufferSize = 64 }; … … 753 745 #endif // __CFA_DEBUG__ 754 746 755 // assert( heapManager.heapBegin != 0 );747 //verify( heapManager.heapBegin != 0 ); 756 748 //heapManager{}; 757 749 if ( heapManager.heapBegin == 0p ) heapManager{}; // sanity check … … 991 983 } // realloc 992 984 985 993 986 // Same as malloc() except the memory address is a multiple of alignment, which must be a power of two. (obsolete) 994 987 void * memalign( size_t alignment, size_t size ) { … … 1035 1028 // free(3). 1036 1029 int posix_memalign( void ** memptr, size_t alignment, size_t size ) { 1037 if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) return EINVAL; // check alignment1030 if ( alignment < libAlign() || ! libPow2( alignment ) ) return EINVAL; // check alignment 1038 1031 * memptr = memalign( alignment, size ); 1039 1032 return 0; … … 1194 1187 } // mallopt 1195 1188 1189 1196 1190 // Attempt to release free memory at the top of the heap (by calling sbrk with a suitable argument). 1197 1191 int malloc_trim( size_t ) { … … 1237 1231 if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size ); 1238 1232 1239 if ( unlikely( nalign == 0 ) ) nalign = libAlign();// reset alignment to minimum1233 if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum 1240 1234 #ifdef __CFA_DEBUG__ 1241 1235 else … … 1250 1244 1251 1245 if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match 1252 if ( oalign > =libAlign() ) { // fake header ?1246 if ( oalign > libAlign() ) { // fake header ? 1253 1247 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same) 1254 1248 } // if … … 1267 1261 1268 1262 void * realloc( void * oaddr, size_t nalign, size_t size ) { 1269 if ( unlikely( nalign == 0 ) ) nalign = libAlign();// reset alignment to minimum1263 if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum 1270 1264 #ifdef __CFA_DEBUG__ 1271 1265 else … … 1279 1273 1280 1274 if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match 1281 if ( oalign > =libAlign() ) { // fake header ?1275 if ( oalign > libAlign() ) { // fake header ? 1282 1276 headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same) 1283 1277 } // if
Note: See TracChangeset
for help on using the changeset viewer.