Changeset 8465b4d for libcfa/src


Ignore:
Timestamp:
Aug 10, 2020, 3:47:34 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
153d0f52
Parents:
1eb239e4 (diff), e2702fd (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r1eb239e4 r8465b4d  
    1919ACLOCAL_AMFLAGS  = -I automake
    2020
    21 include $(srcdir)/../../src/cfa.make
     21include $(top_srcdir)/../tools/build/cfa.make
    2222
    2323libdir = ${CFA_LIBDIR}
  • libcfa/src/bitmanip.hfa

    r1eb239e4 r8465b4d  
    1111// Created On       : Sat Mar 14 18:12:27 2020
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Tue Jun  9 15:14:04 2020
    14 // Update Count     : 123
     13// Last Modified On : Mon Aug 10 09:21:02 2020
     14// Update Count     : 139
    1515//
    1616
     
    2121// Bits are numbered 1-N.
    2222
    23 //#include <assert.h>
     23#include <assert.h>
    2424
    2525#define __bitsizeof( n ) (sizeof(n) * __CHAR_BIT__)
     
    8989
    9090        // Returns n aligned at the floor of align, clear bits above or equal to align, giving n % align.
    91         signed char floor2( signed char n, char align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    92         unsigned char floor2( unsigned char n, unsigned char align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    93         short int floor2( short int n, short int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    94         unsigned short int floor2( unsigned short int n, unsigned short int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    95         int floor2( int n, int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    96         unsigned int floor2( unsigned int n, unsigned int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    97         long int floor2( long int n, long int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    98         unsigned long int floor2( unsigned long int n, unsigned long int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    99         long long int floor2( long long int n, long long int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
    100         unsigned long long int floor2( unsigned long long int n, unsigned long long int align ) { /*assert( is_pow2( align ) );*/ return n & -align; }
     91        signed char floor2( signed char n, signed char align ) { verify( is_pow2( align ) ); return n & -align; }
     92        unsigned char floor2( unsigned char n, unsigned char align ) { verify( is_pow2( align ) ); return n & -align; }
     93        short int floor2( short int n, short int align ) { verify( is_pow2( align ) ); return n & -align; }
     94        unsigned short int floor2( unsigned short int n, unsigned short int align ) { verify( is_pow2( align ) ); return n & -align; }
     95        int floor2( int n, int align ) { verify( is_pow2( align ) ); return n & -align; }
     96        unsigned int floor2( unsigned int n, unsigned int align ) { verify( is_pow2( align ) ); return n & -align; }
     97        long int floor2( long int n, long int align ) { verify( is_pow2( align ) ); return n & -align; }
     98        unsigned long int floor2( unsigned long int n, unsigned long int align ) { verify( is_pow2( align ) ); return n & -align; }
     99        long long int floor2( long long int n, long long int align ) { verify( is_pow2( align ) ); return n & -align; }
     100        unsigned long long int floor2( unsigned long long int n, unsigned long long int align ) { verify( is_pow2( align ) ); return n & -align; }
    101101
    102102        // forall( otype T | { T ?&?( T, T ); T -?( T ); } )
    103         // T floor2( T n, T align ) { /* assert( is_pow2( align ) ); */ return n & -align; }
     103        // T floor2( T n, T align ) { verify( is_pow2( align ) ); return n & -align; }
    104104
    105         signed char floor( signed char n, char align ) { return n / align * align; }
     105        signed char floor( signed char n, signed char align ) { return n / align * align; }
    106106        unsigned char floor( unsigned char n, unsigned char align ) { return n / align * align; }
    107107        short int floor( short int n, short int align ) { return n / align * align; }
     
    118118
    119119        // Returns n aligned at the ceiling of align, negate, round down, negate is the same as round up.
    120         signed char ceiling2( signed char n, char align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    121         unsigned char ceiling2( unsigned char n, unsigned char align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    122         short int ceiling2( short int n, short int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    123         unsigned short int ceiling2( unsigned short int n, unsigned short int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    124         int ceiling2( int n, int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    125         unsigned int ceiling2( unsigned int n, unsigned int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    126         long int ceiling2( long int n, long int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    127         unsigned long int ceiling2( unsigned long int n, unsigned long int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    128         long long int ceiling2( long long int n, long long int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
    129         unsigned long long int ceiling2( unsigned long long int n, unsigned long long int align ) { /*assert( is_pow2( align ) );*/ return -floor2( -n, align ); }
     120        signed char ceiling2( signed char n, signed char align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     121        unsigned char ceiling2( unsigned char n, unsigned char align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     122        short int ceiling2( short int n, short int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     123        unsigned short int ceiling2( unsigned short int n, unsigned short int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     124        int ceiling2( int n, int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     125        unsigned int ceiling2( unsigned int n, unsigned int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     126        long int ceiling2( long int n, long int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     127        unsigned long int ceiling2( unsigned long int n, unsigned long int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     128        long long int ceiling2( long long int n, long long int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
     129        unsigned long long int ceiling2( unsigned long long int n, unsigned long long int align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
    130130
    131131        // forall( otype T | { T floor2( T, T ); T -?( T ); } )
    132         // T ceiling2( T n, T align ) { /* assert( is_pow2( align ) ); */ return -floor2( -n, align ); }
     132        // T ceiling2( T n, T align ) { verify( is_pow2( align ) ); return -floor2( -n, align ); }
    133133
    134         signed char ceiling( signed char n, char align ) { return (n + (align - 1)) / align; }
    135         unsigned char ceiling( unsigned char n, unsigned char align ) { return (n + (align - 1)) / align; }
    136         short int ceiling( short int n, short int align ) { return (n + (align - 1)) / align; }
    137         unsigned short int ceiling( unsigned short int n, unsigned short int align ) { return (n + (align - 1)) / align; }
    138         int ceiling( int n, int align ) { return (n + (align - 1)) / align; }
    139         unsigned int ceiling( unsigned int n, unsigned int align ) { return (n + (align - 1)) / align; }
    140         long int ceiling( long int n, long int align ) { return (n + (align - 1)) / align; }
    141         unsigned long int ceiling( unsigned long int n, unsigned long int align ) { return (n + (align - 1)) / align; }
    142         long long int ceiling( long long int n, long long int align ) { return (n + (align - 1)) / align; }
    143         unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1)) / align; }
     134        signed char ceiling_div( signed char n, char align ) { return (n + (align - 1)) / align; }
     135        unsigned char ceiling_div( unsigned char n, unsigned char align ) { return (n + (align - 1)) / align; }
     136        short int ceiling_div( short int n, short int align ) { return (n + (align - 1)) / align; }
     137        unsigned short int ceiling_div( unsigned short int n, unsigned short int align ) { return (n + (align - 1)) / align; }
     138        int ceiling_div( int n, int align ) { return (n + (align - 1)) / align; }
     139        unsigned int ceiling_div( unsigned int n, unsigned int align ) { return (n + (align - 1)) / align; }
     140        long int ceiling_div( long int n, long int align ) { return (n + (align - 1)) / align; }
     141        unsigned long int ceiling_div( unsigned long int n, unsigned long int align ) { return (n + (align - 1)) / align; }
     142        long long int ceiling_div( long long int n, long long int align ) { return (n + (align - 1)) / align; }
     143        unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1)) / align; }
     144
     145        // forall( otype T | { T ?+?( T, T ); T ?-?( T, T ); T ?%?( T, T ); } )
     146        // T ceiling_div( T n, T align ) { verify( is_pow2( align ) );return (n + (align - 1)) / align; }
     147       
     148        // gcc notices the div/mod pair and saves both so only one div.
     149        signed char ceiling( signed char n, signed char align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     150        unsigned char ceiling( unsigned char n, unsigned char align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     151        short int ceiling( short int n, short int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     152        unsigned short int ceiling( unsigned short int n, unsigned short int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     153        int ceiling( int n, int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     154        unsigned int ceiling( unsigned int n, unsigned int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     155        long int ceiling( long int n, long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     156        unsigned long int ceiling( unsigned long int n, unsigned long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0) , align); }
     157        long long int ceiling( long long int n, long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
     158        unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    144159
    145160        // forall( otype T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T ); T ?/?( T, T ); } )
    146         // T ceiling( T n, T align ) { return (n + (align - (T){1})) / align; }
     161        // T ceiling( T n, T align ) { return return floor( n + (n % align != 0 ? align - 1 : 0), align ); *}
    147162} // distribution
    148163
  • libcfa/src/heap.cfa

    r1eb239e4 r8465b4d  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // heap.c --
     7// heap.cfa --
    88//
    99// Author           : Peter A. Buhr
    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 : Sun Aug  9 12:23:20 2020
     13// Update Count     : 894
    1414//
    1515
     
    2323#include <sys/mman.h>                                                                   // mmap, munmap
    2424
    25 #include "bits/align.hfa"                                                               // libPow2
     25#include "bits/align.hfa"                                                               // libAlign
    2626#include "bits/defs.hfa"                                                                // likely, unlikely
    2727#include "bits/locks.hfa"                                                               // __spinlock_t
     
    8888} // default_heap_expansion
    8989
    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
    94 
    9590
    9691#ifdef __CFA_DEBUG__
    97 static unsigned int allocFree;                                                  // running total of allocations minus frees
     92static size_t allocUnfreed;                                                             // running total of allocations minus frees
    9893
    9994static void prtUnfreed() {
    100         if ( allocFree != 0 ) {
     95        if ( allocUnfreed != 0 ) {
    10196                // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.
    10297                char helpText[512];
    103                 int len = snprintf( helpText, sizeof(helpText), "CFA warning (UNIX pid:%ld) : program terminating with %u(0x%x) bytes of storage allocated but not freed.\n"
     98                int len = snprintf( helpText, sizeof(helpText), "CFA warning (UNIX pid:%ld) : program terminating with %zu(0x%zx) bytes of storage allocated but not freed.\n"
    10499                                                        "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n",
    105                                                         (long int)getpid(), allocFree, allocFree ); // always print the UNIX pid
     100                                                        (long int)getpid(), allocUnfreed, allocUnfreed ); // always print the UNIX pid
    106101                __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug
    107102        } // if
     
    110105extern "C" {
    111106        void heapAppStart() {                                                           // called by __cfaabi_appready_startup
    112                 allocFree = 0;
     107                allocUnfreed = 0;
    113108        } // heapAppStart
    114109
     
    226221#define __STATISTICS__
    227222
    228 // Bucket size must be multiple of 16.
     223// Size of array must harmonize with NoBucketSizes and individual bucket sizes must be multiple of 16.
    229224// Smaller multiples of 16 and powers of 2 are common allocation sizes, so make them generate the minimum required bucket size.
    230225// malloc(0) returns 0p, so no bucket is necessary for 0 bytes returning an address that can be freed.
     
    249244};
    250245
    251 static_assert( NoBucketSizes == sizeof(bucketSizes) / sizeof(bucketSizes[0]), "size of bucket array wrong" );
     246static_assert( NoBucketSizes == sizeof(bucketSizes) / sizeof(bucketSizes[0] ), "size of bucket array wrong" );
    252247
    253248#ifdef FASTLOOKUP
     
    267262#ifdef __STATISTICS__
    268263// Heap statistics counters.
     264static unsigned int malloc_calls;
     265static unsigned long long int malloc_storage;
     266static unsigned int aalloc_calls;
     267static unsigned long long int aalloc_storage;
     268static unsigned int calloc_calls;
     269static unsigned long long int calloc_storage;
     270static unsigned int memalign_calls;
     271static unsigned long long int memalign_storage;
     272static unsigned int amemalign_calls;
     273static unsigned long long int amemalign_storage;
     274static unsigned int cmemalign_calls;
     275static unsigned long long int cmemalign_storage;
     276static unsigned int resize_calls;
     277static unsigned long long int resize_storage;
     278static unsigned int realloc_calls;
     279static unsigned long long int realloc_storage;
     280static unsigned int free_calls;
     281static unsigned long long int free_storage;
     282static unsigned int mmap_calls;
    269283static unsigned long long int mmap_storage;
    270 static unsigned int mmap_calls;
     284static unsigned int munmap_calls;
    271285static unsigned long long int munmap_storage;
    272 static unsigned int munmap_calls;
     286static unsigned int sbrk_calls;
    273287static unsigned long long int sbrk_storage;
    274 static unsigned int sbrk_calls;
    275 static unsigned long long int malloc_storage;
    276 static unsigned int malloc_calls;
    277 static unsigned long long int free_storage;
    278 static unsigned int free_calls;
    279 static unsigned long long int aalloc_storage;
    280 static unsigned int aalloc_calls;
    281 static unsigned long long int calloc_storage;
    282 static unsigned int calloc_calls;
    283 static unsigned long long int memalign_storage;
    284 static unsigned int memalign_calls;
    285 static unsigned long long int amemalign_storage;
    286 static unsigned int amemalign_calls;
    287 static unsigned long long int cmemalign_storage;
    288 static unsigned int cmemalign_calls;
    289 static unsigned long long int resize_storage;
    290 static unsigned int resize_calls;
    291 static unsigned long long int realloc_storage;
    292 static unsigned int realloc_calls;
    293288// Statistics file descriptor (changed by malloc_stats_fd).
    294 static int statfd = STDERR_FILENO;                                              // default stderr
     289static int stat_fd = STDERR_FILENO;                                             // default stderr
    295290
    296291// Use "write" because streams may be shutdown when calls are made.
     
    312307                                                                        "  sbrk: calls %u / storage %llu\n",
    313308                                                                        malloc_calls, malloc_storage,
    314                                                                         aalloc_calls, calloc_storage,
     309                                                                        aalloc_calls, aalloc_storage,
    315310                                                                        calloc_calls, calloc_storage,
    316311                                                                        memalign_calls, memalign_storage,
     
    410405
    411406
    412 // static inline void noMemory() {
    413 //      abort( "Heap memory exhausted at %zu bytes.\n"
    414 //                 "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
    415 //                 ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
    416 // } // noMemory
    417 
    418 
    419407static inline void checkAlign( size_t alignment ) {
    420         if ( alignment < libAlign() || ! libPow2( alignment ) ) {
     408        if ( alignment < libAlign() || ! is_pow2( alignment ) ) {
    421409                abort( "Alignment %zu for memory allocation is less than %d and/or not a power of 2.", alignment, libAlign() );
    422410        } // if
     
    441429                header = realHeader( header );                                  // backup from fake to real header
    442430        } else {
    443                 alignment = 0;
     431                alignment = libAlign();                                                 // => no fake header
    444432        } // if
    445433} // fakeHeader
     
    450438        header = headerAddr( addr );
    451439
    452         if ( unlikely( heapEnd < addr ) ) {                                     // mmapped ?
     440  if ( unlikely( heapEnd < addr ) ) {                                   // mmapped ?
    453441                fakeHeader( header, alignment );
    454442                size = header->kind.real.blockSize & -3;                // mmap size
     
    478466} // headers
    479467
    480 #define NO_MEMORY_MSG "no heap memory available for allocating %zd new bytes."
     468#define NO_MEMORY_MSG "insufficient heap memory available for allocating %zd new bytes."
    481469
    482470static inline void * extend( size_t size ) with( heapManager ) {
     
    486474                // If the size requested is bigger than the current remaining storage, increase the size of the heap.
    487475
    488                 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
     476                size_t increase = ceiling2( size > heapExpand ? size : heapExpand, libAlign() );
     477                if ( sbrk( increase ) == (void *)-1 ) {                 // failed, no memory ?
    495478                        unlock( extlock );
    496479                        abort( NO_MEMORY_MSG, size );                           // give up
    497                 }
     480                } // if
    498481                #ifdef __STATISTICS__
    499482                sbrk_calls += 1;
     
    531514                        posn = Bsearchl( (unsigned int)tsize, bucketSizes, (size_t)maxBucketsUsed );
    532515                HeapManager.FreeHeader * freeElem = &freeLists[posn];
    533                 // #ifdef FASTLOOKUP
    534                 // if ( tsize < LookupSizes )
    535                 //      freeElem = &freeLists[lookup[tsize]];
    536                 // else
    537                 // #endif // FASTLOOKUP
    538                 //      freeElem = bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search
    539                 // HeapManager.FreeHeader * freeElem =
    540                 //      #ifdef FASTLOOKUP
    541                 //      tsize < LookupSizes ? &freeLists[lookup[tsize]] :
    542                 //      #endif // FASTLOOKUP
    543                 //      bsearchl( tsize, freeLists, (size_t)maxBucketsUsed ); // binary search
    544                 assert( freeElem <= &freeLists[maxBucketsUsed] ); // subscripting error ?
    545                 assert( tsize <= freeElem->blockSize );                 // search failure ?
     516                verify( freeElem <= &freeLists[maxBucketsUsed] ); // subscripting error ?
     517                verify( tsize <= freeElem->blockSize );                 // search failure ?
    546518                tsize = freeElem->blockSize;                                    // total space needed for request
    547519
     
    573545        } else {                                                                                        // large size => mmap
    574546  if ( unlikely( size > ULONG_MAX - pageSize ) ) return 0p;
    575                 tsize = libCeiling( tsize, pageSize );                  // must be multiple of page size
     547                tsize = ceiling2( tsize, pageSize );                    // must be multiple of page size
    576548                #ifdef __STATISTICS__
    577549                __atomic_add_fetch( &mmap_calls, 1, __ATOMIC_SEQ_CST );
    578550                __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST );
    579551                #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 );
     552
     553                block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 );
     554                if ( block == (HeapManager.Storage *)MAP_FAILED ) { // failed ?
     555                        if ( errno == ENOMEM ) abort( NO_MEMORY_MSG, tsize ); // no memory
    589556                        // Do not call strerror( errno ) as it may call malloc.
    590557                        abort( "(HeapManager &)0x%p.doMalloc() : internal error, mmap failure, size:%zu error:%d.", &heapManager, tsize, errno );
    591                 }
     558                } //if
    592559                #ifdef __CFA_DEBUG__
    593560                // Set new memory to garbage so subsequent uninitialized usages might fail.
     
    599566        block->header.kind.real.size = size;                            // store allocation size
    600567        void * addr = &(block->data);                                           // adjust off header to user bytes
     568        verify( ((uintptr_t)addr & (libAlign() - 1)) == 0 ); // minimum alignment ?
    601569
    602570        #ifdef __CFA_DEBUG__
    603         assert( ((uintptr_t)addr & (libAlign() - 1)) == 0 ); // minimum alignment ?
    604         __atomic_add_fetch( &allocFree, tsize, __ATOMIC_SEQ_CST );
     571        __atomic_add_fetch( &allocUnfreed, tsize, __ATOMIC_SEQ_CST );
    605572        if ( traceHeap() ) {
    606573                enum { BufferSize = 64 };
    607574                char helpText[BufferSize];
    608575                int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", addr, size, tsize );
    609                 // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", addr, size );
    610576                __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug
    611577        } // if
     
    659625
    660626        #ifdef __CFA_DEBUG__
    661         __atomic_add_fetch( &allocFree, -size, __ATOMIC_SEQ_CST );
     627        __atomic_add_fetch( &allocUnfreed, -size, __ATOMIC_SEQ_CST );
    662628        if ( traceHeap() ) {
    663                 enum { BufferSize = 64 };
    664                 char helpText[BufferSize];
     629                char helpText[64];
    665630                int len = snprintf( helpText, sizeof(helpText), "Free( %p ) size:%zu\n", addr, size );
    666631                __cfaabi_bits_write( STDERR_FILENO, helpText, len ); // print debug/nodebug
     
    685650                for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0p; p = p->header.kind.real.next ) {
    686651                #else
    687                 for ( HeapManager.Storage * p = top( freeLists[i].freeList ); p != 0p; /* p = getNext( p )->top */) {
    688                         typeof(p) temp = ( p )`next->top;                       // FIX ME: direct assignent fails, initialization works
    689                         p = temp;
     652                for ( HeapManager.Storage * p = top( freeLists[i].freeList ); p != 0p; p = (p)`next->top ) {
    690653                #endif // BUCKETLOCK
    691654                        total += size;
     
    729692
    730693        char * end = (char *)sbrk( 0 );
    731         heapBegin = heapEnd = sbrk( (char *)libCeiling( (long unsigned int)end, libAlign() ) - end ); // move start of heap to multiple of alignment
     694        heapBegin = heapEnd = sbrk( (char *)ceiling2( (long unsigned int)end, libAlign() ) - end ); // move start of heap to multiple of alignment
    732695} // HeapManager
    733696
     
    737700        if ( traceHeapTerm() ) {
    738701                printStats();
    739                 // if ( prtfree() ) prtFree( heapManager, true );
     702                // prtUnfreed() called in heapAppStop()
    740703        } // if
    741704        #endif // __STATISTICS__
     
    746709void memory_startup( void ) {
    747710        #ifdef __CFA_DEBUG__
    748         if ( unlikely( heapBoot ) ) {                                           // check for recursion during system boot
     711        if ( heapBoot ) {                                                                       // check for recursion during system boot
    749712                // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.
    750713                abort( "boot() : internal error, recursively invoked during system boot." );
     
    753716        #endif // __CFA_DEBUG__
    754717
    755         //assert( heapManager.heapBegin != 0 );
     718        //verify( heapManager.heapBegin != 0 );
    756719        //heapManager{};
    757720        if ( heapManager.heapBegin == 0p ) heapManager{};       // sanity check
     
    765728
    766729static inline void * mallocNoStats( size_t size ) {             // necessary for malloc statistics
    767         verify( heapManager.heapBegin != 0 );                           // called before memory_startup ?
     730        verify( heapManager.heapBegin != 0p );                          // called before memory_startup ?
    768731  if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
    769732
     
    801764
    802765
    803 static inline void * memalignNoStats( size_t alignment, size_t size ) { // necessary for malloc statistics
     766static inline void * memalignNoStats( size_t alignment, size_t size ) {
    804767  if ( unlikely( size ) == 0 ) return 0p;                               // 0 BYTE ALLOCATION RETURNS NULL POINTER
    805768
     
    823786
    824787        // address in the block of the "next" alignment address
    825         char * user = (char *)libCeiling( (uintptr_t)(addr + sizeof(HeapManager.Storage)), alignment );
     788        char * user = (char *)ceiling2( (uintptr_t)(addr + sizeof(HeapManager.Storage)), alignment );
    826789
    827790        // address of header from malloc
     
    851814        #endif // __CFA_DEBUG__
    852815                headers( "cmemalign", addr, header, freeElem, bsize, alignment );
     816
     817        // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    853818        #ifndef __CFA_DEBUG__
    854 
    855         // Mapped storage is zero filled, but in debug mode mapped memory is scrubbed in doMalloc, so it has to be reset to zero.
    856819        if ( ! mapped )
    857820        #endif // __CFA_DEBUG__
     
    865828
    866829
    867 // supported mallopt options
    868 #ifndef M_MMAP_THRESHOLD
    869 #define M_MMAP_THRESHOLD (-1)
    870 #endif // M_TOP_PAD
    871 #ifndef M_TOP_PAD
    872 #define M_TOP_PAD (-2)
    873 #endif // M_TOP_PAD
    874 
    875 
    876830extern "C" {
    877831        // Allocates size bytes and returns a pointer to the allocated memory.  The contents are undefined. If size is 0,
     
    889843        // Same as malloc() except size bytes is an array of dim elements each of elemSize bytes.
    890844        void * aalloc( size_t dim, size_t elemSize ) {
     845                size_t size = dim * elemSize;
    891846                #ifdef __STATISTICS__
    892847                __atomic_add_fetch( &aalloc_calls, 1, __ATOMIC_SEQ_CST );
    893                 __atomic_add_fetch( &aalloc_storage, dim * elemSize, __ATOMIC_SEQ_CST );
    894                 #endif // __STATISTICS__
    895 
    896                 return mallocNoStats( dim * elemSize );
     848                __atomic_add_fetch( &aalloc_storage, size, __ATOMIC_SEQ_CST );
     849                #endif // __STATISTICS__
     850
     851                return mallocNoStats( size );
    897852        } // aalloc
    898853
     
    907862                return callocNoStats( dim, elemSize );
    908863        } // calloc
     864
    909865
    910866        // Change the size of the memory block pointed to by oaddr to size bytes. The contents are undefined.  If oaddr is
     
    915871                #ifdef __STATISTICS__
    916872                __atomic_add_fetch( &resize_calls, 1, __ATOMIC_SEQ_CST );
    917                 __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    918873                #endif // __STATISTICS__
    919874
    920875                // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    921876          if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    922           if ( unlikely( oaddr == 0p ) ) return mallocNoStats( size );
     877          if ( unlikely( oaddr == 0p ) ) {
     878                        #ifdef __STATISTICS__
     879                        __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     880                        #endif // __STATISTICS__
     881                        return mallocNoStats( size );
     882                } // if
    923883
    924884                HeapManager.Storage.Header * header;
    925885                HeapManager.FreeHeader * freeElem;
    926                 size_t bsize, oalign = 0;
     886                size_t bsize, oalign;
    927887                headers( "resize", oaddr, header, freeElem, bsize, oalign );
    928888
    929889                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    930890                // same size, DO NOT preserve STICKY PROPERTIES.
    931           if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
     891                if ( oalign <= libAlign() && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    932892                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
    933893                        header->kind.real.size = size;                          // reset allocation size
    934894                        return oaddr;
    935895                } // if
     896
     897                #ifdef __STATISTICS__
     898                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     899                #endif // __STATISTICS__
    936900
    937901                // change size, DO NOT preserve STICKY PROPERTIES.
     
    946910                #ifdef __STATISTICS__
    947911                __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
    948                 __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    949912                #endif // __STATISTICS__
    950913
    951914                // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    952915          if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    953           if ( unlikely( oaddr == 0p ) ) return mallocNoStats( size );
     916          if ( unlikely( oaddr == 0p ) ) {
     917                        #ifdef __STATISTICS__
     918                        __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     919                        #endif // __STATISTICS__
     920                        return mallocNoStats( size );
     921                } // if
    954922
    955923                HeapManager.Storage.Header * header;
    956924                HeapManager.FreeHeader * freeElem;
    957                 size_t bsize, oalign = 0;
     925                size_t bsize, oalign;
    958926                headers( "realloc", oaddr, header, freeElem, bsize, oalign );
    959927
     
    969937                } // if
    970938
     939                #ifdef __STATISTICS__
     940                __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     941                #endif // __STATISTICS__
     942
    971943                // change size and copy old content to new storage
    972944
    973945                void * naddr;
    974                 if ( likely( oalign == 0 ) ) {                                  // previous request memalign?
     946                if ( likely( oalign <= libAlign() ) ) {                 // previous request not aligned ?
    975947                        naddr = mallocNoStats( size );                          // create new area
    976948                } else {
     
    991963        } // realloc
    992964
     965
    993966        // Same as malloc() except the memory address is a multiple of alignment, which must be a power of two. (obsolete)
    994967        void * memalign( size_t alignment, size_t size ) {
     
    1004977        // Same as aalloc() with memory alignment.
    1005978        void * amemalign( size_t alignment, size_t dim, size_t elemSize ) {
     979                size_t size = dim * elemSize;
    1006980                #ifdef __STATISTICS__
    1007981                __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
    1008                 __atomic_add_fetch( &cmemalign_storage, dim * elemSize, __ATOMIC_SEQ_CST );
    1009                 #endif // __STATISTICS__
    1010 
    1011                 return memalignNoStats( alignment, dim * elemSize );
     982                __atomic_add_fetch( &cmemalign_storage, size, __ATOMIC_SEQ_CST );
     983                #endif // __STATISTICS__
     984
     985                return memalignNoStats( alignment, size );
    1012986        } // amemalign
    1013987
     
    10351009        // free(3).
    10361010        int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
    1037           if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) return EINVAL; // check alignment
     1011          if ( alignment < libAlign() || ! is_pow2( alignment ) ) return EINVAL; // check alignment
    10381012                * memptr = memalign( alignment, size );
    10391013                return 0;
     
    10491023        // Same as valloc but rounds size to multiple of page size.
    10501024        void * pvalloc( size_t size ) {
    1051                 return memalign( pageSize, libCeiling( size, pageSize ) );
     1025                return memalign( pageSize, ceiling2( size, pageSize ) );
    10521026        } // pvalloc
    10531027
     
    10871061        } // malloc_alignment
    10881062
     1063
    10891064        // Set the alignment for an the allocation and return previous alignment or 0 if no alignment.
    10901065        size_t $malloc_alignment_set( void * addr, size_t alignment ) {
     
    11691144        } // malloc_stats
    11701145
     1146
    11711147        // Changes the file descripter where malloc_stats() writes statistics.
    11721148        int malloc_stats_fd( int fd __attribute__(( unused )) ) {
    11731149                #ifdef __STATISTICS__
    1174                 int temp = statfd;
    1175                 statfd = fd;
     1150                int temp = stat_fd;
     1151                stat_fd = fd;
    11761152                return temp;
    11771153                #else
     
    11941170        } // mallopt
    11951171
     1172
    11961173        // Attempt to release free memory at the top of the heap (by calling sbrk with a suitable argument).
    11971174        int malloc_trim( size_t ) {
     
    12041181        // malloc).
    12051182        int malloc_info( int options, FILE * stream ) {
    1206                 if ( options != 0 ) { errno = EINVAL; return -1; }
     1183          if ( options != 0 ) { errno = EINVAL; return -1; }
     1184                #ifdef __STATISTICS__
    12071185                return printStatsXML( stream );
     1186                #else
     1187                return 0;                                                                               // unsupported
     1188                #endif // __STATISTICS__
    12081189        } // malloc_info
    12091190
     
    12201201        // Restores the state of all malloc internal bookkeeping variables to the values recorded in the opaque data
    12211202        // structure pointed to by state.
    1222         int malloc_set_state( void * ptr ) {
     1203        int malloc_set_state( void * ) {
    12231204                return 0;                                                                               // unsupported
    12241205        } // malloc_set_state
     
    12301211        #ifdef __STATISTICS__
    12311212        __atomic_add_fetch( &resize_calls, 1, __ATOMIC_SEQ_CST );
    1232         __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    12331213        #endif // __STATISTICS__
    12341214
    12351215        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    12361216  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    1237   if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
    1238 
    1239         if ( unlikely( nalign == 0 ) ) nalign = libAlign();     // reset alignment to minimum
     1217  if ( unlikely( oaddr == 0p ) ) {
     1218                #ifdef __STATISTICS__
     1219                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     1220                #endif // __STATISTICS__
     1221                return memalignNoStats( nalign, size );
     1222        } // if
     1223
     1224        if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum
    12401225        #ifdef __CFA_DEBUG__
    12411226        else
     
    12451230        HeapManager.Storage.Header * header;
    12461231        HeapManager.FreeHeader * freeElem;
    1247         size_t bsize, oalign = 0;
     1232        size_t bsize, oalign;
    12481233        headers( "resize", oaddr, header, freeElem, bsize, oalign );
    12491234        size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    12501235
    12511236        if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
    1252                 if ( oalign >= libAlign() ) {                                   // fake header ?
     1237                if ( oalign > libAlign() ) {                                    // fake header ?
    12531238                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    12541239                } // if
     
    12601245        } // if
    12611246
     1247        #ifdef __STATISTICS__
     1248        __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     1249        #endif // __STATISTICS__
     1250
    12621251        // change size, DO NOT preserve STICKY PROPERTIES.
    12631252        free( oaddr );
     
    12671256
    12681257void * realloc( void * oaddr, size_t nalign, size_t size ) {
    1269         if ( unlikely( nalign == 0 ) ) nalign = libAlign();     // reset alignment to minimum
     1258        if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum
    12701259        #ifdef __CFA_DEBUG__
    12711260        else
     
    12751264        HeapManager.Storage.Header * header;
    12761265        HeapManager.FreeHeader * freeElem;
    1277         size_t bsize, oalign = 0;
     1266        size_t bsize, oalign;
    12781267        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
    12791268
    12801269        if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
    1281                 if ( oalign >= libAlign() ) {                                   // fake header ?
     1270                if ( oalign > libAlign() ) {                                    // fake header ?
    12821271                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    12831272                } // if
  • libcfa/src/heap.hfa

    r1eb239e4 r8465b4d  
    1010// Created On       : Tue May 26 11:23:55 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug  5 14:55:55 2020
    13 // Update Count     : 14
     12// Last Modified On : Sat Aug  8 17:36:48 2020
     13// Update Count     : 16
    1414//
    1515
     
    1818size_t default_mmap_start();                                                    // CFA extras
    1919size_t default_heap_expansion();
    20 bool default_heap_exhausted();                                                  // unsafe to call printf!
    2120
    2221bool traceHeap();
     
    3130bool checkFreeOn();
    3231bool checkFreeOff();
     32
     33// supported mallopt options
     34#ifndef M_MMAP_THRESHOLD
     35#define M_MMAP_THRESHOLD (-1)
     36#endif // M_TOP_PAD
     37#ifndef M_TOP_PAD
     38#define M_TOP_PAD (-2)
     39#endif // M_TOP_PAD
    3340
    3441extern "C" {
  • libcfa/src/iostream.cfa

    r1eb239e4 r8465b4d  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 20 15:00:37 2020
    13 // Update Count     : 1124
     12// Last Modified On : Mon Aug 10 09:32:14 2020
     13// Update Count     : 1126
    1414//
    1515
     
    615615                                                sepOff( os ); \
    616616                                                fmt2.flags.left = true; \
    617                                                 int msigd = ceiling( high1( fmt.val ), 3 ); \
     617                                                int msigd = ceiling_div( high1( fmt.val ), 3 ); \
    618618                                                fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
    619619                                                if ( ! fmt.flags.nobsdp ) fmt2.wd -= 1; /* compensate for 0 base specifier */ \
     
    704704                                        if ( f.base == 'd' && (f.flags.neg || f.flags.sign) ) bs = 1; // sign ?
    705705                                } else {
    706                                         dig = ceiling( high1( f.val ), bits );
     706                                        dig = ceiling_div( high1( f.val ), bits );
    707707                                        if ( ! f.flags.nobsdp ) {                       // base prefix ?
    708708                                                if ( f.base == 'o' ) {
Note: See TracChangeset for help on using the changeset viewer.