Changeset dd23e66


Ignore:
Timestamp:
Aug 5, 2020, 11:17:08 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
74cfe054
Parents:
5727c23
Message:

add default_heap_exhausted, update resize/realloc with alignment, fix cmemalignNoStats to match callocNoStats

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    r5727c23 rdd23e66  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug  3 19:01:22 2020
    13 // Update Count     : 828
     12// Last Modified On : Wed Aug  5 22:21:27 2020
     13// Update Count     : 853
    1414//
    1515
     
    8080};
    8181
     82size_t default_mmap_start() __attribute__(( weak )) {
     83        return __CFA_DEFAULT_MMAP_START__;
     84} // default_mmap_start
     85
    8286size_t default_heap_expansion() __attribute__(( weak )) {
    8387        return __CFA_DEFAULT_HEAP_EXPANSION__;
    8488} // default_heap_expansion
    8589
    86 size_t default_mmap_start() __attribute__(( weak )) {
    87         return __CFA_DEFAULT_MMAP_START__;
    88 } // default_mmap_start
     90bool 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
    8994
    9095
     
    473478} // headers
    474479
     480#define NO_MEMORY_MSG "no heap memory available for allocating %zd new bytes."
    475481
    476482static inline void * extend( size_t size ) with( heapManager ) {
     
    481487
    482488                size_t increase = libCeiling( size > heapExpand ? size : heapExpand, libAlign() );
    483                 if ( sbrk( increase ) == (void *)-1 ) {
     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
    484495                        unlock( extlock );
    485                         errno = ENOMEM;
    486 //                      return 0p;
    487                         abort( "no memory" );
    488                 } // if
     496                        abort( NO_MEMORY_MSG, size );                           // give up
     497                }
    489498                #ifdef __STATISTICS__
    490499                sbrk_calls += 1;
     
    554563
    555564                        block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call
    556 //      if ( unlikely( block == 0p ) ) return 0p;
    557565                #if BUCKETLOCK == SPINLOCK
    558566                } else {
     
    570578                __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST );
    571579                #endif // __STATISTICS__
    572                 block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 );
    573                 if ( block == (HeapManager.Storage *)MAP_FAILED ) {
     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 );
    574589                        // Do not call strerror( errno ) as it may call malloc.
    575590                        abort( "(HeapManager &)0x%p.doMalloc() : internal error, mmap failure, size:%zu error:%d.", &heapManager, tsize, errno );
    576                 } // if
     591                }
    577592                #ifdef __CFA_DEBUG__
    578593                // Set new memory to garbage so subsequent uninitialized usages might fail.
     
    751766static inline void * mallocNoStats( size_t size ) {             // necessary for malloc statistics
    752767        verify( heapManager.heapBegin != 0 );                           // called before memory_startup ?
    753   if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
     768  if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
    754769
    755770#if __SIZEOF_POINTER__ == 8
     
    762777static inline void * callocNoStats( size_t dim, size_t elemSize ) {
    763778        size_t size = dim * elemSize;
    764   if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
     779  if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
    765780        char * addr = (char *)mallocNoStats( size );
    766781
     
    773788                headers( "calloc", addr, header, freeElem, bsize, alignment );
    774789        #ifndef __CFA_DEBUG__
     790
    775791        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    776792        if ( ! mapped )
     
    786802
    787803static inline void * memalignNoStats( size_t alignment, size_t size ) { // necessary for malloc statistics
    788   if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
     804  if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
    789805
    790806        #ifdef __CFA_DEBUG__
     
    825841static inline void * cmemalignNoStats( size_t alignment, size_t dim, size_t elemSize ) {
    826842        size_t size = dim * elemSize;
    827   if ( size == 0 ) return 0p;                                                   // 0 BYTE ALLOCATION RETURNS NULL POINTER
     843  if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
    828844        char * addr = (char *)memalignNoStats( alignment, size );
    829845
     
    831847        HeapManager.FreeHeader * freeElem;
    832848        size_t bsize;
    833         bool mapped __attribute__(( unused )) = headers( "cmemalign", addr, header, freeElem, bsize, alignment );
    834849        #ifndef __CFA_DEBUG__
     850        bool mapped =
     851        #endif // __CFA_DEBUG__
     852                headers( "cmemalign", addr, header, freeElem, bsize, alignment );
     853        #ifndef __CFA_DEBUG__
     854
    835855        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    836856        if ( ! mapped )
    837857        #endif // __CFA_DEBUG__
    838                 memset( addr, '\0', dataStorage( bsize, addr, header ) ); // set to zeros
     858                // <-------0000000000000000000000000000UUUUUUUUUUUUUUUUUUUUUUUUU> bsize (bucket size) U => undefined
     859                // `-header`-addr                      `-size
     860                memset( addr, '\0', size );                                             // set to zeros
    839861
    840862        header->kind.real.blockSize |= 2;                                       // mark as zero filled
     
    11351157
    11361158                headers( "malloc_usable_size", addr, header, freeElem, bsize, alignment );
    1137                 return dataStorage( bsize, addr, header );      // data storage in bucket
     1159                return dataStorage( bsize, addr, header );              // data storage in bucket
    11381160        } // malloc_usable_size
    11391161
     
    12331255                if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    12341256                        header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1235                         if ( size != odsize ) header->kind.real.size = size; // reset allocation size
     1257                        header->kind.real.size = size;                          // reset allocation size
    12361258                        return oaddr;
    12371259                } // if
    12381260        } // if
    12391261
    1240         // change size
    1241 
    1242         void * naddr = memalignNoStats( nalign, size );         // create new aligned area
     1262        // change size, DO NOT preserve STICKY PROPERTIES.
    12431263        free( oaddr );
    1244         return naddr;
     1264        return memalignNoStats( nalign, size );                         // create new aligned area
    12451265} // resize
    12461266
     
    12721292        #endif // __STATISTICS__
    12731293
    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 
    12771294        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    12781295  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    12791296  if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
    12801297
    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
     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
    12871302
    12881303        headers( "realloc", naddr, header, freeElem, bsize, oalign );
  • libcfa/src/heap.hfa

    r5727c23 rdd23e66  
    1010// Created On       : Tue May 26 11:23:55 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 20 18:52:31 2020
    13 // Update Count     : 11
     12// Last Modified On : Wed Aug  5 14:55:55 2020
     13// Update Count     : 14
    1414//
    1515
     
    1818size_t default_mmap_start();                                                    // CFA extras
    1919size_t default_heap_expansion();
     20bool default_heap_exhausted();                                                  // unsafe to call printf!
    2021
    2122bool traceHeap();
Note: See TracChangeset for help on using the changeset viewer.