Changes in / [7d6e01d:068a202]
- Files:
-
- 1 deleted
- 12 edited
-
driver/cfa.cc (modified) (3 diffs)
-
libcfa/src/Makefile.am (modified) (2 diffs)
-
libcfa/src/Makefile.in (modified) (2 diffs)
-
libcfa/src/containers/list.hfa (modified) (1 diff)
-
libcfa/src/containers/stackLockFree.hfa (deleted)
-
libcfa/src/exception.c (modified) (1 diff)
-
libcfa/src/exception.h (modified) (1 diff)
-
libcfa/src/exception.hfa (modified) (3 diffs)
-
libcfa/src/executor.cfa (modified) (6 diffs)
-
libcfa/src/heap.cfa (modified) (24 diffs)
-
libcfa/src/stdlib.hfa (modified) (8 diffs)
-
tests/list/.expect/dlist-insert-remove.txt (modified) (1 diff)
-
tests/list/dlist-insert-remove.cfa (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
driver/cfa.cc
r7d6e01d r068a202 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 18 13:26:26202013 // Update Count : 42 412 // Last Modified On : Fri Jan 31 16:48:03 2020 13 // Update Count : 421 14 14 // 15 15 … … 301 301 } // for 302 302 303 #ifdef __x86_64__ 304 args[nargs++] = "-mcx16"; // allow double-wide CAA 305 #endif // __x86_64__ 306 303 307 #ifdef __DEBUG_H__ 304 308 cerr << "args:"; … … 415 419 args[nargs++] = "-lcfa"; 416 420 args[nargs++] = "-Wl,--pop-state"; 417 #ifdef __x86_64__418 args[nargs++] = "-mcx16"; // allow double-wide CAS419 args[nargs++] = "-latomic";420 #endif // __x86_64__421 421 args[nargs++] = "-pthread"; 422 422 args[nargs++] = "-ldl"; -
libcfa/src/Makefile.am
r7d6e01d r068a202 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Sun May 17 21:10:26202014 ## Update Count : 24 313 ## Last Modified On : Mon Mar 16 18:07:59 2020 14 ## Update Count : 242 15 15 ############################################################################### 16 16 … … 39 39 #---------------------------------------------------------------------------------------------------------------- 40 40 if BUILDLIB 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 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 43 42 headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \ 44 containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/stackLockFree.hfa containers/vector.hfa43 containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa 45 44 46 45 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa} -
libcfa/src/Makefile.in
r7d6e01d r068a202 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 clock.hfabits/align.hfa bits/containers.hfa bits/defs.hfa \242 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 clock.hfa \ 467 @BUILDLIB_TRUE@ bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa 468 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 469 467 @BUILDLIB_FALSE@headers = 470 468 @BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \ 471 @BUILDLIB_TRUE@ containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa469 @BUILDLIB_TRUE@ containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa 472 470 473 471 @BUILDLIB_FALSE@libsrc = -
libcfa/src/containers/list.hfa
r7d6e01d r068a202 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 340 303 } 341 304 -
libcfa/src/exception.c
r7d6e01d r068a202 223 223 224 224 // Cancel the current stack, prefroming approprate clean-up and messaging. 225 void __cfaehm_cancel_stack( exception_t * exception ) { 225 static __attribute__((noreturn)) void __cfaehm_cancel_stack( 226 exception_t * exception ) { 226 227 // TODO: Detect current stack and pick a particular stop-function. 227 228 _Unwind_Reason_Code ret; -
libcfa/src/exception.h
r7d6e01d r068a202 38 38 39 39 40 void __cfaehm_cancel_stack(exception_t * except) __attribute__((noreturn));41 42 40 // Used in throw statement translation. 43 41 void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn)); -
libcfa/src/exception.hfa
r7d6e01d r068a202 10 10 // Created On : Thu Apr 7 10:25:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Apr 13 15:42:00 202013 // Update Count : 112 // Last Modified On : Thu Apr 7 10:25:00 2020 13 // Update Count : 0 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 }26 15 27 16 // Everything below this line should be considered a patch while the exception … … 80 69 #define _VTABLE_DECLARATION(exception_name, parent_name, ...) \ 81 70 struct exception_name; \ 82 void mark_exception(exception_name *); \83 71 VTABLE_TYPE(exception_name); \ 84 72 extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \ … … 97 85 #define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__) 98 86 #define _VTABLE_INSTANCE(exception_name, parent_name, ...) \ 99 void mark_exception(exception_name *) {} \100 87 void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \ 101 88 *this = *other; \ -
libcfa/src/executor.cfa
r7d6e01d r068a202 4 4 // buffer. 5 5 6 #include < containers/list.hfa>6 #include <bits/containers.hfa> 7 7 #include <thread.hfa> 8 8 #include <stdio.h> 9 9 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 10 27 struct WRequest { // client request, no return 11 28 void (* action)( void ); 12 DLISTED_MGD_IMPL_IN(WRequest)29 WRequest * next; // intrusive queue field 13 30 }; // WRequest 14 DLISTED_MGD_IMPL_OUT(WRequest)15 31 16 void ?{}( WRequest & req ) with(req) { action = 0; } 17 void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; } 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; } 18 35 bool stop( WRequest & req ) { return req.action == 0; } 19 36 void doit( WRequest & req ) { req.action(); } 20 21 monitor WRBuffer { // unbounded buffer22 dlist( WRequest, WRequest ) queue; // unbounded list of work requests23 condition delay;24 }; // WRBuffer25 26 void insert( WRBuffer & mutex buf, WRequest * elem ) with(buf) {27 insert_last( queue, *elem ); // insert element into buffer28 signal( delay ); // restart29 } // insert30 31 WRequest * remove( WRBuffer & mutex buf ) with(buf) {32 if ( queue`is_empty ) wait( delay ); // no request to process ? => wait33 return & pop_first( queue );34 } // remove35 37 36 38 // Each worker has its own work buffer to reduce contention between client and server. Hence, work requests arrive and … … 38 40 39 41 thread Worker { 40 WRBuffer* requests;42 Buffer( WRequest ) * requests; 41 43 unsigned int start, range; 42 44 }; // Worker … … 52 54 } // Worker::main 53 55 54 void ?{}( Worker & worker, cluster * wc, WRBuffer* requests, unsigned int start, unsigned int range ) {56 void ?{}( Worker & worker, cluster * wc, Buffer( WRequest ) * requests, unsigned int start, unsigned int range ) { 55 57 (*get_thread(worker)){ *wc }; // create on given cluster 56 58 worker.[requests, start, range] = [requests, start, range]; … … 60 62 cluster * cluster; // if workers execute on separate cluster 61 63 processor ** processors; // array of virtual processors adding parallelism for workers 62 WRBuffer * requests;// list of work requests64 Buffer( WRequest ) * requests; // list of work requests 63 65 Worker ** workers; // array of workers executing work requests 64 66 unsigned int nprocessors, nworkers, nmailboxes; // number of mailboxes/workers/processor tasks … … 77 79 cluster = sepClus ? new( "Executor" ) : active_cluster(); 78 80 processors = (processor **)anew( nprocessors ); 79 requests = (WRBuffer *)anew( nmailboxes );81 requests = anew( nmailboxes ); 80 82 workers = (Worker **)anew( nworkers ); 81 83 … … 139 141 for ( i; 3000 ) { 140 142 send( exector, workie ); 141 if ( i % 100 == 0 ) { 142 // fprintf( stderr, "%d\n", i ); 143 yield(); 144 } 143 if ( i % 100 ) yield(); 145 144 } // for 146 145 } -
libcfa/src/heap.cfa
r7d6e01d r068a202 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 17 20:58:17202013 // Update Count : 7 6212 // Last Modified On : Wed May 6 17:29:26 2020 13 // Update Count : 727 14 14 // 15 15 … … 128 128 #define LOCKFREE 1 129 129 #define BUCKETLOCK SPINLOCK 130 #if BUCKETLOCK == SPINLOCK 131 #elif BUCKETLOCK == LOCKFREE 132 #include <stackLockFree.hfa> 133 #else 134 #error undefined lock type for bucket lock 130 #if BUCKETLOCK == LOCKFREE 131 #include <uStackLF.h> 135 132 #endif // LOCKFREE 136 133 … … 140 137 141 138 struct HeapManager { 139 // struct FreeHeader; // forward declaration 140 142 141 struct Storage { 143 142 struct Header { // header … … 147 146 struct { // 4-byte word => 8-byte header, 8-byte word => 16-byte header 148 147 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4 149 uint 64_t padding; // unused, force home/blocksize to overlay alignment in fake header148 uint32_t padding; // unused, force home/blocksize to overlay alignment in fake header 150 149 #endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4 151 150 152 151 union { 153 //FreeHeader * home; // allocated block points back to home locations (must overlay alignment)152 // FreeHeader * home; // allocated block points back to home locations (must overlay alignment) 154 153 // 2nd low-order bit => zero filled 155 154 void * home; // allocated block points back to home locations (must overlay alignment) 156 155 size_t blockSize; // size for munmap (must overlay alignment) 157 #if BUCK ETLOCK == SPINLOCK156 #if BUCKLOCK == SPINLOCK 158 157 Storage * next; // freed block points next freed block of same size 159 158 #endif // SPINLOCK 160 159 }; 161 size_t size; // allocation size in bytes162 160 163 161 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4 164 uint 64_t padding; // unused, force home/blocksize to overlay alignment in fake header162 uint32_t padding; // unused, force home/blocksize to overlay alignment in fake header 165 163 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4 166 164 }; 167 #if BUCKETLOCK == LOCKFREE 168 Link(Storage) next; // freed block points next freed block of same size (double-wide) 165 // future code 166 #if BUCKLOCK == LOCKFREE 167 Stack<Storage>::Link next; // freed block points next freed block of same size (double-wide) 169 168 #endif // LOCKFREE 170 169 }; 171 170 } real; // RealHeader 172 173 171 struct FakeHeader { 174 172 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 175 uint32_t alignment; // 1st low-order bit => fake header & alignment 173 // 1st low-order bit => fake header & alignment 174 uint32_t alignment; 176 175 #endif // __ORDER_LITTLE_ENDIAN__ 177 176 … … 183 182 } fake; // FakeHeader 184 183 } kind; // Kind 184 size_t size; // allocation size in bytes 185 185 } header; // Header 186 186 char pad[libAlign() - sizeof( Header )]; … … 191 191 192 192 struct FreeHeader { 193 #if BUCK ETLOCK == SPINLOCK193 #if BUCKLOCK == SPINLOCK 194 194 __spinlock_t lock; // must be first field for alignment 195 195 Storage * freeList; 196 #elif BUCKLOCK == LOCKFREE 197 // future code 198 StackLF<Storage> freeList; 196 199 #else 197 StackLF(Storage) freeList;198 #endif // BUCKETLOCK200 #error undefined lock type for bucket lock 201 #endif // SPINLOCK 199 202 size_t blockSize; // size of allocations on this list 200 203 }; // FreeHeader … … 208 211 size_t heapRemaining; // amount of storage not allocated in the current chunk 209 212 }; // HeapManager 210 211 #if BUCKETLOCK == LOCKFREE212 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 // LOCKFREE216 213 217 214 static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; } … … 254 251 static bool heapBoot = 0; // detect recursion during boot 255 252 #endif // __CFA_DEBUG__ 256 257 // The constructor for heapManager is called explicitly in memory_startup.258 253 static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing 259 254 … … 359 354 360 355 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 361 363 // thunk problem 362 364 size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) { … … 404 406 405 407 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 // } // noMemory411 412 413 408 static inline void checkAlign( size_t alignment ) { 414 409 if ( alignment < libAlign() || ! libPow2( alignment ) ) { … … 438 433 439 434 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 ) { 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 ) { 442 436 header = headerAddr( addr ); 443 437 … … 471 465 472 466 473 static inline void * extend( size_t size ) with ( heapManager ) {467 static inline void * extend( size_t size ) with ( heapManager ) { 474 468 lock( extlock __cfaabi_dbg_ctx2 ); 475 469 ptrdiff_t rem = heapRemaining - size; … … 502 496 503 497 504 static inline void * doMalloc( size_t size ) with ( heapManager ) {498 static inline void * doMalloc( size_t size ) with ( heapManager ) { 505 499 HeapManager.Storage * block; // pointer to new block of storage 506 500 … … 535 529 // Spin until the lock is acquired for this particular size of block. 536 530 537 #if BUCKETLOCK == SPINLOCK531 #if defined( SPINLOCK ) 538 532 lock( freeElem->lock __cfaabi_dbg_ctx2 ); 539 533 block = freeElem->freeList; // remove node from stack 540 534 #else 541 block = pop( freeElem->freeList);542 #endif // BUCKETLOCK535 block = freeElem->freeList.pop(); 536 #endif // SPINLOCK 543 537 if ( unlikely( block == 0p ) ) { // no free block ? 544 #if BUCKETLOCK == SPINLOCK538 #if defined( SPINLOCK ) 545 539 unlock( freeElem->lock ); 546 #endif // BUCKETLOCK540 #endif // SPINLOCK 547 541 548 542 // Freelist for that size was empty, so carve it out of the heap if there's enough left, or get some more … … 550 544 551 545 block = (HeapManager.Storage *)extend( tsize ); // mutual exclusion on call 552 if ( unlikely( block == 0p ) ) return 0p;553 #if BUCKETLOCK == SPINLOCK546 if ( unlikely( block == 0p ) ) return 0p; 547 #if defined( SPINLOCK ) 554 548 } else { 555 549 freeElem->freeList = block->header.kind.real.next; 556 550 unlock( freeElem->lock ); 557 #endif // BUCKETLOCK551 #endif // SPINLOCK 558 552 } // if 559 553 … … 578 572 } // if 579 573 580 block->header. kind.real.size = size;// store allocation size574 block->header.size = size; // store allocation size 581 575 void * addr = &(block->data); // adjust off header to user bytes 582 576 … … 597 591 598 592 599 static inline void doFree( void * addr ) with ( heapManager ) {593 static inline void doFree( void * addr ) with ( heapManager ) { 600 594 #ifdef __CFA_DEBUG__ 601 595 if ( unlikely( heapManager.heapBegin == 0p ) ) { … … 629 623 free_storage += size; 630 624 #endif // __STATISTICS__ 631 #if BUCKETLOCK == SPINLOCK625 #if defined( SPINLOCK ) 632 626 lock( freeElem->lock __cfaabi_dbg_ctx2 ); // acquire spin lock 633 627 header->kind.real.next = freeElem->freeList; // push on stack … … 635 629 unlock( freeElem->lock ); // release spin lock 636 630 #else 637 push( freeElem->freeList,*(HeapManager.Storage *)header );638 #endif // BUCKETLOCK631 freeElem->freeList.push( *(HeapManager.Storage *)header ); 632 #endif // SPINLOCK 639 633 } // if 640 634 … … 651 645 652 646 653 size_t prtFree( HeapManager & manager ) with ( manager ) {647 size_t prtFree( HeapManager & manager ) with ( manager ) { 654 648 size_t total = 0; 655 649 #ifdef __STATISTICS__ … … 663 657 #endif // __STATISTICS__ 664 658 665 #if BUCKETLOCK == SPINLOCK659 #if defined( SPINLOCK ) 666 660 for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0p; p = p->header.kind.real.next ) { 667 661 #else 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 662 for ( HeapManager.Storage * p = freeLists[i].freeList.top(); p != 0p; p = p->header.kind.real.next.top ) { 663 #endif // SPINLOCK 672 664 total += size; 673 665 #ifdef __STATISTICS__ … … 689 681 690 682 691 static void ?{}( HeapManager & manager ) with ( manager ) {683 static void ?{}( HeapManager & manager ) with ( manager ) { 692 684 pageSize = sysconf( _SC_PAGESIZE ); 693 685 … … 1103 1095 header = realHeader( header ); // backup from fake to real header 1104 1096 } // if 1105 return header-> kind.real.size;1097 return header->size; 1106 1098 } // malloc_size 1107 1099 … … 1113 1105 header = realHeader( header ); // backup from fake to real header 1114 1106 } // if 1115 size_t ret = header-> kind.real.size;1116 header-> kind.real.size = size;1107 size_t ret = header->size; 1108 header->size = size; 1117 1109 return ret; 1118 1110 } // $malloc_size_set -
libcfa/src/stdlib.hfa
r7d6e01d r068a202 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 13 17:23:51202013 // Update Count : 43 512 // Last Modified On : Thu Apr 16 22:44:05 2020 13 // Update Count : 432 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 heap26 void * resize( void * oaddr, size_t size ); // CFA heap27 25 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 26 size_t malloc_usable_size( void * ptr ); // malloc.h 30 27 size_t malloc_size( void * addr ); // CFA heap 31 size_t malloc_usable_size( void * ptr ); // malloc.h28 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap 32 29 void * memset( void * dest, int fill, size_t size ); // string.h 33 30 void * memcpy( void * dest, const void * src, size_t size ); // string.h 31 void * resize( void * oaddr, size_t size ); // CFA heap 34 32 } // extern "C" 35 33 … … 54 52 } // malloc 55 53 56 T * aalloc( size_t dim ) {57 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)aalloc( dim, (size_t)sizeof(T) ); // CFA aalloc58 else return (T *)amemalign( _Alignof(T), dim, sizeof(T) );59 } // aalloc60 61 54 T * calloc( size_t dim ) { 62 55 if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc … … 64 57 } // calloc 65 58 66 T * resize( T * ptr, size_t size ) { // CFA realloc, eliminate return-type cast67 return (T *)(void *)resize( (void *)ptr, size ); // C realloc68 } // resize69 70 59 T * realloc( T * ptr, size_t size ) { // CFA realloc, eliminate return-type cast 71 60 return (T *)(void *)realloc( (void *)ptr, size ); // C realloc … … 76 65 } // memalign 77 66 78 T * amemalign( size_t align, size_t dim ) {79 return (T *)amemalign( align, dim, sizeof(T) ); // CFA amemalign80 } // amemalign81 82 67 T * cmemalign( size_t align, size_t dim ) { 83 68 return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign … … 101 86 102 87 T * alloc( size_t dim ) { 103 return aalloc( 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) ); 104 90 } // alloc 105 91 … … 120 106 return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc 121 107 } else { 122 return resize( ptr, dim * sizeof(T) ); // resize 108 struct __Unknown {}; 109 return alloc( (__Unknown *)ptr, dim ); // reuse, cheat making T/S different types 123 110 } // if 124 111 } // alloc … … 161 148 } // alloc_align 162 149 163 T * alloc_align( T * ptr, size_t align ) { // aligned realloc array150 T * alloc_align( T ptr[], size_t align ) { // aligned realloc array 164 151 return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc 165 152 } // alloc_align -
tests/list/.expect/dlist-insert-remove.txt
r7d6e01d r068a202 1464 1464 0.7 1465 1465 - 1466 1467 ~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~1468 1469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1470 Test 16-i. Modifying Freds on MINE1471 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1472 ==== fred by MINE before1473 1.71474 2.71475 3.71476 -1477 1.71478 -1479 3.71480 -1481 3.71482 2.71483 1.71484 -1485 ==== fred by YOURS before1486 1.71487 2.71488 3.71489 -1490 1.71491 -1492 3.71493 -1494 3.71495 2.71496 1.71497 -1498 ==== fred by MINE after1499 2.71500 3.71501 -1502 2.71503 -1504 3.71505 -1506 3.71507 2.71508 -1509 ==== fred by YOURS after1510 1.71511 2.71512 3.71513 -1514 1.71515 -1516 3.71517 -1518 3.71519 2.71520 1.71521 -1522 ==== fred by MINE after1523 1.71524 -1525 1.71526 -1527 -1528 -1529 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1530 Test 16-ii. Modifying Freds on YOURS1531 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1532 ==== fred by MINE before1533 1.71534 2.71535 3.71536 -1537 1.71538 -1539 3.71540 -1541 3.71542 2.71543 1.71544 -1545 ==== fred by YOURS before1546 1.71547 2.71548 3.71549 -1550 1.71551 -1552 3.71553 -1554 3.71555 2.71556 1.71557 -1558 ==== fred by MINE after1559 1.71560 2.71561 3.71562 -1563 1.71564 -1565 3.71566 -1567 3.71568 2.71569 1.71570 -1571 ==== fred by YOURS after1572 2.71573 3.71574 -1575 2.71576 -1577 3.71578 -1579 3.71580 2.71581 -1582 ==== fred by YOURS after1583 1.71584 -1585 1.71586 -1587 -1588 -1589 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1590 Test 16-iii. Modifying Maries1591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1592 ==== mary before1593 1.71594 2.71595 3.71596 -1597 1.71598 -1599 3.71600 -1601 3.71602 2.71603 1.71604 -1605 ==== mary after1606 2.71607 3.71608 -1609 2.71610 -1611 3.71612 -1613 3.71614 2.71615 -1616 ==== mary after1617 1.71618 -1619 1.71620 -1621 -1622 -1623 1624 ~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~1625 1626 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1627 Test 17-i. Modifying Freds on MINE1628 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1629 ==== fred by MINE before1630 1.71631 2.71632 3.71633 -1634 1.71635 -1636 3.71637 -1638 3.71639 2.71640 1.71641 -1642 ==== fred by YOURS before1643 1.71644 2.71645 3.71646 -1647 1.71648 -1649 3.71650 -1651 3.71652 2.71653 1.71654 -1655 ==== fred by MINE after1656 1.71657 2.71658 -1659 1.71660 -1661 2.71662 -1663 2.71664 1.71665 -1666 ==== fred by YOURS after1667 1.71668 2.71669 3.71670 -1671 1.71672 -1673 3.71674 -1675 3.71676 2.71677 1.71678 -1679 ==== fred by MINE after1680 3.71681 -1682 3.71683 -1684 -1685 -1686 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1687 Test 17-ii. Modifying Freds on YOURS1688 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1689 ==== fred by MINE before1690 1.71691 2.71692 3.71693 -1694 1.71695 -1696 3.71697 -1698 3.71699 2.71700 1.71701 -1702 ==== fred by YOURS before1703 1.71704 2.71705 3.71706 -1707 1.71708 -1709 3.71710 -1711 3.71712 2.71713 1.71714 -1715 ==== fred by MINE after1716 1.71717 2.71718 3.71719 -1720 1.71721 -1722 3.71723 -1724 3.71725 2.71726 1.71727 -1728 ==== fred by YOURS after1729 1.71730 2.71731 -1732 1.71733 -1734 2.71735 -1736 2.71737 1.71738 -1739 ==== fred by YOURS after1740 3.71741 -1742 3.71743 -1744 -1745 -1746 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1747 Test 17-iii. Modifying Maries1748 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1749 ==== mary before1750 1.71751 2.71752 3.71753 -1754 1.71755 -1756 3.71757 -1758 3.71759 2.71760 1.71761 -1762 ==== mary after1763 1.71764 2.71765 -1766 1.71767 -1768 2.71769 -1770 2.71771 1.71772 -1773 ==== mary after1774 3.71775 -1776 3.71777 -1778 -1779 - -
tests/list/dlist-insert-remove.cfa
r7d6e01d r068a202 1187 1187 //////////////////////////////////////////////////////////// 1188 1188 // 1189 // Section 4f1190 //1191 // Test cases of pop_first, pop_last1192 //1193 // Example of call-side user code1194 //1195 ////////////////////////////////////////////////////////////1196 1197 // These cases assume element removal at first-last is correct1198 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.71216 printYourFreddies(fly`first, fly`last, 1); // 1.7, 2.7, 3.7; 1.7; 3.7; 3.7, 2.7, 1.71217 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 traversed1230 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.71252 printYourFreddies(fly`first, fly`last, 1); // 1.7, 2.7, 3.7; 1.7; 3.7; 3.7, 2.7, 1.71253 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 traversed1266 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.71283 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 solo1293 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.71315 printYourFreddies(fly`first, fly`last, 1); // 1.7, 2.7, 3.7; 1.7; 3.7; 3.7, 2.7, 1.71316 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 traversed1329 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.71351 printYourFreddies(fly`first, fly`last, 1); // 1.7, 2.7, 3.7; 1.7; 3.7; 3.7, 2.7, 1.71352 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 traversed1365 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.71382 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 solo1392 printMariatheotokos(m3, *0p, 0); // 3.7; 3.7; ;1393 1394 assert( &popped == &m3 );1395 }1396 1397 ////////////////////////////////////////////////////////////1398 //1399 1189 // Section 5 1400 1190 // … … 1632 1422 test__remove_of_sole__mary(); 1633 1423 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 1672 1424 return 0; 1673 1425 }
Note:
See TracChangeset
for help on using the changeset viewer.