Changeset c4f411e for libcfa/src/concurrency/select.hfa
- Timestamp:
- May 8, 2023, 6:21:10 PM (15 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 02fa55e
- Parents:
- 84018e0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.