Changes in libcfa/src/heap.cfa [dd23e66:d5d3a90]
- File:
-
- 1 edited
-
libcfa/src/heap.cfa (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/heap.cfa
rdd23e66 rd5d3a90 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 : Mon Aug 3 19:01:22 2020 13 // Update Count : 828 14 14 // 15 15 … … 80 80 }; 81 81 82 size_t default_heap_expansion() __attribute__(( weak )) { 83 return __CFA_DEFAULT_HEAP_EXPANSION__; 84 } // default_heap_expansion 85 82 86 size_t default_mmap_start() __attribute__(( weak )) { 83 87 return __CFA_DEFAULT_MMAP_START__; 84 88 } // default_mmap_start 85 86 size_t default_heap_expansion() __attribute__(( weak )) {87 return __CFA_DEFAULT_HEAP_EXPANSION__;88 } // default_heap_expansion89 90 bool default_heap_exhausted() __attribute__(( weak )) { // find and free some storage91 // Returning false prints "out of heap memory" message and aborts.92 return false;93 } // default_heap_exhausted94 89 95 90 … … 478 473 } // headers 479 474 480 #define NO_MEMORY_MSG "no heap memory available for allocating %zd new bytes."481 475 482 476 static inline void * extend( size_t size ) with( heapManager ) { … … 487 481 488 482 size_t increase = libCeiling( size > heapExpand ? size : heapExpand, libAlign() ); 489 Succeed: 490 { 491 if ( sbrk( increase ) != (void *)-1 ) break Succeed; // succeed ? 492 if ( default_heap_exhausted() ) { // try fix 493 if ( sbrk( increase ) != (void *)-1 ) break Succeed; // succeed ? 494 } // if 483 if ( sbrk( increase ) == (void *)-1 ) { 495 484 unlock( extlock ); 496 abort( NO_MEMORY_MSG, size ); // give up 497 } 485 errno = ENOMEM; 486 // return 0p; 487 abort( "no memory" ); 488 } // if 498 489 #ifdef __STATISTICS__ 499 490 sbrk_calls += 1; … … 563 554 564 555 block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call 556 // if ( unlikely( block == 0p ) ) return 0p; 565 557 #if BUCKETLOCK == SPINLOCK 566 558 } else { … … 578 570 __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST ); 579 571 #endif // __STATISTICS__ 580 Succeed: 581 { 582 block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 ); 583 if ( block != (HeapManager.Storage *)MAP_FAILED ) break Succeed; // succeed ? 584 if ( errno == ENOMEM && default_heap_exhausted() ) { // out of memory and try again ? 585 block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 ); 586 if ( block != (HeapManager.Storage *)MAP_FAILED ) break Succeed; // succeed ? 587 } // if 588 if ( errno == ENOMEM ) abort( NO_MEMORY_MSG, tsize ); 572 block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 ); 573 if ( block == (HeapManager.Storage *)MAP_FAILED ) { 589 574 // Do not call strerror( errno ) as it may call malloc. 590 575 abort( "(HeapManager &)0x%p.doMalloc() : internal error, mmap failure, size:%zu error:%d.", &heapManager, tsize, errno ); 591 } 576 } // if 592 577 #ifdef __CFA_DEBUG__ 593 578 // Set new memory to garbage so subsequent uninitialized usages might fail. … … 766 751 static inline void * mallocNoStats( size_t size ) { // necessary for malloc statistics 767 752 verify( heapManager.heapBegin != 0 ); // called before memory_startup ? 768 if ( unlikely( size ) == 0 ) return 0p;// 0 BYTE ALLOCATION RETURNS NULL POINTER753 if ( size == 0 ) return 0p; // 0 BYTE ALLOCATION RETURNS NULL POINTER 769 754 770 755 #if __SIZEOF_POINTER__ == 8 … … 777 762 static inline void * callocNoStats( size_t dim, size_t elemSize ) { 778 763 size_t size = dim * elemSize; 779 if ( unlikely( size ) == 0 ) return 0p;// 0 BYTE ALLOCATION RETURNS NULL POINTER764 if ( size == 0 ) return 0p; // 0 BYTE ALLOCATION RETURNS NULL POINTER 780 765 char * addr = (char *)mallocNoStats( size ); 781 766 … … 788 773 headers( "calloc", addr, header, freeElem, bsize, alignment ); 789 774 #ifndef __CFA_DEBUG__ 790 791 775 // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero. 792 776 if ( ! mapped ) … … 802 786 803 787 static inline void * memalignNoStats( size_t alignment, size_t size ) { // necessary for malloc statistics 804 if ( unlikely( size ) == 0 ) return 0p;// 0 BYTE ALLOCATION RETURNS NULL POINTER788 if ( size == 0 ) return 0p; // 0 BYTE ALLOCATION RETURNS NULL POINTER 805 789 806 790 #ifdef __CFA_DEBUG__ … … 841 825 static inline void * cmemalignNoStats( size_t alignment, size_t dim, size_t elemSize ) { 842 826 size_t size = dim * elemSize; 843 if ( unlikely( size ) == 0 ) return 0p;// 0 BYTE ALLOCATION RETURNS NULL POINTER827 if ( size == 0 ) return 0p; // 0 BYTE ALLOCATION RETURNS NULL POINTER 844 828 char * addr = (char *)memalignNoStats( alignment, size ); 845 829 … … 847 831 HeapManager.FreeHeader * freeElem; 848 832 size_t bsize; 833 bool mapped __attribute__(( unused )) = headers( "cmemalign", addr, header, freeElem, bsize, alignment ); 849 834 #ifndef __CFA_DEBUG__ 850 bool mapped =851 #endif // __CFA_DEBUG__852 headers( "cmemalign", addr, header, freeElem, bsize, alignment );853 #ifndef __CFA_DEBUG__854 855 835 // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero. 856 836 if ( ! mapped ) 857 837 #endif // __CFA_DEBUG__ 858 // <-------0000000000000000000000000000UUUUUUUUUUUUUUUUUUUUUUUUU> bsize (bucket size) U => undefined 859 // `-header`-addr `-size 860 memset( addr, '\0', size ); // set to zeros 838 memset( addr, '\0', dataStorage( bsize, addr, header ) ); // set to zeros 861 839 862 840 header->kind.real.blockSize |= 2; // mark as zero filled … … 1157 1135 1158 1136 headers( "malloc_usable_size", addr, header, freeElem, bsize, alignment ); 1159 return dataStorage( bsize, addr, header ); // data storage in bucket1137 return dataStorage( bsize, addr, header ); // data storage in bucket 1160 1138 } // malloc_usable_size 1161 1139 … … 1255 1233 if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 1256 1234 header->kind.real.blockSize &= -2; // turn off 0 fill 1257 header->kind.real.size = size;// reset allocation size1235 if ( size != odsize ) header->kind.real.size = size; // reset allocation size 1258 1236 return oaddr; 1259 1237 } // if 1260 1238 } // if 1261 1239 1262 // change size, DO NOT preserve STICKY PROPERTIES. 1240 // change size 1241 1242 void * naddr = memalignNoStats( nalign, size ); // create new aligned area 1263 1243 free( oaddr ); 1264 return memalignNoStats( nalign, size ); // create new aligned area1244 return naddr; 1265 1245 } // resize 1266 1246 … … 1292 1272 #endif // __STATISTICS__ 1293 1273 1274 size_t osize = header->kind.real.size; // old allocation size 1275 bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled 1276 1294 1277 // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned. 1295 1278 if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases 1296 1279 if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size ); 1297 1280 1298 size_t osize = header->kind.real.size; // old allocation size 1299 bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled 1300 1301 void * naddr = memalignNoStats( nalign, size ); // create new aligned area 1281 void * naddr; 1282 if ( unlikely( header->kind.real.blockSize & 2 ) ) { // previous request zero fill 1283 naddr = cmemalignNoStats( nalign, 1, size ); // create new aligned area 1284 } else { 1285 naddr = memalignNoStats( nalign, size ); // create new aligned area 1286 } // if 1302 1287 1303 1288 headers( "realloc", naddr, header, freeElem, bsize, oalign );
Note:
See TracChangeset
for help on using the changeset viewer.