Changeset 00675a1 for libcfa/src/concurrency
- Timestamp:
- May 10, 2022, 12:25:05 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 8faa6612
- Parents:
- 3b80db8 (diff), 7edd5c1 (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/src/concurrency
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/io.cfa
r3b80db8 r00675a1 244 244 245 245 remote = true; 246 __STATS__( false, io.calls.helped++; )246 __STATS__( true, io.calls.helped++; ) 247 247 } 248 248 proc->io.target = MAX; -
libcfa/src/concurrency/locks.cfa
r3b80db8 r00675a1 220 220 221 221 //----------------------------------------------------------------------------- 222 // condition variable222 // Synchronization Locks 223 223 forall(L & | is_blocking_lock(L)) { 224 224 225 //----------------------------------------------------------------------------- 226 // condition variable 225 227 void ?{}( condition_variable(L) & this ){ 226 228 this.lock{}; … … 337 339 bool wait( condition_variable(L) & this, L & l, Duration duration ) with(this) { WAIT_TIME( 0 , &l , duration ) } 338 340 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , duration ) } 341 342 //----------------------------------------------------------------------------- 343 // fast_cond_var 344 void ?{}( fast_cond_var(L) & this ){ 345 this.blocked_threads{}; 346 #ifdef __CFA_DEBUG__ 347 this.lock_used = 0p; 348 #endif 349 } 350 void ^?{}( fast_cond_var(L) & this ){ } 351 352 bool notify_one( fast_cond_var(L) & this ) with(this) { 353 bool ret = ! blocked_threads`isEmpty; 354 if ( ret ) { 355 info_thread(L) & popped = try_pop_front( blocked_threads ); 356 on_notify(*popped.lock, popped.t); 357 } 358 return ret; 359 } 360 bool notify_all( fast_cond_var(L) & this ) with(this) { 361 bool ret = ! blocked_threads`isEmpty; 362 while( ! blocked_threads`isEmpty ) { 363 info_thread(L) & popped = try_pop_front( blocked_threads ); 364 on_notify(*popped.lock, popped.t); 365 } 366 return ret; 367 } 368 369 uintptr_t front( fast_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty ? NULL : blocked_threads`first.info; } 370 bool empty ( fast_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty; } 371 372 void wait( fast_cond_var(L) & this, L & l ) { 373 wait( this, l, 0 ); 374 } 375 376 void wait( fast_cond_var(L) & this, L & l, uintptr_t info ) with(this) { 377 // brand cond lock with lock 378 #ifdef __CFA_DEBUG__ 379 if ( lock_used == 0p ) lock_used = &l; 380 else { assert(lock_used == &l); } 381 #endif 382 info_thread( L ) i = { active_thread(), info, &l }; 383 insert_last( blocked_threads, i ); 384 size_t recursion_count = on_wait( *i.lock ); 385 park( ); 386 on_wakeup(*i.lock, recursion_count); 387 } 339 388 } 340 389 -
libcfa/src/concurrency/locks.hfa
r3b80db8 r00675a1 73 73 static inline void on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); } 74 74 75 //----------------------------------------------------------------------------- 76 // MCS Lock 75 77 struct mcs_node { 76 78 mcs_node * volatile next; … … 98 100 } 99 101 102 //----------------------------------------------------------------------------- 103 // Linear backoff Spinlock 100 104 struct linear_backoff_then_block_lock { 101 105 // Spin lock used for mutual exclusion … … 199 203 200 204 //----------------------------------------------------------------------------- 205 // Fast Block Lock 206 207 // High efficiency minimal blocking lock 208 // - No reacquire for cond var 209 // - No recursive acquisition 210 // - No ownership 211 struct fast_block_lock { 212 // Spin lock used for mutual exclusion 213 __spinlock_t lock; 214 215 // List of blocked threads 216 dlist( thread$ ) blocked_threads; 217 218 bool held:1; 219 }; 220 221 static inline void ?{}( fast_block_lock & this ) with(this) { 222 lock{}; 223 blocked_threads{}; 224 held = false; 225 } 226 static inline void ^?{}( fast_block_lock & this ) {} 227 static inline void ?{}( fast_block_lock & this, fast_block_lock this2 ) = void; 228 static inline void ?=?( fast_block_lock & this, fast_block_lock this2 ) = void; 229 230 // if this is called recursively IT WILL DEADLOCK!!!!! 231 static inline void lock(fast_block_lock & this) with(this) { 232 lock( lock __cfaabi_dbg_ctx2 ); 233 if (held) { 234 insert_last( blocked_threads, *active_thread() ); 235 unlock( lock ); 236 park( ); 237 return; 238 } 239 held = true; 240 unlock( lock ); 241 } 242 243 static inline void unlock(fast_block_lock & this) with(this) { 244 lock( lock __cfaabi_dbg_ctx2 ); 245 /* paranoid */ verifyf( held != false, "Attempt to release lock %p that isn't held", &this ); 246 thread$ * t = &try_pop_front( blocked_threads ); 247 held = ( t ? true : false ); 248 unpark( t ); 249 unlock( lock ); 250 } 251 252 static inline void on_notify(fast_block_lock & this, struct thread$ * t ) { unpark(t); } 253 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; } 254 static inline void on_wakeup(fast_block_lock & this, size_t recursion ) { } 255 256 //----------------------------------------------------------------------------- 201 257 // is_blocking_lock 202 258 trait is_blocking_lock(L & | sized(L)) { … … 226 282 // Synchronization Locks 227 283 forall(L & | is_blocking_lock(L)) { 284 285 //----------------------------------------------------------------------------- 286 // condition_variable 287 288 // The multi-tool condition variable 289 // - can pass timeouts to wait for either a signal or timeout 290 // - can wait without passing a lock 291 // - can have waiters reacquire different locks while waiting on the same cond var 292 // - has shadow queue 293 // - can be signalled outside of critical sections with no locks held 228 294 struct condition_variable { 229 295 // Spin lock used for mutual exclusion … … 258 324 bool wait( condition_variable(L) & this, L & l, Duration duration ); 259 325 bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ); 260 } 326 327 //----------------------------------------------------------------------------- 328 // fast_cond_var 329 330 // The trimmed and slim condition variable 331 // - no internal lock so you must hold a lock while using this cond var 332 // - signalling without holding branded lock is UNSAFE! 333 // - only allows usage of one lock, cond var is branded after usage 334 struct fast_cond_var { 335 // List of blocked threads 336 dlist( info_thread(L) ) blocked_threads; 337 338 #ifdef __CFA_DEBUG__ 339 L * lock_used; 340 #endif 341 }; 342 343 344 void ?{}( fast_cond_var(L) & this ); 345 void ^?{}( fast_cond_var(L) & this ); 346 347 bool notify_one( fast_cond_var(L) & this ); 348 bool notify_all( fast_cond_var(L) & this ); 349 350 uintptr_t front( fast_cond_var(L) & this ); 351 352 bool empty ( fast_cond_var(L) & this ); 353 354 void wait( fast_cond_var(L) & this, L & l ); 355 void wait( fast_cond_var(L) & this, L & l, uintptr_t info ); 356 } -
libcfa/src/concurrency/ready_subqueue.hfa
r3b80db8 r00675a1 83 83 /* paranoid */ verify( node->link.ts != 0 ); 84 84 /* paranoid */ verify( this.anchor.ts != 0 ); 85 /* paranoid */ verify( (this.anchor.ts == MAX) == is_empty ); 85 86 return [node, this.anchor.ts]; 86 87 } … … 93 94 // Return the timestamp 94 95 static inline unsigned long long ts(__intrusive_lane_t & this) { 95 // Cannot verify here since it may not be locked96 // Cannot verify 'emptiness' here since it may not be locked 96 97 /* paranoid */ verify(this.anchor.ts != 0); 97 98 return this.anchor.ts;
Note:
See TracChangeset
for help on using the changeset viewer.