Changeset 7d6e01d


Ignore:
Timestamp:
May 19, 2020, 2:51:23 PM (3 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

Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • driver/cfa.cc

    r068a202 r7d6e01d  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jan 31 16:48:03 2020
    13 // Update Count     : 421
     12// Last Modified On : Mon May 18 13:26:26 2020
     13// Update Count     : 424
    1414//
    1515
     
    301301        } // for
    302302
    303         #ifdef __x86_64__
    304         args[nargs++] = "-mcx16";                                                       // allow double-wide CAA
    305         #endif // __x86_64__
    306 
    307303        #ifdef __DEBUG_H__
    308304        cerr << "args:";
     
    419415                args[nargs++] = "-lcfa";
    420416                args[nargs++] = "-Wl,--pop-state";
     417                #ifdef __x86_64__
     418                args[nargs++] = "-mcx16";                                               // allow double-wide CAS
     419                args[nargs++] = "-latomic";
     420                #endif // __x86_64__
    421421                args[nargs++] = "-pthread";
    422422                args[nargs++] = "-ldl";
  • 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
  • tests/list/.expect/dlist-insert-remove.txt

    r068a202 r7d6e01d  
    146414640.7
    14651465-
     1466
     1467~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~
     1468
     1469~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1470Test 16-i.  Modifying Freds on MINE
     1471~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1472==== fred by MINE before
     14731.7
     14742.7
     14753.7
     1476-
     14771.7
     1478-
     14793.7
     1480-
     14813.7
     14822.7
     14831.7
     1484-
     1485==== fred by YOURS before
     14861.7
     14872.7
     14883.7
     1489-
     14901.7
     1491-
     14923.7
     1493-
     14943.7
     14952.7
     14961.7
     1497-
     1498==== fred by MINE after
     14992.7
     15003.7
     1501-
     15022.7
     1503-
     15043.7
     1505-
     15063.7
     15072.7
     1508-
     1509==== fred by YOURS after
     15101.7
     15112.7
     15123.7
     1513-
     15141.7
     1515-
     15163.7
     1517-
     15183.7
     15192.7
     15201.7
     1521-
     1522==== fred by MINE after
     15231.7
     1524-
     15251.7
     1526-
     1527-
     1528-
     1529~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1530Test 16-ii.  Modifying Freds on YOURS
     1531~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1532==== fred by MINE before
     15331.7
     15342.7
     15353.7
     1536-
     15371.7
     1538-
     15393.7
     1540-
     15413.7
     15422.7
     15431.7
     1544-
     1545==== fred by YOURS before
     15461.7
     15472.7
     15483.7
     1549-
     15501.7
     1551-
     15523.7
     1553-
     15543.7
     15552.7
     15561.7
     1557-
     1558==== fred by MINE after
     15591.7
     15602.7
     15613.7
     1562-
     15631.7
     1564-
     15653.7
     1566-
     15673.7
     15682.7
     15691.7
     1570-
     1571==== fred by YOURS after
     15722.7
     15733.7
     1574-
     15752.7
     1576-
     15773.7
     1578-
     15793.7
     15802.7
     1581-
     1582==== fred by YOURS after
     15831.7
     1584-
     15851.7
     1586-
     1587-
     1588-
     1589~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1590Test 16-iii.  Modifying Maries
     1591~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1592==== mary before
     15931.7
     15942.7
     15953.7
     1596-
     15971.7
     1598-
     15993.7
     1600-
     16013.7
     16022.7
     16031.7
     1604-
     1605==== mary after
     16062.7
     16073.7
     1608-
     16092.7
     1610-
     16113.7
     1612-
     16133.7
     16142.7
     1615-
     1616==== mary after
     16171.7
     1618-
     16191.7
     1620-
     1621-
     1622-
     1623
     1624~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~
     1625
     1626~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1627Test 17-i.  Modifying Freds on MINE
     1628~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1629==== fred by MINE before
     16301.7
     16312.7
     16323.7
     1633-
     16341.7
     1635-
     16363.7
     1637-
     16383.7
     16392.7
     16401.7
     1641-
     1642==== fred by YOURS before
     16431.7
     16442.7
     16453.7
     1646-
     16471.7
     1648-
     16493.7
     1650-
     16513.7
     16522.7
     16531.7
     1654-
     1655==== fred by MINE after
     16561.7
     16572.7
     1658-
     16591.7
     1660-
     16612.7
     1662-
     16632.7
     16641.7
     1665-
     1666==== fred by YOURS after
     16671.7
     16682.7
     16693.7
     1670-
     16711.7
     1672-
     16733.7
     1674-
     16753.7
     16762.7
     16771.7
     1678-
     1679==== fred by MINE after
     16803.7
     1681-
     16823.7
     1683-
     1684-
     1685-
     1686~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1687Test 17-ii.  Modifying Freds on YOURS
     1688~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1689==== fred by MINE before
     16901.7
     16912.7
     16923.7
     1693-
     16941.7
     1695-
     16963.7
     1697-
     16983.7
     16992.7
     17001.7
     1701-
     1702==== fred by YOURS before
     17031.7
     17042.7
     17053.7
     1706-
     17071.7
     1708-
     17093.7
     1710-
     17113.7
     17122.7
     17131.7
     1714-
     1715==== fred by MINE after
     17161.7
     17172.7
     17183.7
     1719-
     17201.7
     1721-
     17223.7
     1723-
     17243.7
     17252.7
     17261.7
     1727-
     1728==== fred by YOURS after
     17291.7
     17302.7
     1731-
     17321.7
     1733-
     17342.7
     1735-
     17362.7
     17371.7
     1738-
     1739==== fred by YOURS after
     17403.7
     1741-
     17423.7
     1743-
     1744-
     1745-
     1746~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1747Test 17-iii.  Modifying Maries
     1748~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1749==== mary before
     17501.7
     17512.7
     17523.7
     1753-
     17541.7
     1755-
     17563.7
     1757-
     17583.7
     17592.7
     17601.7
     1761-
     1762==== mary after
     17631.7
     17642.7
     1765-
     17661.7
     1767-
     17682.7
     1769-
     17702.7
     17711.7
     1772-
     1773==== mary after
     17743.7
     1775-
     17763.7
     1777-
     1778-
     1779-
  • tests/list/dlist-insert-remove.cfa

    r068a202 r7d6e01d  
    11871187////////////////////////////////////////////////////////////
    11881188//
     1189// Section 4f
     1190//
     1191// Test cases of pop_first, pop_last
     1192//
     1193// Example of call-side user code
     1194//
     1195////////////////////////////////////////////////////////////
     1196
     1197// These cases assume element removal at first-last is correct
     1198
     1199void test__pop_first__fred_mine() {
     1200
     1201        fred f1 = {1.7};
     1202        fred f2 = {2.7};
     1203        fred f3 = {3.7};
     1204
     1205        dlist(fred_in_mine, fred) flm;
     1206        insert_last(flm, f1);
     1207        insert_last(flm, f2);
     1208        insert_last(flm, f3);
     1209
     1210        dlist(fred_in_yours, fred) fly;
     1211        insert_last(fly, f1);
     1212        insert_last(fly, f2);
     1213        insert_last(fly, f3);
     1214
     1215        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1216        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1217
     1218        verify(validate(fly));
     1219        verify(validate(flm));
     1220
     1221        fred & popped = pop_first(flm);
     1222
     1223        verify(validate(fly));
     1224        verify(validate(flm));
     1225
     1226        printMyFreddies(flm`first, flm`last, 0);     // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
     1227        printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1228
     1229        // observe f1 is now solo in mine; in yours, it was just traversed
     1230        printMyFreddies(f1, *0p, 0);    // 1.7; 1.7; ;
     1231
     1232        assert( &popped == & f1 );
     1233}
     1234
     1235void test__pop_first__fred_yours() {
     1236
     1237        fred f1 = {1.7};
     1238        fred f2 = {2.7};
     1239        fred f3 = {3.7};
     1240
     1241        dlist(fred_in_mine, fred) flm;
     1242        insert_last(flm, f1);
     1243        insert_last(flm, f2);
     1244        insert_last(flm, f3);
     1245
     1246        dlist(fred_in_yours, fred) fly;
     1247        insert_last(fly, f1);
     1248        insert_last(fly, f2);
     1249        insert_last(fly, f3);
     1250
     1251        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1252        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1253
     1254        verify(validate(fly));
     1255        verify(validate(flm));
     1256
     1257        fred & popped = pop_first(fly);
     1258
     1259        verify(validate(fly));
     1260        verify(validate(flm));
     1261
     1262        printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1263        printYourFreddies(fly`first, fly`last, 0);   // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
     1264
     1265        // observe f1 is now solo in yours; in mine, it was just traversed
     1266        printYourFreddies(f1, *0p, 0);    // 1.7; 1.7; ;
     1267
     1268        assert( &popped == &f1 );
     1269}
     1270
     1271void test__pop_first__maries() {
     1272
     1273        mary m1 = {1.7};
     1274        mary m2 = {2.7};
     1275        mary m3 = {3.7};
     1276
     1277        dlist(mary, mary) ml;
     1278        insert_last(ml, m1);
     1279        insert_last(ml, m2);
     1280        insert_last(ml, m3);
     1281
     1282        printMariatheotokos(ml`first, ml`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1283
     1284        verify(validate(ml));
     1285
     1286        mary & popped = pop_first(ml);
     1287
     1288        verify(validate(ml));
     1289
     1290        printMariatheotokos(ml`first, ml`last, 0);     // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
     1291
     1292        // observe m1 is now solo
     1293        printMariatheotokos(m1, *0p, 0);               // 1.7; 1.7; ;
     1294
     1295        assert( &popped == &m1 );
     1296}
     1297
     1298void test__pop_last__fred_mine() {
     1299
     1300        fred f1 = {1.7};
     1301        fred f2 = {2.7};
     1302        fred f3 = {3.7};
     1303
     1304        dlist(fred_in_mine, fred) flm;
     1305        insert_last(flm, f1);
     1306        insert_last(flm, f2);
     1307        insert_last(flm, f3);
     1308
     1309        dlist(fred_in_yours, fred) fly;
     1310        insert_last(fly, f1);
     1311        insert_last(fly, f2);
     1312        insert_last(fly, f3);
     1313
     1314        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1315        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1316
     1317        verify(validate(fly));
     1318        verify(validate(flm));
     1319
     1320        fred & popped = pop_last(flm);
     1321
     1322        verify(validate(fly));
     1323        verify(validate(flm));
     1324
     1325        printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7;       1.7;  2.7;  2.7, 1.7      (modified)
     1326        printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1327
     1328        // observe f3 is now solo in mine; in yours, it was just traversed
     1329        printMyFreddies(f3, *0p, 0);    // 3.7; 3.7; ;
     1330
     1331        assert( &popped == & f3 );
     1332}
     1333
     1334void test__pop_last__fred_yours() {
     1335
     1336        fred f1 = {1.7};
     1337        fred f2 = {2.7};
     1338        fred f3 = {3.7};
     1339
     1340        dlist(fred_in_mine, fred) flm;
     1341        insert_last(flm, f1);
     1342        insert_last(flm, f2);
     1343        insert_last(flm, f3);
     1344
     1345        dlist(fred_in_yours, fred) fly;
     1346        insert_last(fly, f1);
     1347        insert_last(fly, f2);
     1348        insert_last(fly, f3);
     1349
     1350        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1351        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1352
     1353        verify(validate(fly));
     1354        verify(validate(flm));
     1355
     1356        fred & popped = pop_last(fly);
     1357
     1358        verify(validate(fly));
     1359        verify(validate(flm));
     1360
     1361        printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1362        printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7;       1.7;  2.7;  2.7, 1.7      (modified)
     1363
     1364        // observe f3 is now solo in yours; in mine, it was just traversed
     1365        printYourFreddies(f3, *0p, 0);    // 3.7; 3.7; ;
     1366
     1367        assert( &popped == & f3 );
     1368}
     1369
     1370void test__pop_last__maries() {
     1371
     1372        mary m1 = {1.7};
     1373        mary m2 = {2.7};
     1374        mary m3 = {3.7};
     1375
     1376        dlist(mary, mary) ml;
     1377        insert_last(ml, m1);
     1378        insert_last(ml, m2);
     1379        insert_last(ml, m3);
     1380
     1381        printMariatheotokos(ml`first, ml`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1382
     1383        verify(validate(ml));
     1384
     1385        mary & popped = pop_last(ml);
     1386
     1387        verify(validate(ml));
     1388
     1389        printMariatheotokos(ml`first, ml`last, 0);     // 1.7, 1.7;       1.7;  2.7;  2.7, 1.7      (modified)
     1390
     1391        // observe m1 is now solo
     1392        printMariatheotokos(m3, *0p, 0);               // 3.7; 3.7; ;
     1393
     1394        assert( &popped == &m3 );
     1395}
     1396
     1397////////////////////////////////////////////////////////////
     1398//
    11891399// Section 5
    11901400//
     
    14221632        test__remove_of_sole__mary();
    14231633
     1634        sout | "";
     1635        sout | "~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~";
     1636        sout | "";
     1637
     1638        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1639        sout | "Test 16-i.  Modifying Freds on MINE";
     1640        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1641        test__pop_first__fred_mine();
     1642
     1643        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1644        sout | "Test 16-ii.  Modifying Freds on YOURS";
     1645        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1646        test__pop_first__fred_yours();
     1647
     1648        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1649        sout | "Test 16-iii.  Modifying Maries";
     1650        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1651        test__pop_first__maries();
     1652
     1653        sout | "";
     1654        sout | "~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~";
     1655        sout | "";
     1656
     1657        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1658        sout | "Test 17-i.  Modifying Freds on MINE";
     1659        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1660        test__pop_last__fred_mine();
     1661
     1662        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1663        sout | "Test 17-ii.  Modifying Freds on YOURS";
     1664        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1665        test__pop_last__fred_yours();
     1666
     1667        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1668        sout | "Test 17-iii.  Modifying Maries";
     1669        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1670        test__pop_last__maries();
     1671
    14241672        return 0;
    14251673}
Note: See TracChangeset for help on using the changeset viewer.