Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    rdd23e66 rd5d3a90  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug  5 22:21:27 2020
    13 // Update Count     : 853
     12// Last Modified On : Mon Aug  3 19:01:22 2020
     13// Update Count     : 828
    1414//
    1515
     
    8080};
    8181
     82size_t default_heap_expansion() __attribute__(( weak )) {
     83        return __CFA_DEFAULT_HEAP_EXPANSION__;
     84} // default_heap_expansion
     85
    8286size_t default_mmap_start() __attribute__(( weak )) {
    8387        return __CFA_DEFAULT_MMAP_START__;
    8488} // default_mmap_start
    85 
    86 size_t default_heap_expansion() __attribute__(( weak )) {
    87         return __CFA_DEFAULT_HEAP_EXPANSION__;
    88 } // default_heap_expansion
    89 
    90 bool default_heap_exhausted() __attribute__(( weak )) { // find and free some storage
    91         // Returning false prints "out of heap memory" message and aborts.
    92         return false;
    93 } // default_heap_exhausted
    9489
    9590
     
    478473} // headers
    479474
    480 #define NO_MEMORY_MSG "no heap memory available for allocating %zd new bytes."
    481475
    482476static inline void * extend( size_t size ) with( heapManager ) {
     
    487481
    488482                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 ) {
    495484                        unlock( extlock );
    496                         abort( NO_MEMORY_MSG, size );                           // give up
    497                 }
     485                        errno = ENOMEM;
     486//                      return 0p;
     487                        abort( "no memory" );
     488                } // if
    498489                #ifdef __STATISTICS__
    499490                sbrk_calls += 1;
     
    563554
    564555                        block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call
     556//      if ( unlikely( block == 0p ) ) return 0p;
    565557                #if BUCKETLOCK == SPINLOCK
    566558                } else {
     
    578570                __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST );
    579571                #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 ) {
    589574                        // Do not call strerror( errno ) as it may call malloc.
    590575                        abort( "(HeapManager &)0x%p.doMalloc() : internal error, mmap failure, size:%zu error:%d.", &heapManager, tsize, errno );
    591                 }
     576                } // if
    592577                #ifdef __CFA_DEBUG__
    593578                // Set new memory to garbage so subsequent uninitialized usages might fail.
     
    766751static inline void * mallocNoStats( size_t size ) {             // necessary for malloc statistics
    767752        verify( heapManager.heapBegin != 0 );                           // called before memory_startup ?
    768   if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
     753  if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
    769754
    770755#if __SIZEOF_POINTER__ == 8
     
    777762static inline void * callocNoStats( size_t dim, size_t elemSize ) {
    778763        size_t size = dim * elemSize;
    779   if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
     764  if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
    780765        char * addr = (char *)mallocNoStats( size );
    781766
     
    788773                headers( "calloc", addr, header, freeElem, bsize, alignment );
    789774        #ifndef __CFA_DEBUG__
    790 
    791775        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    792776        if ( ! mapped )
     
    802786
    803787static 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 POINTER
     788  if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
    805789
    806790        #ifdef __CFA_DEBUG__
     
    841825static inline void * cmemalignNoStats( size_t alignment, size_t dim, size_t elemSize ) {
    842826        size_t size = dim * elemSize;
    843   if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
     827  if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
    844828        char * addr = (char *)memalignNoStats( alignment, size );
    845829
     
    847831        HeapManager.FreeHeader * freeElem;
    848832        size_t bsize;
     833        bool mapped __attribute__(( unused )) = headers( "cmemalign", addr, header, freeElem, bsize, alignment );
    849834        #ifndef __CFA_DEBUG__
    850         bool mapped =
    851         #endif // __CFA_DEBUG__
    852                 headers( "cmemalign", addr, header, freeElem, bsize, alignment );
    853         #ifndef __CFA_DEBUG__
    854 
    855835        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    856836        if ( ! mapped )
    857837        #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
    861839
    862840        header->kind.real.blockSize |= 2;                                       // mark as zero filled
     
    11571135
    11581136                headers( "malloc_usable_size", addr, header, freeElem, bsize, alignment );
    1159                 return dataStorage( bsize, addr, header );              // data storage in bucket
     1137                return dataStorage( bsize, addr, header );      // data storage in bucket
    11601138        } // malloc_usable_size
    11611139
     
    12551233                if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    12561234                        header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1257                         header->kind.real.size = size;                          // reset allocation size
     1235                        if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    12581236                        return oaddr;
    12591237                } // if
    12601238        } // if
    12611239
    1262         // change size, DO NOT preserve STICKY PROPERTIES.
     1240        // change size
     1241
     1242        void * naddr = memalignNoStats( nalign, size );         // create new aligned area
    12631243        free( oaddr );
    1264         return memalignNoStats( nalign, size );                         // create new aligned area
     1244        return naddr;
    12651245} // resize
    12661246
     
    12921272        #endif // __STATISTICS__
    12931273
     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
    12941277        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    12951278  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    12961279  if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
    12971280
    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
    13021287
    13031288        headers( "realloc", naddr, header, freeElem, bsize, oalign );
Note: See TracChangeset for help on using the changeset viewer.