Changeset 7d6e01d
- Timestamp:
- May 19, 2020, 2:51:23 PM (3 years ago)
- 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. - Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
driver/cfa.cc
r068a202 r7d6e01d 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jan 31 16:48:03202013 // Update Count : 42 112 // Last Modified On : Mon May 18 13:26:26 2020 13 // Update Count : 424 14 14 // 15 15 … … 301 301 } // for 302 302 303 #ifdef __x86_64__304 args[nargs++] = "-mcx16"; // allow double-wide CAA305 #endif // __x86_64__306 307 303 #ifdef __DEBUG_H__ 308 304 cerr << "args:"; … … 419 415 args[nargs++] = "-lcfa"; 420 416 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__ 421 421 args[nargs++] = "-pthread"; 422 422 args[nargs++] = "-ldl"; -
libcfa/src/Makefile.am
r068a202 r7d6e01d 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Mon Mar 16 18:07:59202014 ## Update Count : 24 213 ## Last Modified On : Sun May 17 21:10:26 2020 14 ## Update Count : 243 15 15 ############################################################################### 16 16 … … 39 39 #---------------------------------------------------------------------------------------------------------------- 40 40 if 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 41 headers_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 42 43 headers = 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.hfa44 containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/stackLockFree.hfa containers/vector.hfa 44 45 45 46 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa} -
libcfa/src/Makefile.in
r068a202 r7d6e01d 240 240 containers/maybe.hfa containers/pair.hfa containers/result.hfa \ 241 241 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 \ 243 243 bits/debug.hfa bits/locks.hfa containers/list.hfa \ 244 244 concurrency/coroutine.hfa concurrency/thread.hfa \ … … 464 464 465 465 #---------------------------------------------------------------------------------------------------------------- 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 467 469 @BUILDLIB_FALSE@headers = 468 470 @BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \ 469 @BUILDLIB_TRUE@ 471 @BUILDLIB_TRUE@ containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa 470 472 471 473 @BUILDLIB_FALSE@libsrc = -
libcfa/src/containers/list.hfa
r068a202 r7d6e01d 301 301 $prev_link(list_pos) = (Telem*) 0p; 302 302 } 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 303 340 } 304 341 -
libcfa/src/exception.c
r068a202 r7d6e01d 223 223 224 224 // Cancel the current stack, prefroming approprate clean-up and messaging. 225 static __attribute__((noreturn)) void __cfaehm_cancel_stack( 226 exception_t * exception ) { 225 void __cfaehm_cancel_stack( exception_t * exception ) { 227 226 // TODO: Detect current stack and pick a particular stop-function. 228 227 _Unwind_Reason_Code ret; -
libcfa/src/exception.h
r068a202 r7d6e01d 38 38 39 39 40 void __cfaehm_cancel_stack(exception_t * except) __attribute__((noreturn)); 41 40 42 // Used in throw statement translation. 41 43 void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn)); -
libcfa/src/exception.hfa
r068a202 r7d6e01d 10 10 // Created On : Thu Apr 7 10:25:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Apr 7 10:25:00 202013 // Update Count : 012 // Last Modified On : Wed Apr 13 15:42:00 2020 13 // Update Count : 1 14 14 // 15 16 trait 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 22 forall(dtype T | is_exception(T)) 23 inline void cancel_stack(T & except) __attribute__((noreturn)) { 24 __cfaehm_cancel_stack( (exception_t *)&except ); 25 } 15 26 16 27 // Everything below this line should be considered a patch while the exception … … 69 80 #define _VTABLE_DECLARATION(exception_name, parent_name, ...) \ 70 81 struct exception_name; \ 82 void mark_exception(exception_name *); \ 71 83 VTABLE_TYPE(exception_name); \ 72 84 extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \ … … 85 97 #define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__) 86 98 #define _VTABLE_INSTANCE(exception_name, parent_name, ...) \ 99 void mark_exception(exception_name *) {} \ 87 100 void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \ 88 101 *this = *other; \ -
libcfa/src/executor.cfa
r068a202 r7d6e01d 4 4 // buffer. 5 5 6 #include < bits/containers.hfa>6 #include <containers/list.hfa> 7 7 #include <thread.hfa> 8 8 #include <stdio.h> 9 9 10 forall( dtype T )11 monitor Buffer { // unbounded buffer12 __queue_t( T ) queue; // unbounded list of work requests13 condition delay;14 }; // Buffer15 forall( dtype T | is_node(T) ) {16 void insert( Buffer( T ) & mutex buf, T * elem ) with(buf) {17 append( queue, elem ); // insert element into buffer18 signal( delay ); // restart19 } // insert20 21 T * remove( Buffer( T ) & mutex buf ) with(buf) {22 if ( queue.head != 0 ) wait( delay ); // no request to process ? => wait23 // return pop_head( queue );24 } // remove25 } // distribution26 27 10 struct WRequest { // client request, no return 28 11 void (* action)( void ); 29 WRequest * next; // intrusive queue field12 DLISTED_MGD_IMPL_IN(WRequest) 30 13 }; // WRequest 14 DLISTED_MGD_IMPL_OUT(WRequest) 31 15 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; } 16 void ?{}( WRequest & req ) with(req) { action = 0; } 17 void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; } 35 18 bool stop( WRequest & req ) { return req.action == 0; } 36 19 void doit( WRequest & req ) { req.action(); } 20 21 monitor WRBuffer { // unbounded buffer 22 dlist( WRequest, WRequest ) queue; // unbounded list of work requests 23 condition delay; 24 }; // WRBuffer 25 26 void insert( WRBuffer & mutex buf, WRequest * elem ) with(buf) { 27 insert_last( queue, *elem ); // insert element into buffer 28 signal( delay ); // restart 29 } // insert 30 31 WRequest * 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 37 35 38 36 // Each worker has its own work buffer to reduce contention between client and server. Hence, work requests arrive and … … 40 38 41 39 thread Worker { 42 Buffer( WRequest )* requests;40 WRBuffer * requests; 43 41 unsigned int start, range; 44 42 }; // Worker … … 54 52 } // Worker::main 55 53 56 void ?{}( Worker & worker, cluster * wc, Buffer( WRequest )* requests, unsigned int start, unsigned int range ) {54 void ?{}( Worker & worker, cluster * wc, WRBuffer * requests, unsigned int start, unsigned int range ) { 57 55 (*get_thread(worker)){ *wc }; // create on given cluster 58 56 worker.[requests, start, range] = [requests, start, range]; … … 62 60 cluster * cluster; // if workers execute on separate cluster 63 61 processor ** processors; // array of virtual processors adding parallelism for workers 64 Buffer( WRequest ) * requests;// list of work requests62 WRBuffer * requests; // list of work requests 65 63 Worker ** workers; // array of workers executing work requests 66 64 unsigned int nprocessors, nworkers, nmailboxes; // number of mailboxes/workers/processor tasks … … 79 77 cluster = sepClus ? new( "Executor" ) : active_cluster(); 80 78 processors = (processor **)anew( nprocessors ); 81 requests = anew( nmailboxes );79 requests = (WRBuffer *)anew( nmailboxes ); 82 80 workers = (Worker **)anew( nworkers ); 83 81 … … 141 139 for ( i; 3000 ) { 142 140 send( exector, workie ); 143 if ( i % 100 ) yield(); 141 if ( i % 100 == 0 ) { 142 // fprintf( stderr, "%d\n", i ); 143 yield(); 144 } 144 145 } // for 145 146 } -
libcfa/src/heap.cfa
r068a202 r7d6e01d 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 6 17:29:26202013 // Update Count : 7 2712 // Last Modified On : Sun May 17 20:58:17 2020 13 // Update Count : 762 14 14 // 15 15 … … 128 128 #define LOCKFREE 1 129 129 #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 132 135 #endif // LOCKFREE 133 136 … … 137 140 138 141 struct HeapManager { 139 // struct FreeHeader; // forward declaration140 141 142 struct Storage { 142 143 struct Header { // header … … 146 147 struct { // 4-byte word => 8-byte header, 8-byte word => 16-byte header 147 148 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4 148 uint 32_t padding; // unused, force home/blocksize to overlay alignment in fake header149 uint64_t padding; // unused, force home/blocksize to overlay alignment in fake header 149 150 #endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4 150 151 151 152 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) 153 154 // 2nd low-order bit => zero filled 154 155 void * home; // allocated block points back to home locations (must overlay alignment) 155 156 size_t blockSize; // size for munmap (must overlay alignment) 156 #if BUCK LOCK == SPINLOCK157 #if BUCKETLOCK == SPINLOCK 157 158 Storage * next; // freed block points next freed block of same size 158 159 #endif // SPINLOCK 159 160 }; 161 size_t size; // allocation size in bytes 160 162 161 163 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4 162 uint 32_t padding; // unused, force home/blocksize to overlay alignment in fake header164 uint64_t padding; // unused, force home/blocksize to overlay alignment in fake header 163 165 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4 164 166 }; 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) 168 169 #endif // LOCKFREE 169 170 }; 170 171 } real; // RealHeader 172 171 173 struct FakeHeader { 172 174 #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 175 176 #endif // __ORDER_LITTLE_ENDIAN__ 176 177 … … 182 183 } fake; // FakeHeader 183 184 } kind; // Kind 184 size_t size; // allocation size in bytes185 185 } header; // Header 186 186 char pad[libAlign() - sizeof( Header )]; … … 191 191 192 192 struct FreeHeader { 193 #if BUCK LOCK == SPINLOCK193 #if BUCKETLOCK == SPINLOCK 194 194 __spinlock_t lock; // must be first field for alignment 195 195 Storage * freeList; 196 #elif BUCKLOCK == LOCKFREE197 // future code198 StackLF<Storage> freeList;199 196 #else 200 #error undefined lock type for bucket lock201 #endif // SPINLOCK197 StackLF(Storage) freeList; 198 #endif // BUCKETLOCK 202 199 size_t blockSize; // size of allocations on this list 203 200 }; // FreeHeader … … 211 208 size_t heapRemaining; // amount of storage not allocated in the current chunk 212 209 }; // HeapManager 210 211 #if BUCKETLOCK == LOCKFREE 212 static inline Link(HeapManager.Storage) * getNext( HeapManager.Storage * this ) { return &this->header.kind.real.next; } 213 static inline void ?{}( HeapManager.FreeHeader & ) {} 214 static inline void ^?{}( HeapManager.FreeHeader & ) {} 215 #endif // LOCKFREE 213 216 214 217 static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; } … … 251 254 static bool heapBoot = 0; // detect recursion during boot 252 255 #endif // __CFA_DEBUG__ 256 257 // The constructor for heapManager is called explicitly in memory_startup. 253 258 static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing 254 259 … … 354 359 355 360 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 // } // noMemory361 362 363 361 // thunk problem 364 362 size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) { … … 406 404 407 405 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 408 413 static inline void checkAlign( size_t alignment ) { 409 414 if ( alignment < libAlign() || ! libPow2( alignment ) ) { … … 433 438 434 439 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 ) { 440 static 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 ) { 436 442 header = headerAddr( addr ); 437 443 … … 465 471 466 472 467 static inline void * extend( size_t size ) with 473 static inline void * extend( size_t size ) with( heapManager ) { 468 474 lock( extlock __cfaabi_dbg_ctx2 ); 469 475 ptrdiff_t rem = heapRemaining - size; … … 496 502 497 503 498 static inline void * doMalloc( size_t size ) with 504 static inline void * doMalloc( size_t size ) with( heapManager ) { 499 505 HeapManager.Storage * block; // pointer to new block of storage 500 506 … … 529 535 // Spin until the lock is acquired for this particular size of block. 530 536 531 #if defined( SPINLOCK )537 #if BUCKETLOCK == SPINLOCK 532 538 lock( freeElem->lock __cfaabi_dbg_ctx2 ); 533 539 block = freeElem->freeList; // remove node from stack 534 540 #else 535 block = freeElem->freeList.pop();536 #endif // SPINLOCK541 block = pop( freeElem->freeList ); 542 #endif // BUCKETLOCK 537 543 if ( unlikely( block == 0p ) ) { // no free block ? 538 #if defined( SPINLOCK )544 #if BUCKETLOCK == SPINLOCK 539 545 unlock( freeElem->lock ); 540 #endif // SPINLOCK546 #endif // BUCKETLOCK 541 547 542 548 // Freelist for that size was empty, so carve it out of the heap if there's enough left, or get some more … … 544 550 545 551 block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call 546 547 #if defined( SPINLOCK )552 if ( unlikely( block == 0p ) ) return 0p; 553 #if BUCKETLOCK == SPINLOCK 548 554 } else { 549 555 freeElem->freeList = block->header.kind.real.next; 550 556 unlock( freeElem->lock ); 551 #endif // SPINLOCK557 #endif // BUCKETLOCK 552 558 } // if 553 559 … … 572 578 } // if 573 579 574 block->header. size = size;// store allocation size580 block->header.kind.real.size = size; // store allocation size 575 581 void * addr = &(block->data); // adjust off header to user bytes 576 582 … … 591 597 592 598 593 static inline void doFree( void * addr ) with 599 static inline void doFree( void * addr ) with( heapManager ) { 594 600 #ifdef __CFA_DEBUG__ 595 601 if ( unlikely( heapManager.heapBegin == 0p ) ) { … … 623 629 free_storage += size; 624 630 #endif // __STATISTICS__ 625 #if defined( SPINLOCK )631 #if BUCKETLOCK == SPINLOCK 626 632 lock( freeElem->lock __cfaabi_dbg_ctx2 ); // acquire spin lock 627 633 header->kind.real.next = freeElem->freeList; // push on stack … … 629 635 unlock( freeElem->lock ); // release spin lock 630 636 #else 631 freeElem->freeList.push(*(HeapManager.Storage *)header );632 #endif // SPINLOCK637 push( freeElem->freeList, *(HeapManager.Storage *)header ); 638 #endif // BUCKETLOCK 633 639 } // if 634 640 … … 645 651 646 652 647 size_t prtFree( HeapManager & manager ) with 653 size_t prtFree( HeapManager & manager ) with( manager ) { 648 654 size_t total = 0; 649 655 #ifdef __STATISTICS__ … … 657 663 #endif // __STATISTICS__ 658 664 659 #if defined( SPINLOCK )665 #if BUCKETLOCK == SPINLOCK 660 666 for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0p; p = p->header.kind.real.next ) { 661 667 #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 664 672 total += size; 665 673 #ifdef __STATISTICS__ … … 681 689 682 690 683 static void ?{}( HeapManager & manager ) with 691 static void ?{}( HeapManager & manager ) with( manager ) { 684 692 pageSize = sysconf( _SC_PAGESIZE ); 685 693 … … 1095 1103 header = realHeader( header ); // backup from fake to real header 1096 1104 } // if 1097 return header-> size;1105 return header->kind.real.size; 1098 1106 } // malloc_size 1099 1107 … … 1105 1113 header = realHeader( header ); // backup from fake to real header 1106 1114 } // 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; 1109 1117 return ret; 1110 1118 } // $malloc_size_set -
libcfa/src/stdlib.hfa
r068a202 r7d6e01d 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 16 22:44:05202013 // Update Count : 43 212 // Last Modified On : Wed May 13 17:23:51 2020 13 // Update Count : 435 14 14 // 15 15 … … 23 23 // Reduce includes by explicitly defining these routines. 24 24 extern "C" { 25 void * aalloc( size_t dim, size_t elemSize ); // CFA heap 26 void * resize( void * oaddr, size_t size ); // CFA heap 25 27 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 26 31 size_t malloc_usable_size( void * ptr ); // malloc.h 27 size_t malloc_size( void * addr ); // CFA heap28 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap29 32 void * memset( void * dest, int fill, size_t size ); // string.h 30 33 void * memcpy( void * dest, const void * src, size_t size ); // string.h 31 void * resize( void * oaddr, size_t size ); // CFA heap32 34 } // extern "C" 33 35 … … 52 54 } // malloc 53 55 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 54 61 T * calloc( size_t dim ) { 55 62 if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc … … 57 64 } // calloc 58 65 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 59 70 T * realloc( T * ptr, size_t size ) { // CFA realloc, eliminate return-type cast 60 71 return (T *)(void *)realloc( (void *)ptr, size ); // C realloc … … 65 76 } // memalign 66 77 78 T * amemalign( size_t align, size_t dim ) { 79 return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign 80 } // amemalign 81 67 82 T * cmemalign( size_t align, size_t dim ) { 68 83 return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign … … 86 101 87 102 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 ); 90 104 } // alloc 91 105 … … 106 120 return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc 107 121 } 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 110 123 } // if 111 124 } // alloc … … 148 161 } // alloc_align 149 162 150 T * alloc_align( T ptr[], size_t align ) { // aligned realloc array163 T * alloc_align( T * ptr, size_t align ) { // aligned realloc array 151 164 return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc 152 165 } // alloc_align -
tests/list/.expect/dlist-insert-remove.txt
r068a202 r7d6e01d 1464 1464 0.7 1465 1465 - 1466 1467 ~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~ 1468 1469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1470 Test 16-i. Modifying Freds on MINE 1471 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1472 ==== fred by MINE before 1473 1.7 1474 2.7 1475 3.7 1476 - 1477 1.7 1478 - 1479 3.7 1480 - 1481 3.7 1482 2.7 1483 1.7 1484 - 1485 ==== fred by YOURS before 1486 1.7 1487 2.7 1488 3.7 1489 - 1490 1.7 1491 - 1492 3.7 1493 - 1494 3.7 1495 2.7 1496 1.7 1497 - 1498 ==== fred by MINE after 1499 2.7 1500 3.7 1501 - 1502 2.7 1503 - 1504 3.7 1505 - 1506 3.7 1507 2.7 1508 - 1509 ==== fred by YOURS after 1510 1.7 1511 2.7 1512 3.7 1513 - 1514 1.7 1515 - 1516 3.7 1517 - 1518 3.7 1519 2.7 1520 1.7 1521 - 1522 ==== fred by MINE after 1523 1.7 1524 - 1525 1.7 1526 - 1527 - 1528 - 1529 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1530 Test 16-ii. Modifying Freds on YOURS 1531 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1532 ==== fred by MINE before 1533 1.7 1534 2.7 1535 3.7 1536 - 1537 1.7 1538 - 1539 3.7 1540 - 1541 3.7 1542 2.7 1543 1.7 1544 - 1545 ==== fred by YOURS before 1546 1.7 1547 2.7 1548 3.7 1549 - 1550 1.7 1551 - 1552 3.7 1553 - 1554 3.7 1555 2.7 1556 1.7 1557 - 1558 ==== fred by MINE after 1559 1.7 1560 2.7 1561 3.7 1562 - 1563 1.7 1564 - 1565 3.7 1566 - 1567 3.7 1568 2.7 1569 1.7 1570 - 1571 ==== fred by YOURS after 1572 2.7 1573 3.7 1574 - 1575 2.7 1576 - 1577 3.7 1578 - 1579 3.7 1580 2.7 1581 - 1582 ==== fred by YOURS after 1583 1.7 1584 - 1585 1.7 1586 - 1587 - 1588 - 1589 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1590 Test 16-iii. Modifying Maries 1591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1592 ==== mary before 1593 1.7 1594 2.7 1595 3.7 1596 - 1597 1.7 1598 - 1599 3.7 1600 - 1601 3.7 1602 2.7 1603 1.7 1604 - 1605 ==== mary after 1606 2.7 1607 3.7 1608 - 1609 2.7 1610 - 1611 3.7 1612 - 1613 3.7 1614 2.7 1615 - 1616 ==== mary after 1617 1.7 1618 - 1619 1.7 1620 - 1621 - 1622 - 1623 1624 ~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~ 1625 1626 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1627 Test 17-i. Modifying Freds on MINE 1628 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1629 ==== fred by MINE before 1630 1.7 1631 2.7 1632 3.7 1633 - 1634 1.7 1635 - 1636 3.7 1637 - 1638 3.7 1639 2.7 1640 1.7 1641 - 1642 ==== fred by YOURS before 1643 1.7 1644 2.7 1645 3.7 1646 - 1647 1.7 1648 - 1649 3.7 1650 - 1651 3.7 1652 2.7 1653 1.7 1654 - 1655 ==== fred by MINE after 1656 1.7 1657 2.7 1658 - 1659 1.7 1660 - 1661 2.7 1662 - 1663 2.7 1664 1.7 1665 - 1666 ==== fred by YOURS after 1667 1.7 1668 2.7 1669 3.7 1670 - 1671 1.7 1672 - 1673 3.7 1674 - 1675 3.7 1676 2.7 1677 1.7 1678 - 1679 ==== fred by MINE after 1680 3.7 1681 - 1682 3.7 1683 - 1684 - 1685 - 1686 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1687 Test 17-ii. Modifying Freds on YOURS 1688 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1689 ==== fred by MINE before 1690 1.7 1691 2.7 1692 3.7 1693 - 1694 1.7 1695 - 1696 3.7 1697 - 1698 3.7 1699 2.7 1700 1.7 1701 - 1702 ==== fred by YOURS before 1703 1.7 1704 2.7 1705 3.7 1706 - 1707 1.7 1708 - 1709 3.7 1710 - 1711 3.7 1712 2.7 1713 1.7 1714 - 1715 ==== fred by MINE after 1716 1.7 1717 2.7 1718 3.7 1719 - 1720 1.7 1721 - 1722 3.7 1723 - 1724 3.7 1725 2.7 1726 1.7 1727 - 1728 ==== fred by YOURS after 1729 1.7 1730 2.7 1731 - 1732 1.7 1733 - 1734 2.7 1735 - 1736 2.7 1737 1.7 1738 - 1739 ==== fred by YOURS after 1740 3.7 1741 - 1742 3.7 1743 - 1744 - 1745 - 1746 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1747 Test 17-iii. Modifying Maries 1748 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1749 ==== mary before 1750 1.7 1751 2.7 1752 3.7 1753 - 1754 1.7 1755 - 1756 3.7 1757 - 1758 3.7 1759 2.7 1760 1.7 1761 - 1762 ==== mary after 1763 1.7 1764 2.7 1765 - 1766 1.7 1767 - 1768 2.7 1769 - 1770 2.7 1771 1.7 1772 - 1773 ==== mary after 1774 3.7 1775 - 1776 3.7 1777 - 1778 - 1779 - -
tests/list/dlist-insert-remove.cfa
r068a202 r7d6e01d 1187 1187 //////////////////////////////////////////////////////////// 1188 1188 // 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 1199 void 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 1235 void 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 1271 void 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 1298 void 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 1334 void 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 1370 void 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 // 1189 1399 // Section 5 1190 1400 // … … 1422 1632 test__remove_of_sole__mary(); 1423 1633 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 1424 1672 return 0; 1425 1673 }
Note: See TracChangeset
for help on using the changeset viewer.