- Timestamp:
- Jun 19, 2023, 1:57:11 PM (2 years ago)
- Branches:
- master
- Children:
- adc73a5
- Parents:
- fa5e1aa5 (diff), 33d4bc8 (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. - Location:
- libcfa
- Files:
-
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/prelude/builtins.c
rfa5e1aa5 rb7b3e41 149 149 150 150 static inline { 151 longint ?\?( int x, unsigned int y ) { __CFA_EXP__(); }151 int ?\?( int x, unsigned int y ) { __CFA_EXP__(); } 152 152 long int ?\?( long int x, unsigned long int y ) { __CFA_EXP__(); } 153 153 long long int ?\?( long long int x, unsigned long long int y ) { __CFA_EXP__(); } 154 154 // unsigned computation may be faster and larger 155 unsigned longint ?\?( unsigned int x, unsigned int y ) { __CFA_EXP__(); }155 unsigned int ?\?( unsigned int x, unsigned int y ) { __CFA_EXP__(); } 156 156 unsigned long int ?\?( unsigned long int x, unsigned long int y ) { __CFA_EXP__(); } 157 157 unsigned long long int ?\?( unsigned long long int x, unsigned long long int y ) { __CFA_EXP__(); } … … 176 176 177 177 static inline { 178 longint ?\=?( int & x, unsigned int y ) { x = x \ y; return x; }178 int ?\=?( int & x, unsigned int y ) { x = x \ y; return x; } 179 179 long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; } 180 180 long long int ?\=?( long long int & x, unsigned long long int y ) { x = x \ y; return x; } 181 unsigned longint ?\=?( unsigned int & x, unsigned int y ) { x = x \ y; return x; }181 unsigned int ?\=?( unsigned int & x, unsigned int y ) { x = x \ y; return x; } 182 182 unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; } 183 183 unsigned long long int ?\=?( unsigned long long int & x, unsigned long long int y ) { x = x \ y; return x; } -
libcfa/prelude/sync-builtins.cf
rfa5e1aa5 rb7b3e41 206 206 _Bool __sync_bool_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...); 207 207 #endif 208 // for all pointer types 208 209 forall(T &) _Bool __sync_bool_compare_and_swap(T * volatile *, T *, T*, ...); 209 210 … … 223 224 unsigned __int128 __sync_val_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...); 224 225 #endif 226 // for all pointer types 225 227 forall(T &) T * __sync_val_compare_and_swap(T * volatile *, T *, T*,...); 226 228 … … 326 328 void __atomic_exchange(volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128 *, int); 327 329 #endif 330 // for all pointer types 328 331 forall(T &) T * __atomic_exchange_n(T * volatile *, T *, int); 329 332 forall(T &) void __atomic_exchange(T * volatile *, T **, T **, int); … … 359 362 void __atomic_load(const volatile unsigned __int128 *, unsigned __int128 *, int); 360 363 #endif 364 // for all pointer types 361 365 forall(T &) T * __atomic_load_n(T * const volatile *, int); 362 366 forall(T &) void __atomic_load(T * const volatile *, T **, int); … … 390 394 _Bool __atomic_compare_exchange (volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128 *, _Bool, int, int); 391 395 #endif 396 // for all pointer types 392 397 forall(T &) _Bool __atomic_compare_exchange_n (T * volatile *, T **, T*, _Bool, int, int); 393 398 forall(T &) _Bool __atomic_compare_exchange (T * volatile *, T **, T**, _Bool, int, int); … … 423 428 void __atomic_store(volatile unsigned __int128 *, unsigned __int128 *, int); 424 429 #endif 430 // for all pointer types 425 431 forall(T &) void __atomic_store_n(T * volatile *, T *, int); 426 432 forall(T &) void __atomic_store(T * volatile *, T **, int); -
libcfa/src/common.hfa
rfa5e1aa5 rb7b3e41 32 32 } // extern "C" 33 33 static inline __attribute__((always_inline)) { 34 unsigned char abs( signed char v ) { return abs( (int)v ); }34 unsigned char abs( signed char v ) { return (int)abs( (int)v ); } 35 35 // use default C routine for int 36 36 unsigned long int abs( long int v ) { return labs( v ); } … … 70 70 unsigned int min( unsigned int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; } 71 71 long int min( long int v1, long int v2 ) { return v1 < v2 ? v1 : v2; } 72 unsigned long int min( unsigned long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; }72 unsigned long int min( unsigned long int v1, unsigned long int v2 ) { return v1 < v2 ? v1 : v2; } 73 73 long long int min( long long int v1, long long int v2 ) { return v1 < v2 ? v1 : v2; } 74 unsigned long long int min( unsigned long long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; }74 unsigned long long int min( unsigned long long int v1, unsigned long long int v2 ) { return v1 < v2 ? v1 : v2; } 75 75 forall( T | { int ?<?( T, T ); } ) // generic 76 76 T min( T v1, T v2 ) { return v1 < v2 ? v1 : v2; } -
libcfa/src/concurrency/actor.hfa
rfa5e1aa5 rb7b3e41 13 13 #endif // CFA_DEBUG 14 14 15 #define DEBUG_ABORT( cond, string ) CFA_DEBUG( if ( cond ) abort( string ) ) 16 15 17 // Define the default number of processors created in the executor. Must be greater than 0. 16 18 #define __DEFAULT_EXECUTOR_PROCESSORS__ 2 … … 28 30 #define __DEFAULT_EXECUTOR_BUFSIZE__ 10 29 31 30 #define __STEAL 0// workstealing toggle. Disjoint from toggles above32 #define __STEAL 1 // workstealing toggle. Disjoint from toggles above 31 33 32 34 // workstealing heuristic selection (only set one to be 1) … … 42 44 struct executor; 43 45 44 enum Allocation { Nodelete, Delete, Destroy, Finished }; // allocation status45 46 typedef Allocation (*__receive_fn)(actor &, message &);46 enum allocation { Nodelete, Delete, Destroy, Finished }; // allocation status 47 48 typedef allocation (*__receive_fn)(actor &, message &); 47 49 struct request { 50 actor * base_receiver; 48 51 actor * receiver; 52 message * base_msg; 49 53 message * msg; 50 54 __receive_fn fn; 51 bool stop;52 55 }; 53 56 54 static inline void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel 55 static inline void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) { 57 struct a_msg { 58 int m; 59 }; 60 static inline void ?{}( request & this ) {} 61 static inline void ?{}( request & this, actor * base_receiver, actor * receiver, message * base_msg, message * msg, __receive_fn fn ) { 62 this.base_receiver = base_receiver; 56 63 this.receiver = receiver; 64 this.base_msg = base_msg; 57 65 this.msg = msg; 58 66 this.fn = fn; 59 this.stop = false;60 67 } 61 68 static inline void ?{}( request & this, request & copy ) { … … 63 70 this.msg = copy.msg; 64 71 this.fn = copy.fn; 65 this.stop = copy.stop;66 72 } 67 73 … … 81 87 last_size = 0; 82 88 } 83 static inline void ^?{}( copy_queue & this ) with(this) { adelete(buffer); } 89 static inline void ^?{}( copy_queue & this ) with(this) { 90 DEBUG_ABORT( count != 0, "Actor system terminated with messages sent but not received\n" ); 91 adelete(buffer); 92 } 84 93 85 94 static inline void insert( copy_queue & this, request & elem ) with(this) { … … 115 124 } 116 125 117 static inline bool is Empty( copy_queue & this ) with(this) { return count == 0; }126 static inline bool is_empty( copy_queue & this ) with(this) { return count == 0; } 118 127 119 128 struct work_queue { … … 176 185 volatile unsigned long long stamp; 177 186 #ifdef ACTOR_STATS 178 size_t stolen_from, try_steal, stolen, failed_swaps, msgs_stolen;187 size_t stolen_from, try_steal, stolen, empty_stolen, failed_swaps, msgs_stolen; 179 188 unsigned long long processed; 180 189 size_t gulps; … … 189 198 this.gulps = 0; // number of gulps 190 199 this.failed_swaps = 0; // steal swap failures 200 this.empty_stolen = 0; // queues empty after steal 191 201 this.msgs_stolen = 0; // number of messages stolen 192 202 #endif … … 208 218 #ifdef ACTOR_STATS 209 219 // aggregate counters for statistics 210 size_t __total_tries = 0, __total_stolen = 0, __total_workers, __all_gulps = 0, 220 size_t __total_tries = 0, __total_stolen = 0, __total_workers, __all_gulps = 0, __total_empty_stolen = 0, 211 221 __total_failed_swaps = 0, __all_processed = 0, __num_actors_stats = 0, __all_msgs_stolen = 0; 212 222 #endif … … 233 243 unsigned int nprocessors, nworkers, nrqueues; // number of processors/threads/request queues 234 244 bool seperate_clus; // use same or separate cluster for executor 245 volatile bool is_shutdown; // flag to communicate shutdown to worker threads 235 246 }; // executor 236 247 … … 246 257 __atomic_add_fetch(&__total_stolen, executor_->w_infos[id].stolen, __ATOMIC_SEQ_CST); 247 258 __atomic_add_fetch(&__total_failed_swaps, executor_->w_infos[id].failed_swaps, __ATOMIC_SEQ_CST); 259 __atomic_add_fetch(&__total_empty_stolen, executor_->w_infos[id].empty_stolen, __ATOMIC_SEQ_CST); 248 260 249 261 // per worker steal stats (uncomment alongside the lock above this routine to print) … … 272 284 this.nrqueues = nrqueues; 273 285 this.seperate_clus = seperate_clus; 286 this.is_shutdown = false; 274 287 275 288 if ( nworkers == nrqueues ) … … 320 333 321 334 static inline void ^?{}( executor & this ) with(this) { 322 #ifdef __STEAL 323 request sentinels[nrqueues]; 324 for ( unsigned int i = 0; i < nrqueues; i++ ) { 325 insert( request_queues[i], sentinels[i] ); // force eventually termination 326 } // for 327 #else 328 request sentinels[nworkers]; 329 unsigned int reqPerWorker = nrqueues / nworkers, extras = nrqueues % nworkers; 330 for ( unsigned int i = 0, step = 0, range; i < nworkers; i += 1, step += range ) { 331 range = reqPerWorker + ( i < extras ? 1 : 0 ); 332 insert( request_queues[step], sentinels[i] ); // force eventually termination 333 } // for 334 #endif 335 is_shutdown = true; 335 336 336 337 for ( i; nworkers ) … … 363 364 size_t avg_gulps = __all_gulps == 0 ? 0 : __all_processed / __all_gulps; 364 365 printf("\tGulps:\t\t\t\t\t%lu\n\tAverage Gulp Size:\t\t\t%lu\n\tMissed gulps:\t\t\t\t%lu\n", __all_gulps, avg_gulps, misses); 365 printf("\tSteal attempts:\t\t\t\t%lu\n\tSteals:\t\t\t\t\t%lu\n\tSteal failures (no candidates):\t\t%lu\n\tSteal failures (failed swaps):\t\t%lu\ n",366 __total_tries, __total_stolen, __total_tries - __total_stolen - __total_failed_swaps, __total_failed_swaps );366 printf("\tSteal attempts:\t\t\t\t%lu\n\tSteals:\t\t\t\t\t%lu\n\tSteal failures (no candidates):\t\t%lu\n\tSteal failures (failed swaps):\t\t%lu\t Empty steals:\t\t%lu\n", 367 __total_tries, __total_stolen, __total_tries - __total_stolen - __total_failed_swaps, __total_failed_swaps, __total_empty_stolen); 367 368 size_t avg_steal = __total_stolen == 0 ? 0 : __all_msgs_stolen / __total_stolen; 368 369 printf("\tMessages stolen:\t\t\t%lu\n\tAverage steal size:\t\t\t%lu\n", __all_msgs_stolen, avg_steal); … … 393 394 struct actor { 394 395 size_t ticket; // executor-queue handle 395 Allocation allocation_; // allocation action396 allocation allocation_; // allocation action 396 397 inline virtual_dtor; 397 398 }; … … 400 401 // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive 401 402 // member must be called to end it 402 verifyf( __actor_executor_, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" );403 DEBUG_ABORT( __actor_executor_ == 0p, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" ); 403 404 allocation_ = Nodelete; 404 405 ticket = __get_next_ticket( *__actor_executor_ ); … … 430 431 431 432 struct message { 432 Allocation allocation_; // allocation action433 allocation allocation_; // allocation action 433 434 inline virtual_dtor; 434 435 }; … … 437 438 this.allocation_ = Nodelete; 438 439 } 439 static inline void ?{}( message & this, Allocation allocation) {440 memcpy( &this.allocation_, &alloc ation, sizeof(allocation) ); // optimization to elide ctor441 verifyf( this.allocation_ != Finished, "The Finished Allocation status is not supported for message types.\n");440 static inline void ?{}( message & this, allocation alloc ) { 441 memcpy( &this.allocation_, &alloc, sizeof(allocation) ); // optimization to elide ctor 442 DEBUG_ABORT( this.allocation_ == Finished, "The Finished allocation status is not supported for message types.\n" ); 442 443 } 443 444 static inline void ^?{}( message & this ) with(this) { … … 447 448 static inline void check_message( message & this ) { 448 449 switch ( this.allocation_ ) { // analyze message status 449 case Nodelete: CFA_DEBUG( this.allocation_ = Finished); break;450 case Nodelete: CFA_DEBUG( this.allocation_ = Finished ); break; 450 451 case Delete: delete( &this ); break; 451 case Destroy: ^?{}( this); break;452 case Destroy: ^?{}( this ); break; 452 453 case Finished: break; 453 454 } // switch 454 455 } 455 static inline void set_allocation( message & this, Allocation state ) {456 static inline void set_allocation( message & this, allocation state ) { 456 457 this.allocation_ = state; 457 458 } 458 459 459 460 static inline void deliver_request( request & this ) { 460 this.receiver->allocation_ = this.fn( *this.receiver, *this.msg ); 461 check_message( *this.msg ); 462 check_actor( *this.receiver ); 461 DEBUG_ABORT( this.receiver->ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" ); 462 this.base_receiver->allocation_ = this.fn( *this.receiver, *this.msg ); 463 check_message( *this.base_msg ); 464 check_actor( *this.base_receiver ); 463 465 } 464 466 … … 510 512 curr_steal_queue = request_queues[ i + vic_start ]; 511 513 // avoid empty queues and queues that are being operated on 512 if ( curr_steal_queue == 0p || curr_steal_queue->being_processed || is Empty( *curr_steal_queue->c_queue ) )514 if ( curr_steal_queue == 0p || curr_steal_queue->being_processed || is_empty( *curr_steal_queue->c_queue ) ) 513 515 continue; 514 516 … … 518 520 executor_->w_infos[id].msgs_stolen += curr_steal_queue->c_queue->count; 519 521 executor_->w_infos[id].stolen++; 522 if ( is_empty( *curr_steal_queue->c_queue ) ) executor_->w_infos[id].empty_stolen++; 520 523 // __atomic_add_fetch(&executor_->w_infos[victim_id].stolen_from, 1, __ATOMIC_RELAXED); 521 524 // replaced_queue[swap_idx]++; … … 557 560 } 558 561 562 #define CHECK_TERMINATION if ( unlikely( executor_->is_shutdown ) ) break Exit 559 563 void main( worker & this ) with(this) { 560 564 // #ifdef ACTOR_STATS … … 578 582 579 583 // check if queue is empty before trying to gulp it 580 if ( is Empty( *curr_work_queue->c_queue ) ) {584 if ( is_empty( *curr_work_queue->c_queue ) ) { 581 585 #ifdef __STEAL 582 586 empty_count++; … … 591 595 #endif // ACTOR_STATS 592 596 #ifdef __STEAL 593 if ( is Empty( *current_queue ) ) {594 if ( unlikely( no_steal ) ) continue;597 if ( is_empty( *current_queue ) ) { 598 if ( unlikely( no_steal ) ) { CHECK_TERMINATION; continue; } 595 599 empty_count++; 596 600 if ( empty_count < steal_threshold ) continue; 597 601 empty_count = 0; 602 603 CHECK_TERMINATION; // check for termination 598 604 599 605 __atomic_store_n( &executor_->w_infos[id].stamp, rdtscl(), __ATOMIC_RELAXED ); … … 607 613 } 608 614 #endif // __STEAL 609 while ( ! is Empty( *current_queue ) ) {615 while ( ! is_empty( *current_queue ) ) { 610 616 #ifdef ACTOR_STATS 611 617 executor_->w_infos[id].processed++; … … 613 619 &req = &remove( *current_queue ); 614 620 if ( !&req ) continue; 615 if ( req.stop ) break Exit;616 621 deliver_request( req ); 617 622 } … … 631 636 632 637 static inline void send( actor & this, request & req ) { 633 verifyf( this.ticket != (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" );638 DEBUG_ABORT( this.ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" ); 634 639 send( *__actor_executor_, req, this.ticket ); 635 640 } … … 641 646 __all_gulps = 0; 642 647 __total_failed_swaps = 0; 648 __total_empty_stolen = 0; 643 649 __all_processed = 0; 644 650 __num_actors_stats = 0; … … 654 660 } 655 661 656 // TODO: potentially revisit getting number of processors 657 // ( currently the value stored in active_cluster()->procs.total is often stale 658 // and doesn't reflect how many procs are allocated ) 659 // static inline void start_actor_system() { start_actor_system( active_cluster()->procs.total ); } 660 static inline void start_actor_system() { start_actor_system( 1 ); } 662 static inline void start_actor_system() { start_actor_system( get_proc_count( *active_cluster() ) ); } 661 663 662 664 static inline void start_actor_system( executor & this ) { … … 668 670 669 671 static inline void stop_actor_system() { 670 park( ); // will receive signalwhen actor system is finished672 park( ); // will be unparked when actor system is finished 671 673 672 674 if ( !__actor_executor_passed ) delete( __actor_executor_ ); … … 680 682 // assigned at creation to __base_msg_finished to avoid unused message warning 681 683 message __base_msg_finished @= { .allocation_ : Finished }; 682 struct __ DeleteMsg { inline message; } DeleteMsg = __base_msg_finished;683 struct __ DestroyMsg { inline message; } DestroyMsg = __base_msg_finished;684 struct __ FinishedMsg { inline message; } FinishedMsg = __base_msg_finished;685 686 Allocation receive( actor & this, __DeleteMsg& msg ) { return Delete; }687 Allocation receive( actor & this, __DestroyMsg& msg ) { return Destroy; }688 Allocation receive( actor & this, __FinishedMsg& msg ) { return Finished; }689 684 struct __delete_msg_t { inline message; } delete_msg = __base_msg_finished; 685 struct __destroy_msg_t { inline message; } destroy_msg = __base_msg_finished; 686 struct __finished_msg_t { inline message; } finished_msg = __base_msg_finished; 687 688 allocation receive( actor & this, __delete_msg_t & msg ) { return Delete; } 689 allocation receive( actor & this, __destroy_msg_t & msg ) { return Destroy; } 690 allocation receive( actor & this, __finished_msg_t & msg ) { return Finished; } 691 -
libcfa/src/concurrency/atomic.hfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Thu May 25 15:22:46 2023 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 25 15:24:45202313 // Update Count : 112 // Last Modified On : Wed Jun 14 07:48:57 2023 13 // Update Count : 52 14 14 // 15 15 16 #define LOAD( lock ) (__atomic_load_n( &(lock), __ATOMIC_SEQ_CST )) 17 #define LOADM( lock, memorder ) (__atomic_load_n( &(lock), memorder )) 18 #define STORE( lock, assn ) (__atomic_store_n( &(lock), assn, __ATOMIC_SEQ_CST )) 19 #define STOREM( lock, assn, memorder ) (__atomic_store_n( &(lock), assn, memorder )) 20 #define CLR( lock ) (__atomic_clear( &(lock), __ATOMIC_RELEASE )) 21 #define CLRM( lock, memorder ) (__atomic_clear( &(lock), memorder )) 22 #define TAS( lock ) (__atomic_test_and_set( &(lock), __ATOMIC_ACQUIRE )) 23 #define TASM( lock, memorder ) (__atomic_test_and_set( &(lock), memorder )) 24 #define CAS( change, comp, assn ) ({typeof(comp) __temp = (comp); __atomic_compare_exchange_n( &(change), &(__temp), (assn), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); }) 25 #define CASM( change, comp, assn, memorder... ) ({typeof(comp) * __temp = &(comp); __atomic_compare_exchange_n( &(change), &(__temp), (assn), false, memorder, memorder ); }) 26 #define CASV( change, comp, assn ) (__atomic_compare_exchange_n( &(change), &(comp), (assn), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST )) 27 #define CASVM( change, comp, assn, memorder... ) (__atomic_compare_exchange_n( &(change), &(comp), (assn), false, memorder, memorder )) 28 #define FAS( change, assn ) (__atomic_exchange_n( &(change), (assn), __ATOMIC_SEQ_CST )) 29 #define FASM( change, assn, memorder ) (__atomic_exchange_n( &(change), (assn), memorder )) 30 #define FAI( change, Inc ) (__atomic_fetch_add( &(change), (Inc), __ATOMIC_SEQ_CST )) 31 #define FAIM( change, Inc, memorder ) (__atomic_fetch_add( &(change), (Inc), memorder )) 16 #define LOAD( val ) (LOADM( val, __ATOMIC_SEQ_CST)) 17 #define LOADM( val, memorder ) (__atomic_load_n( &(val), memorder)) 18 19 #define STORE( val, assn ) (STOREM( val, assn, __ATOMIC_SEQ_CST)) 20 #define STOREM( val, assn, memorder ) (__atomic_store_n( &(val), assn, memorder)) 21 22 #define TAS( lock ) (TASM( lock, __ATOMIC_ACQUIRE)) 23 #define TASM( lock, memorder ) (__atomic_test_and_set( &(lock), memorder)) 24 25 #define TASCLR( lock ) (TASCLRM( lock, __ATOMIC_RELEASE)) 26 #define TASCLRM( lock, memorder ) (__atomic_clear( &(lock), memorder)) 27 28 #define FAS( assn, replace ) (FASM(assn, replace, __ATOMIC_SEQ_CST)) 29 #define FASM( assn, replace, memorder ) (__atomic_exchange_n( &(assn), (replace), memorder)) 30 31 #define FAI( assn, Inc ) (__atomic_fetch_add( &(assn), (Inc), __ATOMIC_SEQ_CST)) 32 #define FAIM( assn, Inc, memorder ) (__atomic_fetch_add( &(assn), (Inc), memorder)) 33 34 // Use __sync because __atomic with 128-bit CAA can result in calls to pthread_mutex_lock. 35 36 // #define CAS( assn, comp, replace ) (CASM( assn, comp, replace, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) 37 // #define CASM( assn, comp, replace, memorder... ) ({ typeof(comp) __temp = (comp); __atomic_compare_exchange_n( &(assn), &(__temp), (replace), false, memorder ); }) 38 #define CAS( assn, comp, replace ) (__sync_bool_compare_and_swap( &assn, comp, replace)) 39 #define CASM( assn, comp, replace, memorder... ) _Static_assert( false, "memory order unsupported for CAS macro" ); 40 41 // #define CASV( assn, comp, replace ) (__atomic_compare_exchange_n( &(assn), &(comp), (replace), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST )) 42 // #define CASVM( assn, comp, replace, memorder... ) (__atomic_compare_exchange_n( &(assn), &(comp), (replace), false, memorder, memorder )) 43 #define CASV( assn, comp, replace ) ({ \ 44 typeof(comp) temp = comp; \ 45 typeof(comp) old = __sync_val_compare_and_swap( &(assn), (comp), (replace) ); \ 46 old == temp ? true : (comp = old, false); \ 47 }) 48 #define CASVM( assn, comp, replace, memorder... ) _Static_assert( false, "memory order unsupported for CASV macro" ); -
libcfa/src/concurrency/kernel.hfa
rfa5e1aa5 rb7b3e41 195 195 // Total number of processors 196 196 unsigned total; 197 198 // Number of processors constructed 199 // incremented at construction time, total is incremented once the processor asyncronously registers 200 unsigned constructed; 197 201 198 202 // Total number of idle processors … … 297 301 static inline struct cluster * active_cluster () { return publicTLS_get( this_processor )->cltr; } 298 302 303 // gets the number of constructed processors on the cluster 304 static inline unsigned get_proc_count( cluster & this ) { return this.procs.constructed; } 305 299 306 // set the number of internal processors 300 307 // these processors are in addition to any explicitly declared processors -
libcfa/src/concurrency/kernel/cluster.hfa
rfa5e1aa5 rb7b3e41 40 40 41 41 // convert to log2 scale but using double 42 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2( intsc); }42 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2((__readyQ_avg_t)intsc); } 43 43 44 44 #define warn_large_before warnf( !strict || old_avg < 35.0, "Suspiciously large previous average: %'lf, %'" PRId64 "ms \n", old_avg, program()`ms ) -
libcfa/src/concurrency/kernel/startup.cfa
rfa5e1aa5 rb7b3e41 528 528 this.name = name; 529 529 this.cltr = &_cltr; 530 __atomic_add_fetch( &_cltr.procs.constructed, 1u, __ATOMIC_RELAXED ); 530 531 this.rdq.its = 0; 531 532 this.rdq.itr = 0; … … 595 596 __cfadbg_print_safe(runtime_core, "Kernel : core %p signaling termination\n", &this); 596 597 598 __atomic_sub_fetch( &this.cltr->procs.constructed, 1u, __ATOMIC_RELAXED ); 599 597 600 __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED); 598 601 __disable_interrupts_checked(); … … 615 618 this.fdw = 0p; 616 619 this.idle = 0; 620 this.constructed = 0; 617 621 this.total = 0; 618 622 } -
libcfa/src/concurrency/locks.hfa
rfa5e1aa5 rb7b3e41 32 32 #include "select.hfa" 33 33 34 #include <fstream.hfa>35 36 34 // futex headers 37 35 #include <linux/futex.h> /* Definition of FUTEX_* constants */ -
libcfa/src/containers/lockfree.hfa
rfa5e1aa5 rb7b3e41 199 199 200 200 forall( T & ) 201 struct LinkData { 202 T * volatile top; // pointer to stack top 203 uintptr_t count; // count each push 204 }; 205 206 forall( T & ) 201 207 union Link { 202 struct { // 32/64-bit x 2 203 T * volatile top; // pointer to stack top 204 uintptr_t count; // count each push 205 }; 208 LinkData(T) data; 206 209 #if __SIZEOF_INT128__ == 16 207 210 __int128 // gcc, 128-bit integer … … 220 223 void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; } 221 224 222 T * top( StackLF(T) & this ) with(this) { return stack. top; }225 T * top( StackLF(T) & this ) with(this) { return stack.data.top; } 223 226 224 227 void push( StackLF(T) & this, T & n ) with(this) { 225 228 *( &n )`next = stack; // atomic assignment unnecessary, or use CAA 226 229 for () { // busy wait 227 if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ {&n, ( &n )`next->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node230 if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ (LinkData(T))@{ &n, ( &n )`next->data.count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node 228 231 } // for 229 232 } // push … … 232 235 Link(T) t @= stack; // atomic assignment unnecessary, or use CAA 233 236 for () { // busy wait 234 if ( t.top == 0p ) return 0p; // empty stack ? 235 if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {( t.top )`next->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node 237 if ( t.data.top == 0p ) return 0p; // empty stack ? 238 Link(T) * next = ( t.data.top )`next; 239 if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ (LinkData(T))@{ next->data.top, t.data.count } }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.data.top; // attempt to update top node 236 240 } // for 237 241 } // pop … … 239 243 bool unsafe_remove( StackLF(T) & this, T * node ) with(this) { 240 244 Link(T) * link = &stack; 241 for() { 242 T * next = link->top; 243 if( next == node ) { 244 link->top = ( node )`next->top; 245 for () { 246 // TODO: Avoiding some problems with double fields access. 247 LinkData(T) * data = &link->data; 248 T * next = (T *)&(*data).top; 249 if ( next == node ) { 250 data->top = ( node )`next->data.top; 245 251 return true; 246 252 } 247 if ( next == 0p ) return false;253 if ( next == 0p ) return false; 248 254 link = ( next )`next; 249 255 } -
libcfa/src/fstream.cfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 9 14:55:54 202213 // Update Count : 5 1512 // Last Modified On : Sat Jun 17 08:51:12 2023 13 // Update Count : 528 14 14 // 15 15 … … 117 117 } // for 118 118 if ( file == 0p ) { 119 throw ( Open_Failure){ os };119 throw (open_failure){ os }; 120 120 // abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno ); 121 121 } // if … … 137 137 } // for 138 138 if ( ret == EOF ) { 139 throw ( Close_Failure){ os };139 throw (close_failure){ os }; 140 140 // abort | IO_MSG "close output" | nl | strerror( errno ); 141 141 } // if … … 145 145 ofstream & write( ofstream & os, const char data[], size_t size ) { 146 146 if ( fail( os ) ) { 147 throw ( Write_Failure){ os };147 throw (write_failure){ os }; 148 148 // abort | IO_MSG "attempt write I/O on failed stream"; 149 149 } // if 150 150 151 151 if ( fwrite( data, 1, size, (FILE *)(os.file$) ) != size ) { 152 throw ( Write_Failure){ os };152 throw (write_failure){ os }; 153 153 // abort | IO_MSG "write" | nl | strerror( errno ); 154 154 } // if … … 169 169 if ( cnt == 9 ) abort( "ofstream fmt EINTR spinning exceeded" ); 170 170 } // for 171 if ( len == EOF ) { 172 if ( ferror( (FILE *)(os.file$) ) ) { 173 abort | IO_MSG "invalid write"; 174 } // if 171 if ( len == EOF ) { // error writing ? 172 abort | IO_MSG "invalid write"; 175 173 } // if 176 174 va_end( args ); … … 240 238 } // for 241 239 if ( file == 0p ) { 242 throw ( Open_Failure){ is };240 throw (open_failure){ is }; 243 241 // abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno ); 244 242 } // if … … 260 258 } // for 261 259 if ( ret == EOF ) { 262 throw ( Close_Failure){ is };260 throw (close_failure){ is }; 263 261 // abort | IO_MSG "close input" | nl | strerror( errno ); 264 262 } // if … … 268 266 ifstream & read( ifstream & is, char data[], size_t size ) { 269 267 if ( fail( is ) ) { 270 throw ( Read_Failure){ is };268 throw (read_failure){ is }; 271 269 // abort | IO_MSG "attempt read I/O on failed stream"; 272 270 } // if 273 271 274 272 if ( fread( data, size, 1, (FILE *)(is.file$) ) == 0 ) { 275 throw ( Read_Failure){ is };273 throw (read_failure){ is }; 276 274 // abort | IO_MSG "read" | nl | strerror( errno ); 277 275 } // if … … 302 300 if ( len != EOF || errno != EINTR ) break; // timer interrupt ? 303 301 } // for 304 if ( len == EOF ) { 305 if ( ferror( (FILE *)(is.file$) ) ) {302 if ( len == EOF ) { // EOF or matching failure ? 303 if ( ! feof( (FILE *)(is.file$) ) && ferror( (FILE *)(is.file$) ) ) { 306 304 abort | IO_MSG "invalid read"; 307 305 } // if … … 318 316 319 317 320 static vtable( Open_Failure) Open_Failure_vt;318 static vtable(open_failure) open_failure_vt; 321 319 322 320 // exception I/O constructors 323 void ?{}( Open_Failure & ex, ofstream & ostream ) with(ex) {324 virtual_table = & Open_Failure_vt;321 void ?{}( open_failure & ex, ofstream & ostream ) with(ex) { 322 virtual_table = &open_failure_vt; 325 323 ostream = &ostream; 326 324 tag = 1; 327 325 } // ?{} 328 326 329 void ?{}( Open_Failure & ex, ifstream & istream ) with(ex) {330 virtual_table = & Open_Failure_vt;327 void ?{}( open_failure & ex, ifstream & istream ) with(ex) { 328 virtual_table = &open_failure_vt; 331 329 istream = &istream; 332 330 tag = 0; … … 334 332 335 333 336 static vtable( Close_Failure) Close_Failure_vt;334 static vtable(close_failure) close_failure_vt; 337 335 338 336 // exception I/O constructors 339 void ?{}( Close_Failure & ex, ofstream & ostream ) with(ex) {340 virtual_table = & Close_Failure_vt;337 void ?{}( close_failure & ex, ofstream & ostream ) with(ex) { 338 virtual_table = &close_failure_vt; 341 339 ostream = &ostream; 342 340 tag = 1; 343 341 } // ?{} 344 342 345 void ?{}( Close_Failure & ex, ifstream & istream ) with(ex) {346 virtual_table = & Close_Failure_vt;343 void ?{}( close_failure & ex, ifstream & istream ) with(ex) { 344 virtual_table = &close_failure_vt; 347 345 istream = &istream; 348 346 tag = 0; … … 350 348 351 349 352 static vtable( Write_Failure) Write_Failure_vt;350 static vtable(write_failure) write_failure_vt; 353 351 354 352 // exception I/O constructors 355 void ?{}( Write_Failure & ex, ofstream & ostream ) with(ex) {356 virtual_table = & Write_Failure_vt;353 void ?{}( write_failure & ex, ofstream & ostream ) with(ex) { 354 virtual_table = &write_failure_vt; 357 355 ostream = &ostream; 358 356 tag = 1; 359 357 } // ?{} 360 358 361 void ?{}( Write_Failure & ex, ifstream & istream ) with(ex) {362 virtual_table = & Write_Failure_vt;359 void ?{}( write_failure & ex, ifstream & istream ) with(ex) { 360 virtual_table = &write_failure_vt; 363 361 istream = &istream; 364 362 tag = 0; … … 366 364 367 365 368 static vtable( Read_Failure) Read_Failure_vt;366 static vtable(read_failure) read_failure_vt; 369 367 370 368 // exception I/O constructors 371 void ?{}( Read_Failure & ex, ofstream & ostream ) with(ex) {372 virtual_table = & Read_Failure_vt;369 void ?{}( read_failure & ex, ofstream & ostream ) with(ex) { 370 virtual_table = &read_failure_vt; 373 371 ostream = &ostream; 374 372 tag = 1; 375 373 } // ?{} 376 374 377 void ?{}( Read_Failure & ex, ifstream & istream ) with(ex) {378 virtual_table = & Read_Failure_vt;375 void ?{}( read_failure & ex, ifstream & istream ) with(ex) { 376 virtual_table = &read_failure_vt; 379 377 istream = &istream; 380 378 tag = 0; 381 379 } // ?{} 382 380 383 // void throw Open_Failure( ofstream & ostream ) {384 // Open_Failure exc = { ostream };381 // void throwopen_failure( ofstream & ostream ) { 382 // open_failure exc = { ostream }; 385 383 // } 386 384 387 // void throw Open_Failure( ifstream & istream ) {388 // Open_Failure exc = { istream };385 // void throwopen_failure( ifstream & istream ) { 386 // open_failure exc = { istream }; 389 387 // } 390 388 -
libcfa/src/fstream.hfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Oct 10 09:37:32 202113 // Update Count : 24 312 // Last Modified On : Mon Jun 5 22:00:20 2023 13 // Update Count : 246 14 14 // 15 15 … … 137 137 138 138 139 exception Open_Failure {139 exception open_failure { 140 140 union { 141 141 ofstream * ostream; … … 146 146 }; 147 147 148 void ?{}( Open_Failure & this, ofstream & );149 void ?{}( Open_Failure & this, ifstream & );148 void ?{}( open_failure & this, ofstream & ); 149 void ?{}( open_failure & this, ifstream & ); 150 150 151 exception Close_Failure {151 exception close_failure { 152 152 union { 153 153 ofstream * ostream; … … 158 158 }; 159 159 160 void ?{}( Close_Failure & this, ofstream & );161 void ?{}( Close_Failure & this, ifstream & );160 void ?{}( close_failure & this, ofstream & ); 161 void ?{}( close_failure & this, ifstream & ); 162 162 163 exception Write_Failure {163 exception write_failure { 164 164 union { 165 165 ofstream * ostream; … … 170 170 }; 171 171 172 void ?{}( Write_Failure & this, ofstream & );173 void ?{}( Write_Failure & this, ifstream & );172 void ?{}( write_failure & this, ofstream & ); 173 void ?{}( write_failure & this, ifstream & ); 174 174 175 exception Read_Failure {175 exception read_failure { 176 176 union { 177 177 ofstream * ostream; … … 182 182 }; 183 183 184 void ?{}( Read_Failure & this, ofstream & );185 void ?{}( Read_Failure & this, ifstream & );184 void ?{}( read_failure & this, ofstream & ); 185 void ?{}( read_failure & this, ifstream & ); 186 186 187 187 // Local Variables: // -
libcfa/src/iostream.hfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 11:25:39202313 // Update Count : 41 012 // Last Modified On : Thu Jun 15 22:34:31 2023 13 // Update Count : 411 14 14 // 15 15 … … 51 51 int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) )); 52 52 }; // basic_ostream 53 53 54 54 forall( ostype & | basic_ostream( ostype ) ) 55 55 trait ostream { … … 68 68 69 69 forall( T, ostype & | ostream( ostype ) ) 70 70 trait writeable { 71 71 ostype & ?|?( ostype &, T ); 72 72 }; // writeable … … 161 161 // *********************************** manipulators *********************************** 162 162 163 struct _Ostream_Flags { 164 unsigned char eng:1; // engineering notation 165 unsigned char neg:1; // val is negative 166 unsigned char pc:1; // precision specified 167 unsigned char left:1; // left justify 168 unsigned char nobsdp:1; // base prefix / decimal point 169 unsigned char sign:1; // plus / minus sign 170 unsigned char pad0:1; // zero pad 171 }; 172 163 173 forall( T ) 164 174 struct _Ostream_Manip { … … 168 178 union { 169 179 unsigned char all; 170 struct { 171 unsigned char eng:1; // engineering notation 172 unsigned char neg:1; // val is negative 173 unsigned char pc:1; // precision specified 174 unsigned char left:1; // left justify 175 unsigned char nobsdp:1; // base prefix / decimal point 176 unsigned char sign:1; // plus / minus sign 177 unsigned char pad0:1; // zero pad 178 } flags; 180 _Ostream_Flags flags; 179 181 }; 180 182 }; // _Ostream_Manip -
libcfa/src/math.hfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Mon Apr 18 23:37:04 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S at Oct 8 08:40:42 202213 // Update Count : 13612 // Last Modified On : Sun Jun 18 08:13:53 2023 13 // Update Count : 202 14 14 // 15 15 … … 236 236 237 237 return (i << 32) + (sum); 238 } 238 } // log2_u32_32 239 239 240 240 //---------------------- Trigonometric ---------------------- … … 371 371 372 372 inline __attribute__((always_inline)) static { 373 signed char floor( signed char n, signed char align ) { return n / align * align; } 374 unsigned char floor( unsigned char n, unsigned char align ) { return n / align * align; } 375 short int floor( short int n, short int align ) { return n / align * align; } 376 unsigned short int floor( unsigned short int n, unsigned short int align ) { return n / align * align; } 377 int floor( int n, int align ) { return n / align * align; } 378 unsigned int floor( unsigned int n, unsigned int align ) { return n / align * align; } 379 long int floor( long int n, long int align ) { return n / align * align; } 380 unsigned long int floor( unsigned long int n, unsigned long int align ) { return n / align * align; } 381 long long int floor( long long int n, long long int align ) { return n / align * align; } 382 unsigned long long int floor( unsigned long long int n, unsigned long long int align ) { return n / align * align; } 373 // force divide before multiply 374 signed char floor( signed char n, signed char align ) { return (n / align) * align; } 375 unsigned char floor( unsigned char n, unsigned char align ) { return (n / align) * align; } 376 short int floor( short int n, short int align ) { return (n / align) * align; } 377 unsigned short int floor( unsigned short int n, unsigned short int align ) { return (n / align) * align; } 378 int floor( int n, int align ) { return (n / align) * align; } 379 unsigned int floor( unsigned int n, unsigned int align ) { return (n / align) * align; } 380 long int floor( long int n, long int align ) { return (n / align) * align; } 381 unsigned long int floor( unsigned long int n, unsigned long int align ) { return (n / align) * align; } 382 long long int floor( long long int n, long long int align ) { return (n / align) * align; } 383 unsigned long long int floor( unsigned long long int n, unsigned long long int align ) { return (n / align) * align; } 383 384 384 385 // forall( T | { T ?/?( T, T ); T ?*?( T, T ); } ) 385 // T floor( T n, T align ) { return n / align * align; } 386 387 signed char ceiling_div( signed char n, char align ) { return (n + (align - 1)) / align; } 388 unsigned char ceiling_div( unsigned char n, unsigned char align ) { return (n + (align - 1)) / align; } 389 short int ceiling_div( short int n, short int align ) { return (n + (align - 1)) / align; } 390 unsigned short int ceiling_div( unsigned short int n, unsigned short int align ) { return (n + (align - 1)) / align; } 391 int ceiling_div( int n, int align ) { return (n + (align - 1)) / align; } 392 unsigned int ceiling_div( unsigned int n, unsigned int align ) { return (n + (align - 1)) / align; } 393 long int ceiling_div( long int n, long int align ) { return (n + (align - 1)) / align; } 394 unsigned long int ceiling_div( unsigned long int n, unsigned long int align ) { return (n + (align - 1)) / align; } 395 long long int ceiling_div( long long int n, long long int align ) { return (n + (align - 1)) / align; } 396 unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1)) / align; } 397 398 // forall( T | { T ?+?( T, T ); T ?-?( T, T ); T ?%?( T, T ); } ) 399 // T ceiling_div( T n, T align ) { verify( is_pow2( align ) );return (n + (align - 1)) / align; } 400 401 // gcc notices the div/mod pair and saves both so only one div. 402 signed char ceiling( signed char n, signed char align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 403 unsigned char ceiling( unsigned char n, unsigned char align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 404 short int ceiling( short int n, short int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 405 unsigned short int ceiling( unsigned short int n, unsigned short int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 406 int ceiling( int n, int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 407 unsigned int ceiling( unsigned int n, unsigned int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 408 long int ceiling( long int n, long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 409 unsigned long int ceiling( unsigned long int n, unsigned long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0) , align); } 410 long long int ceiling( long long int n, long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 411 unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); } 412 413 // forall( T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T ); T ?/?( T, T ); } ) 414 // T ceiling( T n, T align ) { return return floor( n + (n % align != 0 ? align - 1 : 0), align ); *} 386 // T floor( T n, T align ) { return (n / align) * align; } 387 388 signed char ceiling_div( signed char n, char align ) { return (n + (align - 1hh)) / align; } 389 unsigned char ceiling_div( unsigned char n, unsigned char align ) { return (n + (align - 1hhu)) / align; } 390 short int ceiling_div( short int n, short int align ) { return (n + (align - 1h)) / align; } 391 unsigned short int ceiling_div( unsigned short int n, unsigned short int align ) { return (n + (align - 1hu)) / align; } 392 int ceiling_div( int n, int align ) { return (n + (align - 1n)) / align; } 393 unsigned int ceiling_div( unsigned int n, unsigned int align ) { return (n + (align - 1nu)) / align; } 394 long int ceiling_div( long int n, long int align ) { return (n + (align - 1l)) / align; } 395 unsigned long int ceiling_div( unsigned long int n, unsigned long int align ) { return (n + (align - 1lu)) / align; } 396 long long int ceiling_div( long long int n, long long int align ) { return (n + (align - 1ll)) / align; } 397 unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1llu)) / align; } 398 399 signed char ceiling( signed char n, char align ) { 400 typeof(n) trunc = floor( n, align ); 401 return n < 0 || n == trunc ? trunc : trunc + align; 402 } 403 unsigned char ceiling( unsigned char n, unsigned char align ) { 404 typeof(n) trunc = floor( n, align ); 405 return n == trunc ? trunc : trunc + align; 406 } 407 short int ceiling( short int n, short int align ) { 408 typeof(n) trunc = floor( n, align ); 409 return n < 0 || n == trunc ? trunc : trunc + align; 410 } 411 unsigned short int ceiling( unsigned short int n, unsigned short int align ) { 412 typeof(n) trunc = floor( n, align ); 413 return n == trunc ? trunc : trunc + align; 414 } 415 int ceiling( int n, int align ) { 416 typeof(n) trunc = floor( n, align ); 417 return n < 0 || n == trunc ? trunc : trunc + align; 418 } 419 unsigned int ceiling( unsigned int n, unsigned int align ) { 420 typeof(n) trunc = floor( n, align ); 421 return n == trunc ? trunc : trunc + align; 422 } 423 long int ceiling( long int n, long int align ) { 424 typeof(n) trunc = floor( n, align ); 425 return n < 0 || n == trunc ? trunc : trunc + align; 426 } 427 unsigned long int ceiling( unsigned long int n, unsigned long int align ) { 428 typeof(n) trunc = floor( n, align ); 429 return n == trunc ? trunc : trunc + align; 430 } 431 long long int ceiling( long long int n, signed long long int align ) { 432 typeof(n) trunc = floor( n, align ); 433 return n < 0 || n == trunc ? trunc : trunc + align; 434 } 435 unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) { 436 typeof(n) trunc = floor( n, align ); 437 return n == trunc ? trunc : trunc + align; 438 } 415 439 416 440 float floor( float x ) { return floorf( x ); } -
libcfa/src/math.trait.hfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Fri Jul 16 15:40:52 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 2 11:36:56202313 // Update Count : 2 012 // Last Modified On : Tue Jun 6 07:59:17 2023 13 // Update Count : 24 14 14 // 15 15 … … 17 17 18 18 forall( U ) 19 trait Not {19 trait not { 20 20 void ?{}( U &, zero_t ); 21 21 int !?( U ); 22 }; // Not22 }; // not 23 23 24 forall( T | Not( T ) )25 trait Equality {24 forall( T | not( T ) ) 25 trait equality { 26 26 int ?==?( T, T ); 27 27 int ?!=?( T, T ); 28 }; // Equality28 }; // equality 29 29 30 forall( U | Equality( U ) )31 trait Relational {30 forall( U | equality( U ) ) 31 trait relational { 32 32 int ?<?( U, U ); 33 33 int ?<=?( U, U ); 34 34 int ?>?( U, U ); 35 35 int ?>=?( U, U ); 36 }; // Relational36 }; // relational 37 37 38 38 forall ( T ) 39 trait Signed { 39 trait Signed { // must be capitalized, conflict with keyword signed 40 40 T +?( T ); 41 41 T -?( T ); … … 44 44 45 45 forall( U | Signed( U ) ) 46 trait Additive {46 trait additive { 47 47 U ?+?( U, U ); 48 48 U ?-?( U, U ); 49 49 U ?+=?( U &, U ); 50 50 U ?-=?( U &, U ); 51 }; // Additive51 }; // additive 52 52 53 forall( T | Additive( T ) )54 trait Incdec {53 forall( T | additive( T ) ) 54 trait inc_dec { 55 55 void ?{}( T &, one_t ); 56 56 // T ?++( T & ); … … 58 58 // T ?--( T & ); 59 59 // T --?( T & ); 60 }; // Incdec60 }; // inc_dec 61 61 62 forall( U | Incdec( U ) )63 trait Multiplicative {62 forall( U | inc_dec( U ) ) 63 trait multiplicative { 64 64 U ?*?( U, U ); 65 65 U ?/?( U, U ); 66 66 U ?%?( U, U ); 67 67 U ?/=?( U &, U ); 68 }; // Multiplicative68 }; // multiplicative 69 69 70 forall( T | Relational( T ) | Multiplicative( T ) )71 trait Arithmetic {72 }; // Arithmetic70 forall( T | relational( T ) | multiplicative( T ) ) 71 trait arithmetic { 72 }; // arithmetic 73 73 74 74 // Local Variables: // -
libcfa/src/parseconfig.cfa
rfa5e1aa5 rb7b3e41 144 144 in | nl; // ignore remainder of line 145 145 } // for 146 } catch( Open_Failure * ex; ex->istream == &in ) {146 } catch( open_failure * ex; ex->istream == &in ) { 147 147 delete( kv_pairs ); 148 148 throw *ex; … … 203 203 204 204 205 forall(T | Relational( T ))205 forall(T | relational( T )) 206 206 [ bool ] is_nonnegative( & T value ) { 207 207 T zero_val = 0; … … 209 209 } 210 210 211 forall(T | Relational( T ))211 forall(T | relational( T )) 212 212 [ bool ] is_positive( & T value ) { 213 213 T zero_val = 0; … … 215 215 } 216 216 217 forall(T | Relational( T ))217 forall(T | relational( T )) 218 218 [ bool ] is_nonpositive( & T value ) { 219 219 T zero_val = 0; … … 221 221 } 222 222 223 forall(T | Relational( T ))223 forall(T | relational( T )) 224 224 [ bool ] is_negative( & T value ) { 225 225 T zero_val = 0; -
libcfa/src/parseconfig.hfa
rfa5e1aa5 rb7b3e41 107 107 108 108 109 forall(T | Relational( T ))109 forall(T | relational( T )) 110 110 [ bool ] is_nonnegative( & T ); 111 111 112 forall(T | Relational( T ))112 forall(T | relational( T )) 113 113 [ bool ] is_positive( & T ); 114 114 115 forall(T | Relational( T ))115 forall(T | relational( T )) 116 116 [ bool ] is_nonpositive( & T ); 117 117 118 forall(T | Relational( T ))118 forall(T | relational( T )) 119 119 [ bool ] is_negative( & T ); 120 120 -
libcfa/src/rational.cfa
rfa5e1aa5 rb7b3e41 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 25 18:09:58 202213 // Update Count : 19 412 // Last Modified On : Mon Jun 5 22:49:06 2023 13 // Update Count : 196 14 14 // 15 15 … … 20 20 #pragma GCC visibility push(default) 21 21 22 forall( T | Arithmetic( T ) ) {22 forall( T | arithmetic( T ) ) { 23 23 // helper routines 24 24 … … 39 39 abort | "Invalid rational number construction: denominator cannot be equal to 0."; 40 40 } // exit 41 if ( d < (T){0} ) { d = -d; n = -n; } 41 if ( d < (T){0} ) { d = -d; n = -n; } // move sign to numerator 42 42 return gcd( abs( n ), d ); // simplify 43 } // Rationalnumber::simplify43 } // simplify 44 44 45 45 // constructors 46 46 47 void ?{}( Rational(T) & r, zero_t ) {47 void ?{}( rational(T) & r, zero_t ) { 48 48 r{ (T){0}, (T){1} }; 49 49 } // rational 50 50 51 void ?{}( Rational(T) & r, one_t ) {51 void ?{}( rational(T) & r, one_t ) { 52 52 r{ (T){1}, (T){1} }; 53 53 } // rational 54 54 55 void ?{}( Rational(T) & r ) {55 void ?{}( rational(T) & r ) { 56 56 r{ (T){0}, (T){1} }; 57 57 } // rational 58 58 59 void ?{}( Rational(T) & r, T n ) {59 void ?{}( rational(T) & r, T n ) { 60 60 r{ n, (T){1} }; 61 61 } // rational 62 62 63 void ?{}( Rational(T) & r, T n, T d ) {64 T t = simplify( n, d ); // simplify63 void ?{}( rational(T) & r, T n, T d ) { 64 T t = simplify( n, d ); // simplify 65 65 r.[numerator, denominator] = [n / t, d / t]; 66 66 } // rational … … 68 68 // getter for numerator/denominator 69 69 70 T numerator( Rational(T) r ) {70 T numerator( rational(T) r ) { 71 71 return r.numerator; 72 72 } // numerator 73 73 74 T denominator( Rational(T) r ) {74 T denominator( rational(T) r ) { 75 75 return r.denominator; 76 76 } // denominator 77 77 78 [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src ) {78 [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ) { 79 79 return dest = src.[ numerator, denominator ]; 80 80 } // ?=? … … 82 82 // setter for numerator/denominator 83 83 84 T numerator( Rational(T) r, T n ) {84 T numerator( rational(T) r, T n ) { 85 85 T prev = r.numerator; 86 T t = gcd( abs( n ), r.denominator ); 86 T t = gcd( abs( n ), r.denominator ); // simplify 87 87 r.[numerator, denominator] = [n / t, r.denominator / t]; 88 88 return prev; 89 89 } // numerator 90 90 91 T denominator( Rational(T) r, T d ) {91 T denominator( rational(T) r, T d ) { 92 92 T prev = r.denominator; 93 T t = simplify( r.numerator, d ); // simplify93 T t = simplify( r.numerator, d ); // simplify 94 94 r.[numerator, denominator] = [r.numerator / t, d / t]; 95 95 return prev; … … 98 98 // comparison 99 99 100 int ?==?( Rational(T) l, Rational(T) r ) {100 int ?==?( rational(T) l, rational(T) r ) { 101 101 return l.numerator * r.denominator == l.denominator * r.numerator; 102 102 } // ?==? 103 103 104 int ?!=?( Rational(T) l, Rational(T) r ) {104 int ?!=?( rational(T) l, rational(T) r ) { 105 105 return ! ( l == r ); 106 106 } // ?!=? 107 107 108 int ?!=?( Rational(T) l, zero_t ) {109 return ! ( l == ( Rational(T)){ 0 } );108 int ?!=?( rational(T) l, zero_t ) { 109 return ! ( l == (rational(T)){ 0 } ); 110 110 } // ?!=? 111 111 112 int ?<?( Rational(T) l, Rational(T) r ) {112 int ?<?( rational(T) l, rational(T) r ) { 113 113 return l.numerator * r.denominator < l.denominator * r.numerator; 114 114 } // ?<? 115 115 116 int ?<=?( Rational(T) l, Rational(T) r ) {116 int ?<=?( rational(T) l, rational(T) r ) { 117 117 return l.numerator * r.denominator <= l.denominator * r.numerator; 118 118 } // ?<=? 119 119 120 int ?>?( Rational(T) l, Rational(T) r ) {120 int ?>?( rational(T) l, rational(T) r ) { 121 121 return ! ( l <= r ); 122 122 } // ?>? 123 123 124 int ?>=?( Rational(T) l, Rational(T) r ) {124 int ?>=?( rational(T) l, rational(T) r ) { 125 125 return ! ( l < r ); 126 126 } // ?>=? … … 128 128 // arithmetic 129 129 130 Rational(T) +?( Rational(T) r ) {131 return ( Rational(T)){ r.numerator, r.denominator };130 rational(T) +?( rational(T) r ) { 131 return (rational(T)){ r.numerator, r.denominator }; 132 132 } // +? 133 133 134 Rational(T) -?( Rational(T) r ) {135 return ( Rational(T)){ -r.numerator, r.denominator };134 rational(T) -?( rational(T) r ) { 135 return (rational(T)){ -r.numerator, r.denominator }; 136 136 } // -? 137 137 138 Rational(T) ?+?( Rational(T) l, Rational(T) r ) {138 rational(T) ?+?( rational(T) l, rational(T) r ) { 139 139 if ( l.denominator == r.denominator ) { // special case 140 return ( Rational(T)){ l.numerator + r.numerator, l.denominator };140 return (rational(T)){ l.numerator + r.numerator, l.denominator }; 141 141 } else { 142 return ( Rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };142 return (rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 143 143 } // if 144 144 } // ?+? 145 145 146 Rational(T) ?+=?( Rational(T) & l, Rational(T) r ) {146 rational(T) ?+=?( rational(T) & l, rational(T) r ) { 147 147 l = l + r; 148 148 return l; 149 149 } // ?+? 150 150 151 Rational(T) ?+=?( Rational(T) & l, one_t ) {152 l = l + ( Rational(T)){ 1 };151 rational(T) ?+=?( rational(T) & l, one_t ) { 152 l = l + (rational(T)){ 1 }; 153 153 return l; 154 154 } // ?+? 155 155 156 Rational(T) ?-?( Rational(T) l, Rational(T) r ) {156 rational(T) ?-?( rational(T) l, rational(T) r ) { 157 157 if ( l.denominator == r.denominator ) { // special case 158 return ( Rational(T)){ l.numerator - r.numerator, l.denominator };158 return (rational(T)){ l.numerator - r.numerator, l.denominator }; 159 159 } else { 160 return ( Rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };160 return (rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator }; 161 161 } // if 162 162 } // ?-? 163 163 164 Rational(T) ?-=?( Rational(T) & l, Rational(T) r ) {164 rational(T) ?-=?( rational(T) & l, rational(T) r ) { 165 165 l = l - r; 166 166 return l; 167 167 } // ?-? 168 168 169 Rational(T) ?-=?( Rational(T) & l, one_t ) {170 l = l - ( Rational(T)){ 1 };169 rational(T) ?-=?( rational(T) & l, one_t ) { 170 l = l - (rational(T)){ 1 }; 171 171 return l; 172 172 } // ?-? 173 173 174 Rational(T) ?*?( Rational(T) l, Rational(T) r ) {175 return ( Rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };174 rational(T) ?*?( rational(T) l, rational(T) r ) { 175 return (rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator }; 176 176 } // ?*? 177 177 178 Rational(T) ?*=?( Rational(T) & l, Rational(T) r ) {178 rational(T) ?*=?( rational(T) & l, rational(T) r ) { 179 179 return l = l * r; 180 180 } // ?*? 181 181 182 Rational(T) ?/?( Rational(T) l, Rational(T) r ) {182 rational(T) ?/?( rational(T) l, rational(T) r ) { 183 183 if ( r.numerator < (T){0} ) { 184 184 r.[numerator, denominator] = [-r.numerator, -r.denominator]; 185 185 } // if 186 return ( Rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };186 return (rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator }; 187 187 } // ?/? 188 188 189 Rational(T) ?/=?( Rational(T) & l, Rational(T) r ) {189 rational(T) ?/=?( rational(T) & l, rational(T) r ) { 190 190 return l = l / r; 191 191 } // ?/? … … 194 194 195 195 forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } ) 196 istype & ?|?( istype & is, Rational(T) & r ) {196 istype & ?|?( istype & is, rational(T) & r ) { 197 197 is | r.numerator | r.denominator; 198 198 T t = simplify( r.numerator, r.denominator ); … … 203 203 204 204 forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) { 205 ostype & ?|?( ostype & os, Rational(T) r ) {205 ostype & ?|?( ostype & os, rational(T) r ) { 206 206 return os | r.numerator | '/' | r.denominator; 207 207 } // ?|? 208 208 209 void ?|?( ostype & os, Rational(T) r ) {209 void ?|?( ostype & os, rational(T) r ) { 210 210 (ostype &)(os | r); ends( os ); 211 211 } // ?|? … … 213 213 } // distribution 214 214 215 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {216 Rational(T) ?\?( Rational(T) x, long int y ) {215 forall( T | arithmetic( T ) | { T ?\?( T, unsigned long ); } ) { 216 rational(T) ?\?( rational(T) x, long int y ) { 217 217 if ( y < 0 ) { 218 return ( Rational(T)){ x.denominator \ -y, x.numerator \ -y };218 return (rational(T)){ x.denominator \ -y, x.numerator \ -y }; 219 219 } else { 220 return ( Rational(T)){ x.numerator \ y, x.denominator \ y };220 return (rational(T)){ x.numerator \ y, x.denominator \ y }; 221 221 } // if 222 222 } // ?\? 223 223 224 Rational(T) ?\=?( Rational(T) & x, long int y ) {224 rational(T) ?\=?( rational(T) & x, long int y ) { 225 225 return x = x \ y; 226 226 } // ?\? … … 229 229 // conversion 230 230 231 forall( T | Arithmetic( T ) | { double convert( T ); } )232 double widen( Rational(T) r ) {231 forall( T | arithmetic( T ) | { double convert( T ); } ) 232 double widen( rational(T) r ) { 233 233 return convert( r.numerator ) / convert( r.denominator ); 234 234 } // widen 235 235 236 forall( T | Arithmetic( T ) | { double convert( T ); T convert( double ); } )237 Rational(T) narrow( double f, T md ) {236 forall( T | arithmetic( T ) | { double convert( T ); T convert( double ); } ) 237 rational(T) narrow( double f, T md ) { 238 238 // http://www.ics.uci.edu/~eppstein/numth/frap.c 239 if ( md <= (T){1} ) { // maximum fractional digits too small?240 return ( Rational(T)){ convert( f ), (T){1}};// truncate fraction239 if ( md <= (T){1} ) { // maximum fractional digits too small? 240 return (rational(T)){ convert( f ), (T){1}}; // truncate fraction 241 241 } // if 242 242 … … 260 260 if ( f > (double)0x7FFFFFFF ) break; // representation failure 261 261 } // for 262 return ( Rational(T)){ m00, m10 };262 return (rational(T)){ m00, m10 }; 263 263 } // narrow 264 264 -
libcfa/src/rational.hfa
rfa5e1aa5 rb7b3e41 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Tue Jul 20 17:45:29 202115 // Update Count : 11 814 // Last Modified On : Mon Jun 5 22:49:05 2023 15 // Update Count : 119 16 16 // 17 17 … … 19 19 20 20 #include "iostream.hfa" 21 #include "math.trait.hfa" // Arithmetic21 #include "math.trait.hfa" // arithmetic 22 22 23 23 // implementation 24 24 25 forall( T | Arithmetic( T ) ) {26 struct Rational {25 forall( T | arithmetic( T ) ) { 26 struct rational { 27 27 T numerator, denominator; // invariant: denominator > 0 28 }; // Rational28 }; // rational 29 29 30 30 // constructors 31 31 32 void ?{}( Rational(T) & r );33 void ?{}( Rational(T) & r, zero_t );34 void ?{}( Rational(T) & r, one_t );35 void ?{}( Rational(T) & r, T n );36 void ?{}( Rational(T) & r, T n, T d );32 void ?{}( rational(T) & r ); 33 void ?{}( rational(T) & r, zero_t ); 34 void ?{}( rational(T) & r, one_t ); 35 void ?{}( rational(T) & r, T n ); 36 void ?{}( rational(T) & r, T n, T d ); 37 37 38 38 // numerator/denominator getter 39 39 40 T numerator( Rational(T) r );41 T denominator( Rational(T) r );42 [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src );40 T numerator( rational(T) r ); 41 T denominator( rational(T) r ); 42 [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ); 43 43 44 44 // numerator/denominator setter 45 45 46 T numerator( Rational(T) r, T n );47 T denominator( Rational(T) r, T d );46 T numerator( rational(T) r, T n ); 47 T denominator( rational(T) r, T d ); 48 48 49 49 // comparison 50 50 51 int ?==?( Rational(T) l, Rational(T) r );52 int ?!=?( Rational(T) l, Rational(T) r );53 int ?!=?( Rational(T) l, zero_t ); // => !54 int ?<?( Rational(T) l, Rational(T) r );55 int ?<=?( Rational(T) l, Rational(T) r );56 int ?>?( Rational(T) l, Rational(T) r );57 int ?>=?( Rational(T) l, Rational(T) r );51 int ?==?( rational(T) l, rational(T) r ); 52 int ?!=?( rational(T) l, rational(T) r ); 53 int ?!=?( rational(T) l, zero_t ); // => ! 54 int ?<?( rational(T) l, rational(T) r ); 55 int ?<=?( rational(T) l, rational(T) r ); 56 int ?>?( rational(T) l, rational(T) r ); 57 int ?>=?( rational(T) l, rational(T) r ); 58 58 59 59 // arithmetic 60 60 61 Rational(T) +?( Rational(T) r );62 Rational(T) -?( Rational(T) r );63 Rational(T) ?+?( Rational(T) l, Rational(T) r );64 Rational(T) ?+=?( Rational(T) & l, Rational(T) r );65 Rational(T) ?+=?( Rational(T) & l, one_t ); // => ++?, ?++66 Rational(T) ?-?( Rational(T) l, Rational(T) r );67 Rational(T) ?-=?( Rational(T) & l, Rational(T) r );68 Rational(T) ?-=?( Rational(T) & l, one_t ); // => --?, ?--69 Rational(T) ?*?( Rational(T) l, Rational(T) r );70 Rational(T) ?*=?( Rational(T) & l, Rational(T) r );71 Rational(T) ?/?( Rational(T) l, Rational(T) r );72 Rational(T) ?/=?( Rational(T) & l, Rational(T) r );61 rational(T) +?( rational(T) r ); 62 rational(T) -?( rational(T) r ); 63 rational(T) ?+?( rational(T) l, rational(T) r ); 64 rational(T) ?+=?( rational(T) & l, rational(T) r ); 65 rational(T) ?+=?( rational(T) & l, one_t ); // => ++?, ?++ 66 rational(T) ?-?( rational(T) l, rational(T) r ); 67 rational(T) ?-=?( rational(T) & l, rational(T) r ); 68 rational(T) ?-=?( rational(T) & l, one_t ); // => --?, ?-- 69 rational(T) ?*?( rational(T) l, rational(T) r ); 70 rational(T) ?*=?( rational(T) & l, rational(T) r ); 71 rational(T) ?/?( rational(T) l, rational(T) r ); 72 rational(T) ?/=?( rational(T) & l, rational(T) r ); 73 73 74 74 // I/O 75 75 forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } ) 76 istype & ?|?( istype &, Rational(T) & );76 istype & ?|?( istype &, rational(T) & ); 77 77 78 78 forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) { 79 ostype & ?|?( ostype &, Rational(T) );80 void ?|?( ostype &, Rational(T) );79 ostype & ?|?( ostype &, rational(T) ); 80 void ?|?( ostype &, rational(T) ); 81 81 } // distribution 82 82 } // distribution 83 83 84 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {85 Rational(T) ?\?( Rational(T) x, long int y );86 Rational(T) ?\=?( Rational(T) & x, long int y );84 forall( T | arithmetic( T ) | { T ?\?( T, unsigned long ); } ) { 85 rational(T) ?\?( rational(T) x, long int y ); 86 rational(T) ?\=?( rational(T) & x, long int y ); 87 87 } // distribution 88 88 89 89 // conversion 90 forall( T | Arithmetic( T ) | { double convert( T ); } )91 double widen( Rational(T) r );92 forall( T | Arithmetic( T ) | { double convert( T ); T convert( double );} )93 Rational(T) narrow( double f, T md );90 forall( T | arithmetic( T ) | { double convert( T ); } ) 91 double widen( rational(T) r ); 92 forall( T | arithmetic( T ) | { double convert( T ); T convert( double );} ) 93 rational(T) narrow( double f, T md ); 94 94 95 95 // Local Variables: // -
libcfa/src/stdlib.hfa
rfa5e1aa5 rb7b3e41 367 367 368 368 char random( void ) { return (unsigned long int)random(); } 369 char random( char u ) { return random( (unsigned long int)u ); } // [0,u)369 char random( char u ) { return (unsigned long int)random( (unsigned long int)u ); } // [0,u) 370 370 char random( char l, char u ) { return random( (unsigned long int)l, (unsigned long int)u ); } // [l,u) 371 371 int random( void ) { return (long int)random(); } 372 int random( int u ) { return random( (long int)u ); } // [0,u]372 int random( int u ) { return (long int)random( (long int)u ); } // [0,u] 373 373 int random( int l, int u ) { return random( (long int)l, (long int)u ); } // [l,u) 374 374 unsigned int random( void ) { return (unsigned long int)random(); } 375 unsigned int random( unsigned int u ) { return random( (unsigned long int)u ); } // [0,u]375 unsigned int random( unsigned int u ) { return (unsigned long int)random( (unsigned long int)u ); } // [0,u] 376 376 unsigned int random( unsigned int l, unsigned int u ) { return random( (unsigned long int)l, (unsigned long int)u ); } // [l,u) 377 377 } // distribution -
libcfa/src/virtual_dtor.hfa
rfa5e1aa5 rb7b3e41 25 25 __virtual_obj_start = &this; 26 26 } 27 static inline void __CFA_dtor_shutdown( virtual_dtor & this ) with(this) { 27 static inline bool __CFA_dtor_shutdown( virtual_dtor & this ) with(this) { 28 if ( __virtual_dtor_ptr == 1p ) return true; // stop base dtors from being called twice 28 29 if ( __virtual_dtor_ptr ) { 29 30 void (*dtor_ptr)(virtual_dtor &) = __virtual_dtor_ptr; 30 31 __virtual_dtor_ptr = 0p; 31 dtor_ptr(*((virtual_dtor *)__virtual_obj_start)); // replace actor with base type 32 return; 32 dtor_ptr(*((virtual_dtor *)__virtual_obj_start)); // call most derived dtor 33 __virtual_dtor_ptr = 1p; // stop base dtors from being called twice 34 return true; 33 35 } 36 return false; 34 37 } 35 38 static inline void __CFA_virt_free( virtual_dtor & this ) { free( this.__virtual_obj_start ); }
Note:
See TracChangeset
for help on using the changeset viewer.