Changeset 7d6e01d for libcfa/src


Ignore:
Timestamp:
May 19, 2020, 2:51:23 PM (4 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:
046a890, d47349b
Parents:
068a202 (diff), 7c38d53 (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 added
9 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r068a202 r7d6e01d  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Mar 16 18:07:59 2020
    14 ## Update Count     : 242
     13## Last Modified On : Sun May 17 21:10:26 2020
     14## Update Count     : 243
    1515###############################################################################
    1616
     
    3939#----------------------------------------------------------------------------------------------------------------
    4040if BUILDLIB
    41 headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
     41headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa clock.hfa \
     42                bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
    4243headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
    43           containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
     44                containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/stackLockFree.hfa containers/vector.hfa
    4445
    4546libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
  • libcfa/src/Makefile.in

    r068a202 r7d6e01d  
    240240        containers/maybe.hfa containers/pair.hfa containers/result.hfa \
    241241        containers/vector.hfa bitmanip.hfa math.hfa gmp.hfa time_t.hfa \
    242         bits/align.hfa bits/containers.hfa bits/defs.hfa \
     242        clock.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa \
    243243        bits/debug.hfa bits/locks.hfa containers/list.hfa \
    244244        concurrency/coroutine.hfa concurrency/thread.hfa \
     
    464464
    465465#----------------------------------------------------------------------------------------------------------------
    466 @BUILDLIB_TRUE@headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
     466@BUILDLIB_TRUE@headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa clock.hfa \
     467@BUILDLIB_TRUE@         bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
     468
    467469@BUILDLIB_FALSE@headers =
    468470@BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
    469 @BUILDLIB_TRUE@   containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
     471@BUILDLIB_TRUE@         containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
    470472
    471473@BUILDLIB_FALSE@libsrc =
  • libcfa/src/containers/list.hfa

    r068a202 r7d6e01d  
    301301                $prev_link(list_pos) = (Telem*) 0p;
    302302        }
     303
     304        static inline bool ?`is_empty(dlist(Tnode, Telem) &list) {
     305                assert( &list != 0p );
     306                $dlinks(Telem) *listLinks = & list.$links;
     307                if (listLinks->next.is_terminator) {
     308                        assert(listLinks->prev.is_terminator);
     309                        assert(listLinks->next.terminator);
     310                        assert(listLinks->prev.terminator);
     311                        return true;
     312                } else {
     313                        assert(!listLinks->prev.is_terminator);
     314                        assert(listLinks->next.elem);
     315                        assert(listLinks->prev.elem);
     316                        return false;
     317                }
     318        }
     319
     320        static inline Telem & pop_first(dlist(Tnode, Telem) &list) {
     321                assert( &list != 0p );
     322                assert( !list`is_empty );
     323                $dlinks(Telem) *listLinks = & list.$links;
     324                Telem & first = *listLinks->next.elem;
     325                Tnode & list_pos_first  = $tempcv_e2n( first );
     326                remove(list_pos_first);
     327                return first;
     328        }
     329
     330        static inline Telem & pop_last(dlist(Tnode, Telem) &list) {
     331                assert( &list != 0p );
     332                assert( !list`is_empty );
     333                $dlinks(Telem) *listLinks = & list.$links;
     334                Telem & last = *listLinks->prev.elem;
     335                Tnode & list_pos_last  = $tempcv_e2n( last );
     336                remove(list_pos_last);
     337                return last;
     338        }
     339
    303340}
    304341
  • libcfa/src/exception.c

    r068a202 r7d6e01d  
    223223
    224224// Cancel the current stack, prefroming approprate clean-up and messaging.
    225 static __attribute__((noreturn)) void __cfaehm_cancel_stack(
    226                 exception_t * exception ) {
     225void __cfaehm_cancel_stack( exception_t * exception ) {
    227226        // TODO: Detect current stack and pick a particular stop-function.
    228227        _Unwind_Reason_Code ret;
  • libcfa/src/exception.h

    r068a202 r7d6e01d  
    3838
    3939
     40void __cfaehm_cancel_stack(exception_t * except) __attribute__((noreturn));
     41
    4042// Used in throw statement translation.
    4143void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn));
  • libcfa/src/exception.hfa

    r068a202 r7d6e01d  
    1010// Created On       : Thu Apr  7 10:25:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Apr  7 10:25:00 2020
    13 // Update Count     : 0
     12// Last Modified On : Wed Apr 13 15:42:00 2020
     13// Update Count     : 1
    1414//
     15
     16trait is_exception(dtype T) {
     17        // The trait system can't describe the actual constrants.
     18        // Unused, should always be a no-op.
     19        void mark_exception(T *);
     20};
     21
     22forall(dtype T | is_exception(T))
     23inline void cancel_stack(T & except) __attribute__((noreturn)) {
     24        __cfaehm_cancel_stack( (exception_t *)&except );
     25}
    1526
    1627// Everything below this line should be considered a patch while the exception
     
    6980#define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
    7081        struct exception_name; \
     82        void mark_exception(exception_name *); \
    7183        VTABLE_TYPE(exception_name); \
    7284        extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
     
    8597#define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__)
    8698#define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
     99        void mark_exception(exception_name *) {} \
    87100        void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
    88101                *this = *other; \
  • libcfa/src/executor.cfa

    r068a202 r7d6e01d  
    44// buffer.
    55
    6 #include <bits/containers.hfa>
     6#include <containers/list.hfa>
    77#include <thread.hfa>
    88#include <stdio.h>
    99
    10 forall( dtype T )
    11 monitor Buffer {                                        // unbounded buffer
    12     __queue_t( T ) queue;                               // unbounded list of work requests
    13     condition delay;
    14 }; // Buffer
    15 forall( dtype T | is_node(T) ) {
    16     void insert( Buffer( T ) & mutex buf, T * elem ) with(buf) {
    17         append( queue, elem );                          // insert element into buffer
    18         signal( delay );                                // restart
    19     } // insert
    20 
    21     T * remove( Buffer( T ) & mutex buf ) with(buf) {
    22         if ( queue.head != 0 ) wait( delay );                   // no request to process ? => wait
    23 //      return pop_head( queue );
    24     } // remove
    25 } // distribution
    26 
    2710struct WRequest {                                       // client request, no return
    2811    void (* action)( void );
    29     WRequest * next;                                    // intrusive queue field
     12    DLISTED_MGD_IMPL_IN(WRequest)
    3013}; // WRequest
     14DLISTED_MGD_IMPL_OUT(WRequest)
    3115
    32 WRequest *& get_next( WRequest & this ) { return this.next; }
    33 void ?{}( WRequest & req ) with(req) { action = 0; next = 0; }
    34 void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; next = 0; }
     16void ?{}( WRequest & req ) with(req) { action = 0; }
     17void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; }
    3518bool stop( WRequest & req ) { return req.action == 0; }
    3619void doit( WRequest & req ) { req.action(); }
     20
     21monitor WRBuffer {                                      // unbounded buffer
     22    dlist( WRequest, WRequest ) queue;                  // unbounded list of work requests
     23    condition delay;
     24}; // WRBuffer
     25
     26void insert( WRBuffer & mutex buf, WRequest * elem ) with(buf) {
     27    insert_last( queue, *elem );                        // insert element into buffer
     28    signal( delay );                                    // restart
     29} // insert
     30
     31WRequest * remove( WRBuffer & mutex buf ) with(buf) {
     32    if ( queue`is_empty ) wait( delay );                // no request to process ? => wait
     33    return & pop_first( queue );
     34} // remove
    3735
    3836// Each worker has its own work buffer to reduce contention between client and server. Hence, work requests arrive and
     
    4038
    4139thread Worker {
    42     Buffer( WRequest ) * requests;
     40    WRBuffer * requests;
    4341    unsigned int start, range;
    4442}; // Worker
     
    5452} // Worker::main
    5553
    56 void ?{}( Worker & worker, cluster * wc, Buffer( WRequest ) * requests, unsigned int start, unsigned int range ) {
     54void ?{}( Worker & worker, cluster * wc, WRBuffer * requests, unsigned int start, unsigned int range ) {
    5755    (*get_thread(worker)){ *wc };                       // create on given cluster
    5856    worker.[requests, start, range] = [requests, start, range];
     
    6260    cluster * cluster;                                  // if workers execute on separate cluster
    6361    processor ** processors;                            // array of virtual processors adding parallelism for workers
    64     Buffer( WRequest ) * requests;                      // list of work requests
     62    WRBuffer * requests;                                // list of work requests
    6563    Worker ** workers;                                  // array of workers executing work requests
    6664    unsigned int nprocessors, nworkers, nmailboxes;     // number of mailboxes/workers/processor tasks
     
    7977    cluster = sepClus ? new( "Executor" ) : active_cluster();
    8078    processors = (processor **)anew( nprocessors );
    81     requests = anew( nmailboxes );
     79    requests = (WRBuffer *)anew( nmailboxes );
    8280    workers = (Worker **)anew( nworkers );
    8381
     
    141139        for ( i; 3000 ) {
    142140            send( exector, workie );
    143             if ( i % 100 ) yield();
     141            if ( i % 100 == 0 ) {
     142//              fprintf( stderr, "%d\n", i );
     143                yield();
     144            }
    144145        } // for
    145146    }
  • libcfa/src/heap.cfa

    r068a202 r7d6e01d  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May  6 17:29:26 2020
    13 // Update Count     : 727
     12// Last Modified On : Sun May 17 20:58:17 2020
     13// Update Count     : 762
    1414//
    1515
     
    128128#define LOCKFREE 1
    129129#define BUCKETLOCK SPINLOCK
    130 #if BUCKETLOCK == LOCKFREE
    131 #include <uStackLF.h>
     130#if BUCKETLOCK == SPINLOCK
     131#elif BUCKETLOCK == LOCKFREE
     132#include <stackLockFree.hfa>
     133#else
     134        #error undefined lock type for bucket lock
    132135#endif // LOCKFREE
    133136
     
    137140
    138141struct HeapManager {
    139 //      struct FreeHeader;                                                                      // forward declaration
    140 
    141142        struct Storage {
    142143                struct Header {                                                                 // header
     
    146147                                                struct {                                                // 4-byte word => 8-byte header, 8-byte word => 16-byte header
    147148                                                        #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4
    148                                                         uint32_t padding;                       // unused, force home/blocksize to overlay alignment in fake header
     149                                                        uint64_t padding;                       // unused, force home/blocksize to overlay alignment in fake header
    149150                                                        #endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4
    150151
    151152                                                        union {
    152 //                                                              FreeHeader * home;              // allocated block points back to home locations (must overlay alignment)
     153                                                                // FreeHeader * home;           // allocated block points back to home locations (must overlay alignment)
    153154                                                                // 2nd low-order bit => zero filled
    154155                                                                void * home;                    // allocated block points back to home locations (must overlay alignment)
    155156                                                                size_t blockSize;               // size for munmap (must overlay alignment)
    156                                                                 #if BUCKLOCK == SPINLOCK
     157                                                                #if BUCKETLOCK == SPINLOCK
    157158                                                                Storage * next;                 // freed block points next freed block of same size
    158159                                                                #endif // SPINLOCK
    159160                                                        };
     161                                                        size_t size;                            // allocation size in bytes
    160162
    161163                                                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4
    162                                                         uint32_t padding;                       // unused, force home/blocksize to overlay alignment in fake header
     164                                                        uint64_t padding;                       // unused, force home/blocksize to overlay alignment in fake header
    163165                                                        #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4
    164166                                                };
    165                                                 // future code
    166                                                 #if BUCKLOCK == LOCKFREE
    167                                                 Stack<Storage>::Link next;              // freed block points next freed block of same size (double-wide)
     167                                                #if BUCKETLOCK == LOCKFREE
     168                                                Link(Storage) next;                             // freed block points next freed block of same size (double-wide)
    168169                                                #endif // LOCKFREE
    169170                                        };
    170171                                } real; // RealHeader
     172
    171173                                struct FakeHeader {
    172174                                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    173                                         // 1st low-order bit => fake header & alignment
    174                                         uint32_t alignment;
     175                                        uint32_t alignment;                                     // 1st low-order bit => fake header & alignment
    175176                                        #endif // __ORDER_LITTLE_ENDIAN__
    176177
     
    182183                                } fake; // FakeHeader
    183184                        } kind; // Kind
    184                         size_t size;                                                            // allocation size in bytes
    185185                } header; // Header
    186186                char pad[libAlign() - sizeof( Header )];
     
    191191
    192192        struct FreeHeader {
    193                 #if BUCKLOCK == SPINLOCK
     193                #if BUCKETLOCK == SPINLOCK
    194194                __spinlock_t lock;                                                              // must be first field for alignment
    195195                Storage * freeList;
    196                 #elif BUCKLOCK == LOCKFREE
    197                 // future code
    198                 StackLF<Storage> freeList;
    199196                #else
    200                         #error undefined lock type for bucket lock
    201                 #endif // SPINLOCK
     197                StackLF(Storage) freeList;
     198                #endif // BUCKETLOCK
    202199                size_t blockSize;                                                               // size of allocations on this list
    203200        }; // FreeHeader
     
    211208        size_t heapRemaining;                                                           // amount of storage not allocated in the current chunk
    212209}; // HeapManager
     210
     211#if BUCKETLOCK == LOCKFREE
     212static inline Link(HeapManager.Storage) * getNext( HeapManager.Storage * this ) { return &this->header.kind.real.next; }
     213static inline void ?{}( HeapManager.FreeHeader & ) {}
     214static inline void ^?{}( HeapManager.FreeHeader & ) {}
     215#endif // LOCKFREE
    213216
    214217static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; }
     
    251254static bool heapBoot = 0;                                                               // detect recursion during boot
    252255#endif // __CFA_DEBUG__
     256
     257// The constructor for heapManager is called explicitly in memory_startup.
    253258static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing
    254259
     
    354359
    355360
    356 // static inline void noMemory() {
    357 //      abort( "Heap memory exhausted at %zu bytes.\n"
    358 //                 "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
    359 //                 ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
    360 // } // noMemory
    361 
    362 
    363361// thunk problem
    364362size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) {
     
    406404
    407405
     406// static inline void noMemory() {
     407//      abort( "Heap memory exhausted at %zu bytes.\n"
     408//                 "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
     409//                 ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
     410// } // noMemory
     411
     412
    408413static inline void checkAlign( size_t alignment ) {
    409414        if ( alignment < libAlign() || ! libPow2( alignment ) ) {
     
    433438
    434439
    435 static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
     440static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem,
     441                                                        size_t & size, size_t & alignment ) with( heapManager ) {
    436442        header = headerAddr( addr );
    437443
     
    465471
    466472
    467 static inline void * extend( size_t size ) with ( heapManager ) {
     473static inline void * extend( size_t size ) with( heapManager ) {
    468474        lock( extlock __cfaabi_dbg_ctx2 );
    469475        ptrdiff_t rem = heapRemaining - size;
     
    496502
    497503
    498 static inline void * doMalloc( size_t size ) with ( heapManager ) {
     504static inline void * doMalloc( size_t size ) with( heapManager ) {
    499505        HeapManager.Storage * block;                                            // pointer to new block of storage
    500506
     
    529535                // Spin until the lock is acquired for this particular size of block.
    530536
    531                 #if defined( SPINLOCK )
     537                #if BUCKETLOCK == SPINLOCK
    532538                lock( freeElem->lock __cfaabi_dbg_ctx2 );
    533539                block = freeElem->freeList;                                             // remove node from stack
    534540                #else
    535                 block = freeElem->freeList.pop();
    536                 #endif // SPINLOCK
     541                block = pop( freeElem->freeList );
     542                #endif // BUCKETLOCK
    537543                if ( unlikely( block == 0p ) ) {                                // no free block ?
    538                         #if defined( SPINLOCK )
     544                        #if BUCKETLOCK == SPINLOCK
    539545                        unlock( freeElem->lock );
    540                         #endif // SPINLOCK
     546                        #endif // BUCKETLOCK
    541547
    542548                        // Freelist for that size was empty, so carve it out of the heap if there's enough left, or get some more
     
    544550
    545551                        block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call
    546   if ( unlikely( block == 0p ) ) return 0p;
    547                 #if defined( SPINLOCK )
     552        if ( unlikely( block == 0p ) ) return 0p;
     553                #if BUCKETLOCK == SPINLOCK
    548554                } else {
    549555                        freeElem->freeList = block->header.kind.real.next;
    550556                        unlock( freeElem->lock );
    551                 #endif // SPINLOCK
     557                #endif // BUCKETLOCK
    552558                } // if
    553559
     
    572578        } // if
    573579
    574         block->header.size = size;                                                      // store allocation size
     580        block->header.kind.real.size = size;                            // store allocation size
    575581        void * addr = &(block->data);                                           // adjust off header to user bytes
    576582
     
    591597
    592598
    593 static inline void doFree( void * addr ) with ( heapManager ) {
     599static inline void doFree( void * addr ) with( heapManager ) {
    594600        #ifdef __CFA_DEBUG__
    595601        if ( unlikely( heapManager.heapBegin == 0p ) ) {
     
    623629                free_storage += size;
    624630                #endif // __STATISTICS__
    625                 #if defined( SPINLOCK )
     631                #if BUCKETLOCK == SPINLOCK
    626632                lock( freeElem->lock __cfaabi_dbg_ctx2 );               // acquire spin lock
    627633                header->kind.real.next = freeElem->freeList;    // push on stack
     
    629635                unlock( freeElem->lock );                                               // release spin lock
    630636                #else
    631                 freeElem->freeList.push( *(HeapManager.Storage *)header );
    632                 #endif // SPINLOCK
     637                push( freeElem->freeList, *(HeapManager.Storage *)header );
     638                #endif // BUCKETLOCK
    633639        } // if
    634640
     
    645651
    646652
    647 size_t prtFree( HeapManager & manager ) with ( manager ) {
     653size_t prtFree( HeapManager & manager ) with( manager ) {
    648654        size_t total = 0;
    649655        #ifdef __STATISTICS__
     
    657663                #endif // __STATISTICS__
    658664
    659                 #if defined( SPINLOCK )
     665                #if BUCKETLOCK == SPINLOCK
    660666                for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0p; p = p->header.kind.real.next ) {
    661667                #else
    662                 for ( HeapManager.Storage * p = freeLists[i].freeList.top(); p != 0p; p = p->header.kind.real.next.top ) {
    663                 #endif // SPINLOCK
     668                for ( HeapManager.Storage * p = top( freeLists[i].freeList ); p != 0p; /* p = getNext( p )->top */) {
     669                        typeof(p) temp = getNext( p )->top;                     // FIX ME: direct assignent fails, initialization works
     670                        p = temp;
     671                #endif // BUCKETLOCK
    664672                        total += size;
    665673                        #ifdef __STATISTICS__
     
    681689
    682690
    683 static void ?{}( HeapManager & manager ) with ( manager ) {
     691static void ?{}( HeapManager & manager ) with( manager ) {
    684692        pageSize = sysconf( _SC_PAGESIZE );
    685693
     
    10951103                        header = realHeader( header );                          // backup from fake to real header
    10961104                } // if
    1097                 return header->size;
     1105                return header->kind.real.size;
    10981106        } // malloc_size
    10991107
     
    11051113                        header = realHeader( header );                          // backup from fake to real header
    11061114                } // if
    1107                 size_t ret = header->size;
    1108                 header->size = size;
     1115                size_t ret = header->kind.real.size;
     1116                header->kind.real.size = size;
    11091117                return ret;
    11101118        } // $malloc_size_set
  • libcfa/src/stdlib.hfa

    r068a202 r7d6e01d  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 16 22:44:05 2020
    13 // Update Count     : 432
     12// Last Modified On : Wed May 13 17:23:51 2020
     13// Update Count     : 435
    1414//
    1515
     
    2323// Reduce includes by explicitly defining these routines.
    2424extern "C" {
     25        void * aalloc( size_t dim, size_t elemSize );           // CFA heap
     26        void * resize( void * oaddr, size_t size );                     // CFA heap
    2527        void * memalign( size_t align, size_t size );           // malloc.h
     28        void * amemalign( size_t align, size_t dim, size_t elemSize ); // CFA heap
     29        void * cmemalign( size_t align, size_t noOfElems, size_t elemSize ); // CFA heap
     30        size_t malloc_size( void * addr );                                      // CFA heap
    2631        size_t malloc_usable_size( void * ptr );                        // malloc.h
    27         size_t malloc_size( void * addr );                                      // CFA heap
    28         void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    2932        void * memset( void * dest, int fill, size_t size ); // string.h
    3033        void * memcpy( void * dest, const void * src, size_t size ); // string.h
    31         void * resize( void * oaddr, size_t size );                     // CFA heap
    3234} // extern "C"
    3335
     
    5254        } // malloc
    5355
     56        T * aalloc( size_t dim ) {
     57                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)aalloc( dim, (size_t)sizeof(T) ); // CFA aalloc
     58                else return (T *)amemalign( _Alignof(T), dim, sizeof(T) );
     59        } // aalloc
     60
    5461        T * calloc( size_t dim ) {
    5562                if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc
     
    5764        } // calloc
    5865
     66        T * resize( T * ptr, size_t size ) {                            // CFA realloc, eliminate return-type cast
     67                return (T *)(void *)resize( (void *)ptr, size ); // C realloc
     68        } // resize
     69
    5970        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    6071                return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
     
    6576        } // memalign
    6677
     78        T * amemalign( size_t align, size_t dim ) {
     79                return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign
     80        } // amemalign
     81
    6782        T * cmemalign( size_t align, size_t dim  ) {
    6883                return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign
     
    86101
    87102        T * alloc( size_t dim ) {
    88                 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( dim * (size_t)sizeof(T) );
    89                 else return (T *)memalign( _Alignof(T), dim * sizeof(T) );
     103                return aalloc( dim );
    90104        } // alloc
    91105
     
    106120                        return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
    107121                } else {
    108                         struct __Unknown {};
    109                         return alloc( (__Unknown *)ptr, dim );          // reuse, cheat making T/S different types
     122                        return resize( ptr, dim * sizeof(T) );          // resize
    110123                } // if
    111124        } // alloc
     
    148161        } // alloc_align
    149162
    150         T * alloc_align( T ptr[], size_t align ) {                      // aligned realloc array
     163        T * alloc_align( T * ptr, size_t align ) {                      // aligned realloc array
    151164                return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
    152165        } // alloc_align
Note: See TracChangeset for help on using the changeset viewer.