Changeset d46ed6e
- Timestamp:
- Jul 25, 2018, 6:20:35 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- cf0de0e
- Parents:
- 891790ef
- Location:
- src/libcfa
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/heap.c
r891790ef rd46ed6e 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 24 08:57:22 201813 // Update Count : 38812 // Last Modified On : Wed Jul 25 16:42:02 2018 13 // Update Count : 438 14 14 // 15 15 … … 25 25 #include "bits/defs.h" // likely, unlikely 26 26 #include "bits/locks.h" // __spinlock_t 27 #include "startup.h" // STARTUP_PRIORITY_MEMORY 27 28 #include "stdlib" // bsearchl 28 29 #include "malloc.h" … … 74 75 75 76 76 struct HeapManager { 77 // struct FreeHeader; // forward declaration 78 79 struct Storage { 80 struct Header { // header 81 union Kind { 82 struct RealHeader { 83 union { 84 struct { // 32-bit word => 64-bit header, 64-bit word => 128-bit header 85 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __U_WORDSIZE__ == 32 86 uint32_t padding; // unused, force home/blocksize to overlay alignment in fake header 87 #endif // __U_WORDSIZE__ == 32 && __U_WORDSIZE__ == 32 88 89 union { 90 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 91 void * home; // allocated block points back to home locations (must overlay alignment) 92 size_t blockSize; // size for munmap (must overlay alignment) 93 #if BUCKLOCK == SPINLOCK 94 Storage * next; // freed block points next freed block of same size 95 #endif // SPINLOCK 96 }; 97 98 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __U_WORDSIZE__ == 32 99 uint32_t padding; // unused, force home/blocksize to overlay alignment in fake header 100 #endif // __U_WORDSIZE__ == 32 && __U_WORDSIZE__ == 32 101 102 }; 103 #if BUCKLOCK == LOCKFREE 104 Stack<Storage>::Link next; // freed block points next freed block of same size (double-wide) 105 #endif // LOCKFREE 106 }; 107 } real; 108 struct FakeHeader { 109 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 110 uint32_t alignment; // low-order bits of home/blockSize used for tricks 111 #endif // __BYTE_ORDER__ 112 113 uint32_t offset; 114 115 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 116 uint32_t alignment; // low-order bits of home/blockSize used for tricks 117 #endif // __BYTE_ORDER__ 118 } fake; 119 } kind; 120 } header; // Header 121 char pad[ALIGN - sizeof( Header )]; 122 char data[0]; // storage 123 }; // Storage 124 125 static_assert( ALIGN >= sizeof( Storage ), "ALIGN < sizeof( Storage )" ); 126 127 struct FreeHeader { 128 #if BUCKLOCK == SPINLOCK 129 __spinlock_t lock; // must be first field for alignment 130 Storage * freeList; 131 #elif BUCKLOCK == LOCKFREE 132 StackLF<Storage> freeList; 133 #else 134 #error undefined lock type for bucket lock 135 #endif // SPINLOCK 136 size_t blockSize; // size of allocations on this list 137 }; // FreeHeader 138 139 // must be first fields for alignment 140 __spinlock_t extlock; // protects allocation-buffer extension 141 FreeHeader freeLists[NoBucketSizes]; // buckets for different allocation sizes 142 143 void * heapBegin; // start of heap 144 void * heapEnd; // logical end of heap 145 size_t heapRemaining; // amount of storage not allocated in the current chunk 146 }; // HeapManager 147 148 #ifdef __CFA_DEBUG__ 149 static _Bool heapBoot = 0; // detect recursion during boot 150 #endif // __CFA_DEBUG__ 151 static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing 152 153 static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; } 77 static _Bool traceHeap = false; 78 79 inline _Bool traceHeap() { 80 return traceHeap; 81 } // traceHeap 82 83 _Bool traceHeapOn() { 84 _Bool temp = traceHeap; 85 traceHeap = true; 86 return temp; 87 } // traceHeapOn 88 89 _Bool traceHeapOff() { 90 _Bool temp = traceHeap; 91 traceHeap = false; 92 return temp; 93 } // traceHeapOff 94 95 96 // static _Bool prtHeapTerm = false; 97 98 // inline _Bool prtHeapTerm() { 99 // return prtHeapTerm; 100 // } // prtHeapTerm 101 102 // _Bool prtHeapTermOn() { 103 // _Bool temp = traceHeap; 104 // traceHeap = true; 105 // return temp; 106 // } // prtHeapTermOn 107 108 // _Bool prtHeapTermOff() { 109 // _Bool temp = traceHeap; 110 // traceHeap = false; 111 // return temp; 112 // } // prtHeapTermOff 113 154 114 155 115 // statically allocated variables => zero filled. … … 178 138 #endif // FASTLOOKUP 179 139 static int mmapFd = -1; // fake or actual fd for anonymous file 140 141 static unsigned int allocfree; // running total of allocations minus frees 142 static unsigned int appStart; // storage allocation when application starts 143 144 static void checkUnfreed() { 145 #ifdef __CFA_DEBUG__ 146 unsigned int total = allocfree - appStart; 147 if ( total != 0 ) { 148 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT. 149 // char helpText[512]; 150 // int len = snprintf( helpText, 512, "CFA warning (UNIX pid:%ld) : program terminating with %u(0x%x) bytes of storage allocated but not freed.\n" 151 // "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n", 152 // (long int)getpid(), total, total ); // always print the UNIX pid 153 // __cfaabi_dbg_bits_write( helpText, len ); 154 } // if 155 #endif // __CFA_DEBUG__ 156 } // checkUnfreed 157 180 158 #ifdef __CFA_DEBUG__ 181 static unsigned int allocfree; // running total of allocations minus frees 159 extern "C" { 160 void heapAppStart() { // called by __cfaabi_appready_startup 161 appStart = allocfree; 162 } // heapAppStart 163 164 void heapAppStop() { // called by __cfaabi_appready_startdown 165 checkUnfreed(); 166 } // heapAppStop 167 } // extern "C" 182 168 #endif // __CFA_DEBUG__ 183 169 184 170 171 struct HeapManager { 172 // struct FreeHeader; // forward declaration 173 174 struct Storage { 175 struct Header { // header 176 union Kind { 177 struct RealHeader { 178 union { 179 struct { // 32-bit word => 64-bit header, 64-bit word => 128-bit header 180 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __U_WORDSIZE__ == 32 181 uint32_t padding; // unused, force home/blocksize to overlay alignment in fake header 182 #endif // __U_WORDSIZE__ == 32 && __U_WORDSIZE__ == 32 183 184 union { 185 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 186 void * home; // allocated block points back to home locations (must overlay alignment) 187 size_t blockSize; // size for munmap (must overlay alignment) 188 #if BUCKLOCK == SPINLOCK 189 Storage * next; // freed block points next freed block of same size 190 #endif // SPINLOCK 191 }; 192 193 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __U_WORDSIZE__ == 32 194 uint32_t padding; // unused, force home/blocksize to overlay alignment in fake header 195 #endif // __U_WORDSIZE__ == 32 && __U_WORDSIZE__ == 32 196 197 }; 198 #if BUCKLOCK == LOCKFREE 199 Stack<Storage>::Link next; // freed block points next freed block of same size (double-wide) 200 #endif // LOCKFREE 201 }; 202 } real; 203 struct FakeHeader { 204 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 205 uint32_t alignment; // low-order bits of home/blockSize used for tricks 206 #endif // __BYTE_ORDER__ 207 208 uint32_t offset; 209 210 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 211 uint32_t alignment; // low-order bits of home/blockSize used for tricks 212 #endif // __BYTE_ORDER__ 213 } fake; 214 } kind; 215 } header; // Header 216 char pad[ALIGN - sizeof( Header )]; 217 char data[0]; // storage 218 }; // Storage 219 220 static_assert( ALIGN >= sizeof( Storage ), "ALIGN < sizeof( Storage )" ); 221 222 struct FreeHeader { 223 #if BUCKLOCK == SPINLOCK 224 __spinlock_t lock; // must be first field for alignment 225 Storage * freeList; 226 #elif BUCKLOCK == LOCKFREE 227 StackLF<Storage> freeList; 228 #else 229 #error undefined lock type for bucket lock 230 #endif // SPINLOCK 231 size_t blockSize; // size of allocations on this list 232 }; // FreeHeader 233 234 // must be first fields for alignment 235 __spinlock_t extlock; // protects allocation-buffer extension 236 FreeHeader freeLists[NoBucketSizes]; // buckets for different allocation sizes 237 238 void * heapBegin; // start of heap 239 void * heapEnd; // logical end of heap 240 size_t heapRemaining; // amount of storage not allocated in the current chunk 241 }; // HeapManager 242 243 244 static inline _Bool setMmapStart( size_t value ) { 245 if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return true; 246 mmapStart = value; // set global 247 248 // find the closest bucket size less than or equal to the mmapStart size 249 maxBucketsUsed = bsearchl( (unsigned int)mmapStart, bucketSizes, NoBucketSizes ); // binary search 250 assert( maxBucketsUsed < NoBucketSizes ); // subscript failure ? 251 assert( mmapStart <= bucketSizes[maxBucketsUsed] ); // search failure ? 252 return false; 253 } // setMmapStart 254 255 256 static void ?{}( HeapManager & manager ) with ( manager ) { 257 pageSize = sysconf( _SC_PAGESIZE ); 258 259 for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists 260 freeLists[i].blockSize = bucketSizes[i]; 261 } // for 262 263 #ifdef FASTLOOKUP 264 unsigned int idx = 0; 265 for ( unsigned int i = 0; i < LookupSizes; i += 1 ) { 266 if ( i > bucketSizes[idx] ) idx += 1; 267 lookup[i] = idx; 268 } // for 269 #endif // FASTLOOKUP 270 271 if ( setMmapStart( default_mmap_start() ) ) { 272 abort( "HeapManager : internal error, mmap start initialization failure." ); 273 } // if 274 heapExpand = default_heap_expansion(); 275 276 char * End = (char *)sbrk( 0 ); 277 sbrk( (char *)libCeiling( (long unsigned int)End, libAlign() ) - End ); // move start of heap to multiple of alignment 278 heapBegin = heapEnd = sbrk( 0 ); // get new start point 279 } // HeapManager 280 281 282 static void ^?{}( HeapManager & ) { 283 #ifdef __STATISTICS__ 284 // if ( prtHeapTerm() ) { 285 // printStats(); 286 // checkFree( heapManager, true ); 287 // } // if 288 #endif // __STATISTICS__ 289 } // ~HeapManager 290 291 292 #ifdef __CFA_DEBUG__ 293 static _Bool heapBoot = 0; // detect recursion during boot 294 #endif // __CFA_DEBUG__ 295 static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing 296 297 static void memory_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_MEMORY ) )); 298 void memory_startup( void ) { 299 #ifdef __CFA_DEBUG__ 300 if ( unlikely( heapBoot ) ) { // check for recursion during system boot 301 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT. 302 abort( "boot() : internal error, recursively invoked during system boot." ); 303 } // if 304 heapBoot = true; 305 #endif // __CFA_DEBUG__ 306 307 heapManager{}; 308 } // memory_startup 309 310 static void memory_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_MEMORY ) )); 311 void memory_shutdown( void ) { 312 ^heapManager{}; 313 } // memory_shutdown 314 315 static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; } 316 317 185 318 #ifdef __STATISTICS__ 186 // Heap statistics 187 static unsigned long long int mmap_storage; 319 static unsigned long long int mmap_storage; // heap statistics counters 188 320 static unsigned int mmap_calls; 189 321 static unsigned long long int munmap_storage; … … 203 335 static unsigned long long int realloc_storage; 204 336 static unsigned int realloc_calls; 205 static int statfd; 337 338 static int statfd; // statistics file descriptor (changed by malloc_stats_fd) 206 339 207 340 208 341 // Use "write" because streams may be shutdown when calls are made. 209 static void print () {342 static void printStats() { 210 343 char helpText[512]; 211 344 int len = snprintf( helpText, 512, … … 231 364 ); 232 365 write( statfd, helpText, len ); 233 } // print 234 235 236 static int print XML( FILE * stream ) {366 } // printStats 367 368 369 static int printStatsXML( FILE * stream ) { 237 370 char helpText[512]; 238 371 int len = snprintf( helpText, 512, … … 262 395 ); 263 396 return write( fileno( stream ), helpText, len ); // -1 => error 264 } // print XML397 } // printStatsXML 265 398 #endif // __STATISTICS__ 266 399 … … 287 420 288 421 289 static inline _Bool setMmapStart( size_t value ) {290 if ( value < pageSize || bucketSizes[NoBucketSizes-1] < value ) return true;291 mmapStart = value; // set global292 293 // find the closest bucket size less than or equal to the mmapStart size294 maxBucketsUsed = bsearchl( (unsigned int)mmapStart, bucketSizes, NoBucketSizes ); // binary search295 assert( maxBucketsUsed < NoBucketSizes ); // subscript failure ?296 assert( mmapStart <= bucketSizes[maxBucketsUsed] ); // search failure ?297 return false;298 } // setMmapStart299 300 301 422 static inline void checkHeader( _Bool check, const char * name, void * addr ) { 302 423 if ( unlikely( check ) ) { // bad address ? … … 306 427 } // if 307 428 } // checkHeader 429 308 430 309 431 static inline void fakeHeader( HeapManager.Storage.Header *& header, size_t & size, size_t & alignment ) { … … 448 570 assert( ((uintptr_t)area & (libAlign() - 1)) == 0 ); // minimum alignment ? 449 571 __atomic_add_fetch( &allocfree, tsize, __ATOMIC_SEQ_CST ); 450 // if ( uHeapControl::traceHeap() ) {451 //enum { BufferSize = 64 };452 //char helpText[BufferSize];453 //int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", area, size, tsize );454 // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", area, size );455 // uDebugWrite( STDERR_FILENO,helpText, len );456 //} // if572 if ( traceHeap() ) { 573 enum { BufferSize = 64 }; 574 char helpText[BufferSize]; 575 int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", area, size, tsize ); 576 // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", area, size ); 577 __cfaabi_dbg_bits_write( helpText, len ); 578 } // if 457 579 #endif // __CFA_DEBUG__ 458 580 … … 505 627 #ifdef __CFA_DEBUG__ 506 628 __atomic_add_fetch( &allocfree, -size, __ATOMIC_SEQ_CST ); 507 // if ( uHeapControl::traceHeap() ) {508 //enum { BufferSize = 64 };509 //char helpText[BufferSize];510 //int len = snprintf( helpText, BufferSize, "Free( %p ) size:%zu\n", addr, size );511 // uDebugWrite( STDERR_FILENO,helpText, len );512 //} // if629 if ( traceHeap() ) { 630 enum { BufferSize = 64 }; 631 char helpText[BufferSize]; 632 int len = snprintf( helpText, BufferSize, "Free( %p ) size:%zu\n", addr, size ); 633 __cfaabi_dbg_bits_write( helpText, len ); 634 } // if 513 635 #endif // __CFA_DEBUG__ 514 636 } // doFree 515 637 516 638 517 // size_t checkFree( _Bool prt ) { 518 // size_t total = 0; 519 // #ifdef __STATISTICS__ 520 // uDebugAcquire(); 521 // if ( prt ) uDebugPrt2( "\nBin lists (bin size : free blocks on list)\n" ); 522 // #endif // __STATISTICS__ 523 // for ( unsigned int i = 0; i < maxBucketsUsed; i += 1 ) { 524 // size_t size = freeLists[i].blockSize; 525 // #ifdef __STATISTICS__ 526 // unsigned int N = 0; 527 // #endif // __STATISTICS__ 528 // #if defined( SPINLOCK ) 529 // for ( Storage * p = freeLists[i].freeList; p != 0; p = p->header.kind.real.next ) { 530 // #else 531 // for ( Storage * p = freeLists[i].freeList.top(); p != 0; p = p->header.kind.real.next.top ) { 532 // #endif // SPINLOCK 533 // total += size; 534 // #ifdef __STATISTICS__ 535 // N += 1; 536 // #endif // __STATISTICS__ 537 // } // for 538 // #ifdef __STATISTICS__ 539 // if ( prt ) uDebugPrt2( "%7zu, %-7u ", size, N ); 540 // if ( (i + 1) % 8 == 0 ) uDebugPrt2( "\n" ); 541 // #endif // __STATISTICS__ 542 // } // for 543 // #ifdef __STATISTICS__ 544 // if ( prt ) uDebugPrt2( "\ntotal free blocks:%zu\n", total ); 545 // uDebugRelease(); 546 // #endif // __STATISTICS__ 547 // return (char *)heapEnd - (char *)heapBegin - total; 548 // } // for 549 // } // checkFree 550 551 552 static void ?{}( HeapManager & manager ) with ( manager ) { 553 pageSize = sysconf( _SC_PAGESIZE ); 554 555 for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists 556 freeLists[i].blockSize = bucketSizes[i]; 557 } // for 558 559 #ifdef FASTLOOKUP 560 unsigned int idx = 0; 561 for ( unsigned int i = 0; i < LookupSizes; i += 1 ) { 562 if ( i > bucketSizes[idx] ) idx += 1; 563 lookup[i] = idx; 564 } // for 565 #endif // FASTLOOKUP 566 567 if ( setMmapStart( default_mmap_start() ) ) { 568 abort( "HeapManager : internal error, mmap start initialization failure." ); 569 } // if 570 heapExpand = default_heap_expansion(); 571 572 char * End = (char *)sbrk( 0 ); 573 sbrk( (char *)libCeiling( (long unsigned int)End, libAlign() ) - End ); // move start of heap to multiple of alignment 574 heapBegin = heapEnd = sbrk( 0 ); // get new start point 575 } // HeapManager 576 577 578 static void ^?{}( HeapManager & ) { 639 size_t checkFree( HeapManager & manager, _Bool prt ) with ( manager ) { 640 size_t total = 0; 579 641 #ifdef __STATISTICS__ 580 // if ( prtHeapterm ) { 581 // print(); 582 // heapManager.checkFree( true ); 583 // } // if 642 __cfaabi_dbg_bits_acquire(); 643 if ( prt ) __cfaabi_dbg_bits_print_nolock( "\nBin lists (bin size : free blocks on list)\n" ); 584 644 #endif // __STATISTICS__ 585 586 #ifdef __CFA_DEBUG__ 587 if ( allocfree != 0 ) { 588 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT. 589 char helpText[512]; 590 int len = snprintf( helpText, 512, "CFA warning (UNIX pid:%ld) : program terminating with %u(0x%x) bytes of storage allocated but not freed.\n" 591 "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n", 592 (long int)getpid(), allocfree, allocfree ); // always print the UNIX pid 593 __cfaabi_dbg_bits_write( helpText, len ); 594 } // if 595 #endif // __CFA_DEBUG__ 596 } // ~HeapManager 645 for ( unsigned int i = 0; i < maxBucketsUsed; i += 1 ) { 646 size_t size = freeLists[i].blockSize; 647 #ifdef __STATISTICS__ 648 unsigned int N = 0; 649 #endif // __STATISTICS__ 650 #if defined( SPINLOCK ) 651 for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0; p = p->header.kind.real.next ) { 652 #else 653 for ( HeapManager.Storage * p = freeLists[i].freeList.top(); p != 0; p = p->header.kind.real.next.top ) { 654 #endif // SPINLOCK 655 total += size; 656 #ifdef __STATISTICS__ 657 N += 1; 658 #endif // __STATISTICS__ 659 } // for 660 #ifdef __STATISTICS__ 661 if ( prt ) __cfaabi_dbg_bits_print_nolock( "%7zu, %-7u ", size, N ); 662 if ( (i + 1) % 8 == 0 ) __cfaabi_dbg_bits_print_nolock( "\n" ); 663 #endif // __STATISTICS__ 664 } // for 665 #ifdef __STATISTICS__ 666 if ( prt ) __cfaabi_dbg_bits_print_nolock( "\ntotal free blocks:%zu\n", total ); 667 __cfaabi_dbg_bits_release(); 668 #endif // __STATISTICS__ 669 return (char *)heapEnd - (char *)heapBegin - total; 670 } // checkFree 597 671 598 672 599 673 static inline void * malloc2( size_t size ) { // necessary for malloc statistics 600 if ( unlikely( heapManager.heapBegin == 0 ) ) { 601 #ifdef __CFA_DEBUG__ 602 if ( unlikely( heapBoot ) ) { // check for recursion during system boot 603 // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT. 604 abort( "boot() : internal error, recursively invoked during system boot." ); 605 } // if 606 heapBoot = true; 607 #endif // __CFA_DEBUG__ 608 609 heapManager{}; 610 } // if 611 674 assert( heapManager.heapBegin != 0 ) ; // heap started 612 675 void * area = doMalloc( size ); 613 676 if ( unlikely( area == 0 ) ) errno = ENOMEM; // POSIX … … 793 856 794 857 if ( unlikely( addr == 0 ) ) { // special case 795 //#ifdef __CFA_DEBUG__796 // if ( uHeapControl::traceHeap() ) {797 // #define nullmsg "Free( 0x0 ) size:0\n"798 //// Do not debug print free( 0 ), as it can cause recursive entry from sprintf.799 // uDebugWrite( STDERR_FILENO,nullmsg, sizeof(nullmsg) - 1 );800 //} // if801 //#endif // __CFA_DEBUG__858 #ifdef __CFA_DEBUG__ 859 if ( traceHeap() ) { 860 #define nullmsg "Free( 0x0 ) size:0\n" 861 // Do not debug print free( 0 ), as it can cause recursive entry from sprintf. 862 __cfaabi_dbg_bits_write( nullmsg, sizeof(nullmsg) - 1 ); 863 } // if 864 #endif // __CFA_DEBUG__ 802 865 return; 803 866 } // exit 804 867 805 868 doFree( addr ); 806 // Do not debug print free( 0 ), as it can cause recursive entry from sprintf.807 869 } // free 808 870 … … 859 921 void malloc_stats( void ) { 860 922 #ifdef __STATISTICS__ 861 print ();862 // heapManager.checkFree(true );923 printStats(); 924 checkFree( heapManager, true ); 863 925 #endif // __STATISTICS__ 864 926 } // malloc_stats … … 877 939 878 940 int malloc_info( int options, FILE * stream ) { 879 return print XML( stream );941 return printStatsXML( stream ); 880 942 } // malloc_info 881 943 -
src/libcfa/stdhdr/malloc.h
r891790ef rd46ed6e 10 10 // Created On : Thu Jul 20 15:58:16 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 20 16:00:12 201713 // Update Count : 412 // Last Modified On : Mon Jul 23 18:20:32 2018 13 // Update Count : 8 14 14 // 15 16 17 size_t default_mmap_start(); // CFA extras 18 size_t default_heap_expansion(); 19 extern "C" { 20 size_t malloc_alignment( void * ); 21 _Bool malloc_zero_fill( void * ); 22 int malloc_stats_fd( int fd ); 23 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); 24 } // extern "C" 15 25 16 26 extern "C" { -
src/libcfa/stdlib
r891790ef rd46ed6e 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 12 08:03:58201813 // Update Count : 3 3712 // Last Modified On : Mon Jul 23 07:44:47 2018 13 // Update Count : 341 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <stdlib.h> // allocation, strto*, ato*18 #include <stdlib.h> // *alloc, strto*, ato* 19 19 extern "C" { 20 20 void * memalign( size_t align, size_t size ); // malloc.h 21 21 void * memset( void * dest, int c, size_t size ); // string.h 22 22 void * memcpy( void * dest, const void * src, size_t size ); // string.h 23 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA 23 24 } // extern "C" 24 25 … … 36 37 37 38 T * malloc( void ) { 38 // printf( "* malloc\n" );39 39 return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc 40 40 } // malloc … … 48 48 49 49 T * calloc( size_t dim ) { 50 //printf( "X2\n" );51 50 return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc 52 51 } // calloc 53 52 54 53 T * realloc( T * ptr, size_t size ) { 55 //printf( "X3\n" );56 54 return (T *)(void *)realloc( (void *)ptr, size ); 57 55 } // realloc 58 56 59 57 T * memalign( size_t align ) { 60 //printf( "X4\n" );61 58 return (T *)memalign( align, sizeof(T) ); 62 59 } // memalign 63 60 64 61 T * aligned_alloc( size_t align ) { 65 //printf( "X5\n" );66 62 return (T *)aligned_alloc( align, sizeof(T) ); 67 63 } // aligned_alloc 68 64 69 65 int posix_memalign( T ** ptr, size_t align ) { 70 //printf( "X6\n" );71 66 return posix_memalign( (void **)ptr, align, sizeof(T) ); // C posix_memalign 72 67 } // posix_memalign … … 76 71 77 72 T * alloc( void ) { 78 //printf( "X7\n" );79 73 return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc 80 74 } // alloc 81 75 82 76 T * alloc( char fill ) { 83 //printf( "X8\n" );84 77 T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc 85 78 return (T *)memset( ptr, (int)fill, sizeof(T) ); // initial with fill value … … 87 80 88 81 T * alloc( size_t dim ) { 89 //printf( "X9\n" );90 82 return (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc 91 83 } // alloc 92 84 93 85 T * alloc( size_t dim, char fill ) { 94 //printf( "X10\n" );95 86 T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc 96 87 return (T *)memset( ptr, (int)fill, dim * sizeof(T) ); // initial with fill value … … 98 89 99 90 T * alloc( T ptr[], size_t dim ) { 100 //printf( "X11\n" );101 91 return (T *)(void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc 102 92 } // alloc … … 109 99 static inline forall( dtype T | sized(T) ) { 110 100 T * align_alloc( size_t align ) { 111 //printf( "X13\n" );112 101 return (T *)memalign( align, sizeof(T) ); 113 102 } // align_alloc 114 103 115 104 T * align_alloc( size_t align, char fill ) { 116 //printf( "X14\n" );117 105 T * ptr = (T *)memalign( align, sizeof(T) ); 118 106 return (T *)memset( ptr, (int)fill, sizeof(T) ); … … 120 108 121 109 T * align_alloc( size_t align, size_t dim ) { 122 //printf( "X15\n" );123 110 return (T *)memalign( align, dim * sizeof(T) ); 124 111 } // align_alloc 125 112 126 113 T * align_alloc( size_t align, size_t dim, char fill ) { 127 //printf( "X16\n" ); 128 T * ptr = (T *)memalign( align, dim * sizeof(T) ); 129 return (T *)memset( ptr, (int)fill, dim * sizeof(T) ); 114 T * ptr; 115 if ( fill == '\0' ) { 116 ptr = (T *)cmemalign( align, dim, sizeof(T) ); 117 } else { 118 ptr = (T *)memalign( align, dim * sizeof(T) ); 119 return (T *)memset( ptr, (int)fill, dim * sizeof(T) ); 120 } // if 121 return ptr; 130 122 } // align_alloc 131 123 } // distribution … … 136 128 137 129 T * memset( T * dest, char c ) { 138 //printf( "X17\n" );139 130 return (T *)memset( dest, c, sizeof(T) ); 140 131 } // memset 141 132 142 133 T * memcpy( T * dest, const T * src ) { 143 //printf( "X18\n" );144 134 return (T *)memcpy( dest, src, sizeof(T) ); 145 135 } // memcpy … … 150 140 151 141 T * memset( T dest[], size_t dim, char c ) { 152 //printf( "X19\n" );153 142 return (T *)(void *)memset( dest, c, dim * sizeof(T) ); // C memset 154 143 } // memset 155 144 156 145 T * memcpy( T dest[], const T src[], size_t dim ) { 157 //printf( "X20\n" );158 146 return (T *)(void *)memcpy( dest, src, dim * sizeof(T) ); // C memcpy 159 147 } // memcpy
Note: See TracChangeset
for help on using the changeset viewer.