- File:
-
- 1 edited
-
libcfa/src/concurrency/locks.hfa (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.hfa
r0cee082 r0348fd8 38 38 #include <unistd.h> 39 39 40 // C_TODO: cleanup this and locks.cfa 41 // - appropriate separation of interface and impl 42 // - clean up unused/unneeded locks 43 // - change messy big blocking lock from inheritance to composition to remove need for flags 40 // undef to make a number of the locks not reacquire upon waking from a condlock 41 #define REACQ 1 44 42 45 43 //----------------------------------------------------------------------------- … … 251 249 static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); } 252 250 static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; } 253 static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); } 254 255 256 //----------------------------------------------------------------------------- 257 // Exponential backoff then block lock 258 struct exp_backoff_then_block_lock { 251 static inline void on_wakeup(clh_lock & this, size_t recursion ) { 252 #ifdef REACQ 253 lock(this); 254 #endif 255 } 256 257 258 //----------------------------------------------------------------------------- 259 // Linear backoff Spinlock 260 struct linear_backoff_then_block_lock { 259 261 // Spin lock used for mutual exclusion 260 262 __spinlock_t spinlock; … … 267 269 }; 268 270 269 static inline void ?{}( exp_backoff_then_block_lock & this ) {271 static inline void ?{}( linear_backoff_then_block_lock & this ) { 270 272 this.spinlock{}; 271 273 this.blocked_threads{}; 272 274 this.lock_value = 0; 273 275 } 274 static inline void ^?{}( exp_backoff_then_block_lock & this ) {}275 // static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;276 // static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;277 278 static inline bool internal_try_lock( exp_backoff_then_block_lock & this, size_t & compare_val) with(this) {276 static inline void ^?{}( linear_backoff_then_block_lock & this ) {} 277 // static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void; 278 // static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void; 279 280 static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) { 279 281 if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { 280 282 return true; … … 283 285 } 284 286 285 static inline bool try_lock( exp_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }286 287 static inline bool try_lock_contention( exp_backoff_then_block_lock & this) with(this) {287 static inline bool try_lock(linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); } 288 289 static inline bool try_lock_contention(linear_backoff_then_block_lock & this) with(this) { 288 290 if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) { 289 291 return true; … … 292 294 } 293 295 294 static inline bool block( exp_backoff_then_block_lock & this) with(this) {296 static inline bool block(linear_backoff_then_block_lock & this) with(this) { 295 297 lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC) 296 298 if (lock_value != 2) { … … 304 306 } 305 307 306 static inline void lock( exp_backoff_then_block_lock & this) with(this) {308 static inline void lock(linear_backoff_then_block_lock & this) with(this) { 307 309 size_t compare_val = 0; 308 310 int spin = 4; … … 322 324 } 323 325 324 static inline void unlock( exp_backoff_then_block_lock & this) with(this) {326 static inline void unlock(linear_backoff_then_block_lock & this) with(this) { 325 327 if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return; 326 328 lock( spinlock __cfaabi_dbg_ctx2 ); … … 330 332 } 331 333 332 static inline void on_notify(exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); } 333 static inline size_t on_wait(exp_backoff_then_block_lock & this) { unlock(this); return 0; } 334 static inline void on_wakeup(exp_backoff_then_block_lock & this, size_t recursion ) { lock(this); } 334 static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); } 335 static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; } 336 static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) { 337 #ifdef REACQ 338 lock(this); 339 #endif 340 } 335 341 336 342 //----------------------------------------------------------------------------- … … 384 390 385 391 static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) { 386 lock( lock __cfaabi_dbg_ctx2 ); 387 insert_last( blocked_threads, *t ); 388 unlock( lock ); 392 #ifdef REACQ 393 lock( lock __cfaabi_dbg_ctx2 ); 394 insert_last( blocked_threads, *t ); 395 unlock( lock ); 396 #else 397 unpark(t); 398 #endif 389 399 } 390 400 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; } … … 543 553 } 544 554 static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; } 545 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { lock(this); } 555 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { 556 #ifdef REACQ 557 lock(this); 558 #endif 559 } 546 560 547 561 … … 584 598 static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); } 585 599 static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; } 586 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {lock(this); } 600 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) { 601 #ifdef REACQ 602 lock(this); 603 #endif 604 } 587 605 588 606 //----------------------------------------------------------------------------- … … 622 640 623 641 static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) { 642 #ifdef REACQ 624 643 // first we acquire internal fast_block_lock 625 644 lock( lock __cfaabi_dbg_ctx2 ); … … 633 652 unlock( lock ); 634 653 654 #endif 635 655 unpark(t); 656 636 657 } 637 658 static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; } 638 659 static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) { 660 #ifdef REACQ 639 661 // now we acquire the entire block_spin_lock upon waking up 640 662 while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause(); 641 663 __atomic_store_n(&held, true, __ATOMIC_RELEASE); 642 664 unlock( lock ); // Now we release the internal fast_spin_lock 665 #endif 643 666 } 644 667
Note:
See TracChangeset
for help on using the changeset viewer.