Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/heap.cfa

    rb5ce31e r7b149bc  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 23 14:13:13 2019
    13 // Update Count     : 549
     12// Last Modified On : Thu May  9 16:29:12 2019
     13// Update Count     : 516
    1414//
    1515
     
    3131
    3232
     33enum {
     34        __CFA_DEFAULT_MMAP_START__ = (512 * 1024 + 1),
     35        __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024),
     36};
     37
     38size_t default_mmap_start() __attribute__(( weak )) {
     39        return __CFA_DEFAULT_MMAP_START__;
     40} // default_mmap_start
     41
     42size_t default_heap_expansion() __attribute__(( weak )) {
     43        return __CFA_DEFAULT_HEAP_EXPANSION__;
     44} // default_heap_expansion
     45
     46
     47// supported mallopt options
     48#ifndef M_MMAP_THRESHOLD
     49#define M_MMAP_THRESHOLD (-1)
     50#endif // M_TOP_PAD
     51#ifndef M_TOP_PAD
     52#define M_TOP_PAD (-2)
     53#endif // M_TOP_PAD
     54
     55#define FASTLOOKUP
     56#define __STATISTICS__
     57
     58#define SPINLOCK 0
     59#define LOCKFREE 1
     60#define BUCKETLOCK SPINLOCK
     61#if BUCKETLOCK == LOCKFREE
     62#include <uStackLF.h>
     63#endif // LOCKFREE
     64
     65// #comment TD : This defined is significantly different from the __ALIGN__ define from locks.hfa
     66#define ALIGN 16
     67
     68// enum { NoBucketSizes = 93,                                                           // number of buckets sizes
     69// #ifdef FASTLOOKUP
     70//         LookupSizes = 65536,                                                         // number of fast lookup sizes
     71// #endif // FASTLOOKUP
     72// };
     73#define NoBucketSizes 93                                                                // number of buckets sizes
     74#ifdef FASTLOOKUP
     75#define LookupSizes 65536                                                               // number of fast lookup sizes
     76#endif // FASTLOOKUP
     77
     78
    3379static bool traceHeap = false;
    3480
     
    86132//      return temp;
    87133// } // traceHeapTermOff
    88 
    89 
    90 enum {
    91         __CFA_DEFAULT_MMAP_START__ = (512 * 1024 + 1),
    92         __CFA_DEFAULT_HEAP_EXPANSION__ = (1 * 1024 * 1024),
    93 };
    94 
    95 size_t default_mmap_start() __attribute__(( weak )) {
    96         return __CFA_DEFAULT_MMAP_START__;
    97 } // default_mmap_start
    98 
    99 size_t default_heap_expansion() __attribute__(( weak )) {
    100         return __CFA_DEFAULT_HEAP_EXPANSION__;
    101 } // default_heap_expansion
    102134
    103135
     
    128160#endif // __CFA_DEBUG__
    129161
    130 // statically allocated variables => zero filled.
    131 static size_t pageSize;                                                                 // architecture pagesize
    132 static size_t heapExpand;                                                               // sbrk advance
    133 static size_t mmapStart;                                                                // cross over point for mmap
    134 static unsigned int maxBucketsUsed;                                             // maximum number of buckets in use
    135 
    136 
    137 // #comment TD : This defined is significantly different from the __ALIGN__ define from locks.hfa
    138 #define ALIGN 16
    139 
    140 #define SPINLOCK 0
    141 #define LOCKFREE 1
    142 #define BUCKETLOCK SPINLOCK
    143 #if BUCKETLOCK == LOCKFREE
    144 #include <uStackLF.h>
    145 #endif // LOCKFREE
    146 
    147 // Recursive definitions: HeapManager needs size of bucket array and bucket area needs sizeof HeapManager storage.
    148 // Break recusion by hardcoding number of buckets and statically checking number is correct after bucket array defined.
    149 enum { NoBucketSizes = 93 };                                                    // number of buckets sizes
    150162
    151163struct HeapManager {
     
    222234}; // HeapManager
    223235
     236
    224237static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; }
    225238
    226 
    227 #define FASTLOOKUP
    228 #define __STATISTICS__
     239// statically allocated variables => zero filled.
     240static size_t pageSize;                                                                 // architecture pagesize
     241static size_t heapExpand;                                                               // sbrk advance
     242static size_t mmapStart;                                                                // cross over point for mmap
     243static unsigned int maxBucketsUsed;                                             // maximum number of buckets in use
    229244
    230245// Powers of 2 are common allocation sizes, so make powers of 2 generate the minimum required size.
    231 static const unsigned int bucketSizes[] @= {                    // different bucket sizes
     246static const unsigned int bucketSizes[NoBucketSizes] @= { // different bucket sizes
    232247        16, 32, 48, 64,
    233248        64 + sizeof(HeapManager.Storage), 96, 112, 128, 128 + sizeof(HeapManager.Storage), 160, 192, 224,
     
    244259        4_194_304 + sizeof(HeapManager.Storage)
    245260};
    246 
    247 static_assert( NoBucketSizes == sizeof(bucketSizes) / sizeof(bucketSizes[0]), "size of bucket array wrong" );
    248 
    249261#ifdef FASTLOOKUP
    250 static_assert( 16 == sizeof(HeapManager.Storage), "size of HeapManager Storage wrong" ); // FIX ME
    251 enum { LookupSizes = 65_536 + 16 };                                             // number of fast lookup sizes
    252262static unsigned char lookup[LookupSizes];                               // O(1) lookup for small sizes
    253263#endif // FASTLOOKUP
     
    522532
    523533
    524 size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) {
    525         size_t l = 0, m, h = dim;
    526         while ( l < h ) {
    527                 m = (l + h) / 2;
    528                 if ( (unsigned int &)(vals[m]) < key ) {                // cast away const
    529                         l = m + 1;
    530                 } else {
    531                         h = m;
    532                 } // if
    533         } // while
    534         return l;
    535 } // Bsearchl
    536 
    537 
    538534static inline void * doMalloc( size_t size ) with ( heapManager ) {
    539535        HeapManager.Storage * block;                                            // pointer to new block of storage
     
    544540        size_t tsize = size + sizeof(HeapManager.Storage);
    545541        if ( likely( tsize < mmapStart ) ) {                            // small size => sbrk
    546                 size_t posn;
    547                 #ifdef FASTLOOKUP
    548                 if ( tsize < LookupSizes ) posn = lookup[tsize];
    549                 else
    550                 #endif // FASTLOOKUP
    551                         posn = Bsearchl( (unsigned int)tsize, bucketSizes, (size_t)maxBucketsUsed );
    552                 HeapManager.FreeHeader * freeElem = &freeLists[posn];
    553                 // #ifdef FASTLOOKUP
    554                 // if ( tsize < LookupSizes )
    555                 //      freeElem = &freeLists[lookup[tsize]];
    556                 // else
    557                 // #endif // FASTLOOKUP
    558                 //      freeElem = bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search
    559                 // HeapManager.FreeHeader * freeElem =
    560                 //      #ifdef FASTLOOKUP
    561                 //      tsize < LookupSizes ? &freeLists[lookup[tsize]] :
    562                 //      #endif // FASTLOOKUP
    563                 //      bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search
     542                HeapManager.FreeHeader * freeElem =
     543                        #ifdef FASTLOOKUP
     544                        tsize < LookupSizes ? &freeLists[lookup[tsize]] :
     545                        #endif // FASTLOOKUP
     546                        bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search
    564547                assert( freeElem <= &freeLists[maxBucketsUsed] ); // subscripting error ?
    565548                assert( tsize <= freeElem->blockSize );                 // search failure ?
     
    764747
    765748
    766 // supported mallopt options
    767 #ifndef M_MMAP_THRESHOLD
    768 #define M_MMAP_THRESHOLD (-1)
    769 #endif // M_TOP_PAD
    770 #ifndef M_TOP_PAD
    771 #define M_TOP_PAD (-2)
    772 #endif // M_TOP_PAD
    773 
    774 
    775749extern "C" {
    776750        // The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not
     
    869843                void * area;
    870844                if ( unlikely( alignment != 0 ) ) {                             // previous request memalign?
    871                         area = memalign( alignment, size );                     // create new aligned area
     845                        area = memalign( alignment, size );                     // create new area
    872846                } else {
    873847                        area = mallocNoStats( size );                           // create new area
Note: See TracChangeset for help on using the changeset viewer.