- Timestamp:
- May 8, 2023, 6:21:10 PM (22 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 02fa55e
- Parents:
- 84018e0
- Location:
- libcfa/src/concurrency
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified libcfa/src/concurrency/channel.hfa ¶
r84018e0 rc4f411e 350 350 #endif 351 351 352 // check if we can complete operation. If so race to establish winner in special OR case 353 if ( !node.park_counter && ( count != 0 || !prods`isEmpty || unlikely(closed) ) ) { 354 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering 355 unlock( mutex_lock ); 356 return false; 352 if ( !node.park_counter ) { 353 // are we special case OR and front of cons is also special case OR 354 if ( !unlikely(closed) && !prods`isEmpty && prods`first.clause_status && !prods`first.park_counter ) { 355 if ( !__make_select_node_pending( node ) ) { 356 unlock( mutex_lock ); 357 return false; 358 } 359 360 if ( __handle_waituntil_OR( prods ) ) { 361 __prods_handoff( chan, ret ); 362 unlock( mutex_lock ); 363 return true; 364 } 365 __make_select_node_unsat( node ); 366 } 367 // check if we can complete operation. If so race to establish winner in special OR case 368 if ( count != 0 || !prods`isEmpty || unlikely(closed) ) { 369 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering 370 unlock( mutex_lock ); 371 return false; 372 } 357 373 } 358 374 } … … 422 438 #endif 423 439 424 // check if we can complete operation. If so race to establish winner in special OR case 425 if ( !node.park_counter && ( count != size || !cons`isEmpty || unlikely(closed) ) ) { 426 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering 427 unlock( mutex_lock ); 428 return false; 440 // special OR case handling 441 if ( !node.park_counter ) { 442 // are we special case OR and front of cons is also special case OR 443 if ( !unlikely(closed) && !cons`isEmpty && cons`first.clause_status && !cons`first.park_counter ) { 444 if ( !__make_select_node_pending( node ) ) { 445 unlock( mutex_lock ); 446 return false; 447 } 448 449 if ( __handle_waituntil_OR( cons ) ) { 450 __cons_handoff( chan, elem ); 451 unlock( mutex_lock ); 452 return true; 453 } 454 __make_select_node_unsat( node ); 455 } 456 // check if we can complete operation. If so race to establish winner in special OR case 457 if ( count != size || !cons`isEmpty || unlikely(closed) ) { 458 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering 459 unlock( mutex_lock ); 460 return false; 461 } 429 462 } 430 463 } -
TabularUnified libcfa/src/concurrency/select.hfa ¶
r84018e0 rc4f411e 2 2 3 3 #include "containers/list.hfa" 4 // #include "alarm.hfa" 4 5 #include "stdint.h" 5 6 #include "kernel.hfa" 7 #include "time.hfa" 6 8 7 9 struct select_node; … … 9 11 // node status 10 12 static const unsigned long int __SELECT_UNSAT = 0; 11 static const unsigned long int __SELECT_SAT = 1; 12 static const unsigned long int __SELECT_RUN = 2; 13 static const unsigned long int __SELECT_PENDING = 1; // used only by special OR case 14 static const unsigned long int __SELECT_SAT = 2; 15 static const unsigned long int __SELECT_RUN = 3; 13 16 17 18 // these are used inside the compiler to aid in code generation 14 19 static inline bool __CFA_has_clause_run( unsigned long int status ) { return status == __SELECT_RUN; } 15 20 static inline void __CFA_maybe_park( int * park_counter ) { … … 50 55 this.extra = extra; 51 56 } 52 53 57 static inline void ^?{}( select_node & this ) {} 54 58 59 // this is used inside the compiler to aid in code generation 55 60 static inline unsigned long int * __get_clause_status( select_node & s ) { return s.clause_status; } 61 62 // this is used inside the compiler to attempt to establish an else clause as a winner in the OR special case race 63 static inline bool __select_node_else_race( select_node & this ) with( this ) { 64 unsigned long int cmp_status = __SELECT_UNSAT; 65 return *clause_status == 0 66 && __atomic_compare_exchange_n( clause_status, &cmp_status, __SELECT_SAT, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); 67 } 56 68 57 69 //----------------------------------------------------------------------------- … … 73 85 }; 74 86 75 // this is used inside the compiler to attempt to establish an else clause as a winner in the OR special case race 76 static inline bool __select_node_else_race( select_node & this ) with( this ) { 87 //============================================================================================= 88 // Waituntil Helpers 89 //============================================================================================= 90 91 // used for the 2-stage avail needed by the special OR case 92 static inline bool __mark_select_node( select_node & this, unsigned long int val ) with( this ) { 93 /* paranoid */ verify( park_counter == 0p ); 94 /* paranoid */ verify( clause_status != 0p ); 95 77 96 unsigned long int cmp_status = __SELECT_UNSAT; 78 return *clause_status == 0 79 && __atomic_compare_exchange_n( clause_status, &cmp_status, 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); 97 while( !__atomic_compare_exchange_n( clause_status, &cmp_status, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) { 98 if ( cmp_status != __SELECT_PENDING ) return false; 99 cmp_status = __SELECT_UNSAT; 100 } 101 return true; 102 } 103 104 static inline void __make_select_node_unsat( select_node & this ) with( this ) { 105 __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST ); 106 } 107 108 static inline bool __make_select_node_pending( select_node & this ) with( this ) { 109 return __mark_select_node( this, __SELECT_PENDING ); 80 110 } 81 111 … … 83 113 // return true if we want to unpark the thd 84 114 static inline bool __make_select_node_available( select_node & this ) with( this ) { 115 /* paranoid */ verify( clause_status != 0p ); 116 if( !park_counter ) 117 return __mark_select_node( this, (unsigned long int)&this ); 118 // return *clause_status == 0 119 // && __atomic_compare_exchange_n( clause_status, &cmp_status, (unsigned long int)&this, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); // OR specific case where race was won 120 85 121 unsigned long int cmp_status = __SELECT_UNSAT; 86 122 87 if( !park_counter ) 88 return *clause_status == 0 89 && __atomic_compare_exchange_n( clause_status, &cmp_status, (unsigned long int)&this, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); // OR specific case where race was won 90 91 return *clause_status == 0 123 return *clause_status == 0 // C_TODO might not need a cmp_xchg in non special OR case 92 124 && __atomic_compare_exchange_n( clause_status, &cmp_status, __SELECT_SAT, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) // can maybe just use atomic write 93 125 && !__atomic_add_fetch( park_counter, 1, __ATOMIC_SEQ_CST); … … 128 160 } 129 161 162
Note: See TracChangeset
for help on using the changeset viewer.