Changeset 22b7579
- Timestamp:
- Mar 31, 2021, 1:48:15 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- c7c178b
- Parents:
- f621e43f
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/weakso_locks.cfa
rf621e43f r22b7579 18 18 #include "bits/weakso_locks.hfa" 19 19 20 void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner) {}21 void ^?{}( blocking_lock & this) {}20 void ?{}( blocking_lock &, bool, bool ) {} 21 void ^?{}( blocking_lock & ) {} 22 22 23 void lock( blocking_lock & this ) {} 24 bool try_lock( blocking_lock & this ) { return false; } 25 void unlock( blocking_lock & this ) {} 26 void on_notify( blocking_lock & this, struct $thread * t ) {} 27 void on_wait( blocking_lock & this ) {} 28 size_t wait_count( blocking_lock & this ) { return 0; } 29 void set_recursion_count( blocking_lock & this, size_t recursion ) {} 30 size_t get_recursion_count( blocking_lock & this ) { return 0; } 23 void lock( blocking_lock & ) {} 24 bool try_lock( blocking_lock & ) { return false; } 25 void unlock( blocking_lock & ) {} 26 void on_notify( blocking_lock &, struct $thread * ) {} 27 size_t on_wait( blocking_lock & ) {} 28 void on_wakeup( blocking_lock &, size_t ) {} 29 size_t wait_count( blocking_lock & ) { return 0; } -
libcfa/src/bits/weakso_locks.hfa
rf621e43f r22b7579 56 56 void unlock( blocking_lock & this ) OPTIONAL_THREAD; 57 57 void on_notify( blocking_lock & this, struct $thread * t ) OPTIONAL_THREAD; 58 void on_wait( blocking_lock & this ) OPTIONAL_THREAD; 58 size_t on_wait( blocking_lock & this ) OPTIONAL_THREAD; 59 void on_wakeup( blocking_lock & this, size_t ) OPTIONAL_THREAD; 59 60 size_t wait_count( blocking_lock & this ) OPTIONAL_THREAD; 60 void set_recursion_count( blocking_lock & this, size_t recursion ) OPTIONAL_THREAD;61 size_t get_recursion_count( blocking_lock & this ) OPTIONAL_THREAD;62 61 63 62 //---------- … … 72 71 static inline bool try_lock ( multiple_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); } 73 72 static inline void unlock ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 74 static inline void on_wait ( multiple_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); } 73 static inline size_t on_wait ( multiple_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); } 74 static inline void on_wakeup( multiple_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 75 75 static inline void on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); } 76 static inline void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }77 static inline size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } -
libcfa/src/concurrency/locks.cfa
rf621e43f r22b7579 134 134 lock( lock __cfaabi_dbg_ctx2 ); 135 135 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); 136 /* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 136 /* paranoid */ verifyf( owner == active_thread() || !strict_owner , "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 137 /* paranoid */ verifyf( recursion_count == 1 || multi_acquisition, "Thread %p attempted to release owner lock %p which is not recursive but has a recursive count of %zu", active_thread(), &this, recursion_count ); 137 138 138 139 // if recursion count is zero release lock and set new owner if one is waiting … … 146 147 size_t wait_count( blocking_lock & this ) with( this ) { 147 148 return wait_count; 148 }149 150 void set_recursion_count( blocking_lock & this, size_t recursion ) with( this ) {151 recursion_count = recursion;152 }153 154 size_t get_recursion_count( blocking_lock & this ) with( this ) {155 return recursion_count;156 149 } 157 150 … … 173 166 } 174 167 175 voidon_wait( blocking_lock & this ) with( this ) {168 size_t on_wait( blocking_lock & this ) with( this ) { 176 169 lock( lock __cfaabi_dbg_ctx2 ); 177 170 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); 178 171 /* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this ); 179 172 173 size_t ret = recursion_count; 174 180 175 pop_and_set_new_owner( this ); 181 176 unlock( lock ); 177 return ret; 178 } 179 180 void on_wakeup( blocking_lock & this, size_t recursion ) with( this ) { 181 recursion_count = recursion; 182 182 } 183 183 … … 274 274 } 275 275 276 bool empty( condition_variable(L) & this ) with(this) { return empty(blocked_threads); } 276 bool empty( condition_variable(L) & this ) with(this) { 277 lock( lock __cfaabi_dbg_ctx2 ); 278 bool ret = empty(blocked_threads); 279 unlock( lock ); 280 return ret; 281 } 277 282 278 283 int counter( condition_variable(L) & this ) with(this) { return count; } … … 285 290 if (i->lock) { 286 291 // if lock was passed get recursion count to reset to after waking thread 287 recursion_count = get_recursion_count(*i->lock); 288 on_wait( *i->lock ); 292 recursion_count = on_wait( *i->lock ); 289 293 } 290 294 return recursion_count; … … 301 305 302 306 // resets recursion count here after waking 303 if (i.lock) set_recursion_count(*i.lock, recursion_count);307 if (i.lock) on_wakeup(*i.lock, recursion_count); 304 308 } 305 309 … … 323 327 324 328 // resets recursion count here after waking 325 if (info.lock) set_recursion_count(*info.lock, recursion_count);329 if (info.lock) on_wakeup(*info.lock, recursion_count); 326 330 } 327 331 … … 373 377 } 374 378 375 bool V(semaphore & this) with( this ) {379 $thread * V (semaphore & this, const bool doUnpark ) with( this ) { 376 380 $thread * thrd = 0p; 377 381 lock( lock __cfaabi_dbg_ctx2 ); … … 385 389 386 390 // make new owner 387 unpark( thrd ); 388 391 if( doUnpark ) unpark( thrd ); 392 393 return thrd; 394 } 395 396 bool V(semaphore & this) with( this ) { 397 $thread * thrd = V(this, true); 389 398 return thrd != 0p; 390 399 } -
libcfa/src/concurrency/locks.hfa
rf621e43f r22b7579 119 119 120 120 static inline bool P(ThreadBenaphore & this) { return P(this.ben) ? false : P(this.sem); } 121 static inline bool P(ThreadBenaphore & this, $thread * t) { return P(this.ben) ? false : P(this.sem, t ); }122 121 static inline bool tryP(ThreadBenaphore & this) { return tryP(this.ben); } 123 122 static inline bool P(ThreadBenaphore & this, bool wait) { return wait ? P(this) : tryP(this); } … … 141 140 bool V (semaphore & this); 142 141 bool V (semaphore & this, unsigned count); 142 $thread * V (semaphore & this, bool ); 143 143 144 144 //---------- … … 149 149 static inline void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };} 150 150 static inline void ^?{}( single_acquisition_lock & this ) {} 151 static inline void lock ( single_acquisition_lock & this ) { lock ( (blocking_lock &)this ); } 152 static inline bool try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); } 153 static inline void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 154 static inline void on_wait ( single_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); } 155 static inline void on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } 156 static inline void set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); } 157 static inline size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); } 151 static inline void lock ( single_acquisition_lock & this ) { lock ( (blocking_lock &)this ); } 152 static inline bool try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); } 153 static inline void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 154 static inline size_t on_wait ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); } 155 static inline void on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 156 static inline void on_notify( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } 158 157 159 158 //---------- … … 167 166 static inline bool try_lock ( owner_lock & this ) { return try_lock( (blocking_lock &)this ); } 168 167 static inline void unlock ( owner_lock & this ) { unlock ( (blocking_lock &)this ); } 169 static inline void on_wait ( owner_lock & this ) { on_wait ( (blocking_lock &)this ); } 168 static inline size_t on_wait ( owner_lock & this ) { return on_wait ( (blocking_lock &)this ); } 169 static inline void on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 170 170 static inline void on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); } 171 static inline void set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }172 static inline size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }173 171 174 172 struct fast_lock { … … 182 180 } 183 181 184 static inline void $lock(fast_lock & this, $thread * thrd) { 185 /* paranoid */verify(thrd != this.owner); 186 187 for (;;) { 188 if ($try_lock(this, thrd)) return; 189 P(this.sem, thrd); 190 } 191 } 192 182 static inline void lock( fast_lock & this ) __attribute__((artificial)); 193 183 static inline void lock( fast_lock & this ) { 194 184 $thread * thrd = active_thread(); … … 201 191 } 202 192 203 static inline void try_lock ( fast_lock & this ) { 193 static inline bool try_lock( fast_lock & this ) __attribute__((artificial)); 194 static inline bool try_lock ( fast_lock & this ) { 204 195 $thread * thrd = active_thread(); 205 196 /* paranoid */ verify(thrd != this.owner); … … 207 198 } 208 199 209 static inline void unlock( fast_lock & this ) { 200 static inline $thread * unlock( fast_lock & this ) __attribute__((artificial)); 201 static inline $thread * unlock( fast_lock & this ) { 210 202 $thread * thrd = active_thread(); 211 203 /* paranoid */ verify(thrd == this.owner); 212 $thread * next = V(this.sem, false); // implicit fence 213 // open 'owner' only after fence 204 205 // open 'owner' before unlocking anyone 206 // so new and unlocked threads don't park incorrectly. 214 207 this.owner = 0p; 215 208 216 // Unpark the next person (can be 0p, unpark handles it) 217 unpark(next); 218 } 219 220 static inline void on_wait( fast_lock & this ) { 221 unlock(this); 222 #warning this is broken 223 } 224 225 static inline void on_notify( fast_lock & this, struct $thread * t ) { 226 $lock(this, t); 227 #warning this is broken 228 } 229 230 static inline void set_recursion_count( fast_lock & this, size_t recursion ) {} 231 static inline size_t get_recursion_count( fast_lock & this ) { return 0; } 209 return V(this.sem,true); 210 } 211 212 static inline size_t on_wait( fast_lock & this ) __attribute__((artificial)); 213 static inline void on_wakeup( fast_lock & this, size_t ) __attribute__((artificial)); 214 static inline void on_notify( fast_lock &, struct $thread * t ) __attribute__((artificial)); 215 216 static inline size_t on_wait( fast_lock & this ) { unlock(this); return 0; } 217 static inline void on_wakeup( fast_lock & this, size_t ) { lock(this); } 218 static inline void on_notify( fast_lock &, struct $thread * t ) { unpark(t); } 232 219 233 220 struct mcs_node { … … 263 250 264 251 // For synchronization locks to use when releasing 265 void on_wait( L & ); 266 267 // to get recursion count for cond lock to reset after waking 268 size_t get_recursion_count( L & ); 252 size_t on_wait( L & ); 269 253 270 254 // to set recursion count after getting signalled; 271 void set_recursion_count( L &, size_t recursion );255 void on_wakeup( L &, size_t recursion ); 272 256 }; 273 257 -
tests/unified_locking/.expect/locks.txt
rf621e43f r22b7579 11 11 Start Test 6: owner lock and condition variable 3 wait/notify all 12 12 Done Test 6 13 Start Test 7: multi acquisiton lock and condition variable multiple acquire andwait/notify13 Start Test 7: fast lock and condition variable single wait/notify 14 14 Done Test 7 15 Start Test 8: owner lock and condition variable multiple acquire and wait/notify15 Start Test 8: fast lock and condition variable 3 wait/notify all 16 16 Done Test 8 17 Start Test 9: no lock condition variablewait/notify17 Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify 18 18 Done Test 9 19 Start Test 10: locked condition variable wait/notify with front()19 Start Test 10: owner lock and condition variable multiple acquire and wait/notify 20 20 Done Test 10 21 Start Test 11: no lock condition variable wait/notify 22 Done Test 11 23 Start Test 12: locked condition variable wait/notify with front() 24 Done Test 12 -
tests/unified_locking/locks.cfa
rf621e43f r22b7579 15 15 condition_variable( owner_lock ) c_o; 16 16 17 fast_lock f; 18 condition_variable( fast_lock ) c_f; 19 17 20 thread T_C_M_WS1 {}; 18 21 … … 68 71 } 69 72 unlock(s); 73 } 74 } 75 76 thread T_C_F_WS1 {}; 77 78 void main( T_C_F_WS1 & this ) { 79 for (unsigned int i = 0; i < num_times; i++) { 80 lock(f); 81 if(empty(c_f) && i != num_times - 1) { 82 wait(c_f,f); 83 }else{ 84 notify_one(c_f); 85 } 86 unlock(f); 87 } 88 } 89 90 thread T_C_F_WB1 {}; 91 92 void main( T_C_F_WB1 & this ) { 93 for (unsigned int i = 0; i < num_times; i++) { 94 lock(f); 95 if(counter(c_f) == 3 || i == num_times - 1) { 96 notify_all(c_f); 97 }else{ 98 wait(c_f,f); 99 } 100 unlock(f); 70 101 } 71 102 } … … 255 286 printf("Done Test 6\n"); 256 287 257 printf("Start Test 7: multi acquisiton lock and condition variable multiple acquire and wait/notify\n"); 288 printf("Start Test 7: fast lock and condition variable single wait/notify\n"); 289 { 290 T_C_F_WS1 t1[2]; 291 } 292 printf("Done Test 7\n"); 293 294 printf("Start Test 8: fast lock and condition variable 3 wait/notify all\n"); 295 { 296 T_C_F_WB1 t1[4]; 297 } 298 printf("Done Test 8\n"); 299 300 printf("Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify\n"); 258 301 { 259 302 T_C_M_WS2 t1[2]; 260 303 } 261 printf("Done Test 7\n");262 263 printf("Start Test 8: owner lock and condition variable multiple acquire and wait/notify\n");304 printf("Done Test 9\n"); 305 306 printf("Start Test 10: owner lock and condition variable multiple acquire and wait/notify\n"); 264 307 { 265 308 T_C_O_WS2 t1[2]; 266 309 } 267 printf("Done Test 8\n");268 269 printf("Start Test 9: no lock condition variable wait/notify\n");310 printf("Done Test 10\n"); 311 312 printf("Start Test 11: no lock condition variable wait/notify\n"); 270 313 { 271 314 T_C_NLW t1; 272 315 T_C_NLS t2; 273 316 } 274 printf("Done Test 9\n");275 276 printf("Start Test 1 0: locked condition variable wait/notify with front()\n");317 printf("Done Test 11\n"); 318 319 printf("Start Test 12: locked condition variable wait/notify with front()\n"); 277 320 { 278 321 T_C_S_WNF t1[2]; 279 322 } 280 printf("Done Test 1 0\n");323 printf("Done Test 12\n"); 281 324 282 325 // removed to limit test duration. Full test is in long run tests
Note: See TracChangeset
for help on using the changeset viewer.