Changeset fece3d9 for libcfa/src/concurrency
- Timestamp:
- May 10, 2023, 2:46:05 PM (19 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 8fd1b7c
- Parents:
- e50fce1
- Location:
- libcfa/src/concurrency
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.cfa
re50fce1 rfece3d9 171 171 } 172 172 173 size_t on_wait( blocking_lock & this ) with( this ) {173 size_t on_wait( blocking_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) with( this ) { 174 174 lock( lock __cfaabi_dbg_ctx2 ); 175 175 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); … … 184 184 unlock( lock ); 185 185 186 p ark();186 pre_park_then_park( pp_fn, pp_datum ); 187 187 188 188 return ret; … … 396 396 } 397 397 398 static size_t block_and_get_recursion( info_thread(L) & i ) {398 static size_t block_and_get_recursion( info_thread(L) & i, __cfa_pre_park pp_fn, void * pp_datum ) { 399 399 size_t recursion_count = 0; 400 400 if ( i.lock ) { 401 401 // if lock was passed get recursion count to reset to after waking thread 402 recursion_count = on_wait( *i.lock ); // this call blocks403 } else p ark();402 recursion_count = on_wait( *i.lock, pp_fn, pp_datum ); // this call blocks 403 } else pre_park_then_park( pp_fn, pp_datum ); 404 404 return recursion_count; 405 405 } 406 static size_t block_and_get_recursion( info_thread(L) & i ) { return block_and_get_recursion( i, pre_park_noop, 0p ); } 406 407 407 408 // helper for wait()'s' with no timeout … … 424 425 queue_info_thread( this, i ); 425 426 427 static void cond_alarm_register( void * node_ptr ) { register_self( (alarm_node_t *)node_ptr ); } 428 426 429 // helper for wait()'s' with a timeout 427 430 static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { … … 433 436 434 437 // registers alarm outside cond lock to avoid deadlock 435 register_self( &node_wrap.alarm_node );438 // register_self( &node_wrap.alarm_node ); 436 439 437 440 // blocks here 438 size_t recursion_count = block_and_get_recursion( info );441 size_t recursion_count = block_and_get_recursion( info, cond_alarm_register, (void *)(&node_wrap.alarm_node) ); 439 442 // park(); 440 443 … … 503 506 info_thread( L ) i = { active_thread(), info, &l }; 504 507 insert_last( blocked_threads, i ); 505 size_t recursion_count = on_wait( *i.lock ); // blocks here508 size_t recursion_count = on_wait( *i.lock, pre_park_noop, 0p ); // blocks here 506 509 // park( ); 507 510 on_wakeup(*i.lock, recursion_count); … … 552 555 // return recursion_count; 553 556 // } 554 555 557 556 558 static void queue_info_thread_timeout( pthread_cond_var(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { … … 562 564 563 565 // registers alarm outside cond lock to avoid deadlock 564 register_self( &node_wrap.alarm_node );566 // register_self( &node_wrap.alarm_node ); // C_TODO: fix race: registers itself and then alarm handler calls on_notify before block_and_get_recursion is run 565 567 566 568 // blocks here 567 size_t recursion_count = block_and_get_recursion( info );569 size_t recursion_count = block_and_get_recursion( info, cond_alarm_register, (void *)(&node_wrap.alarm_node) ); 568 570 // park(); 569 571 -
libcfa/src/concurrency/locks.hfa
re50fce1 rfece3d9 44 44 // - change messy big blocking lock from inheritance to composition to remove need for flags 45 45 46 typedef void (*__cfa_pre_park)( void * ); 47 48 static inline void pre_park_noop( void * ) {} 49 50 //----------------------------------------------------------------------------- 51 // is_blocking_lock 52 forall( L & | sized(L) ) 53 trait is_blocking_lock { 54 // For synchronization locks to use when acquiring 55 void on_notify( L &, struct thread$ * ); 56 57 // For synchronization locks to use when releasing 58 size_t on_wait( L &, __cfa_pre_park pp_fn, void * pp_datum ); 59 60 // to set recursion count after getting signalled; 61 void on_wakeup( L &, size_t recursion ); 62 }; 63 64 static inline void pre_park_then_park( __cfa_pre_park pp_fn, void * pp_datum ) { 65 pp_fn( pp_datum ); 66 park(); 67 } 68 46 69 //----------------------------------------------------------------------------- 47 70 // Semaphore … … 69 92 static inline bool try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); } 70 93 static inline void unlock ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); } 71 static inline size_t on_wait ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this); }94 static inline size_t on_wait ( single_acquisition_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum ); } 72 95 static inline void on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 73 96 static inline void on_notify( single_acquisition_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); } … … 86 109 static inline bool try_lock ( owner_lock & this ) { return try_lock( (blocking_lock &)this ); } 87 110 static inline void unlock ( owner_lock & this ) { unlock ( (blocking_lock &)this ); } 88 static inline size_t on_wait ( owner_lock & this ) { return on_wait ( (blocking_lock &)this); }111 static inline size_t on_wait ( owner_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { return on_wait ( (blocking_lock &)this, pp_fn, pp_datum ); } 89 112 static inline void on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 90 113 static inline void on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); } … … 218 241 219 242 static inline void on_notify( futex_mutex & f, thread$ * t){ unpark(t); } 220 static inline size_t on_wait( futex_mutex & f ) { unlock(f); park(); return 0; } 243 static inline size_t on_wait( futex_mutex & this, __cfa_pre_park pp_fn, void * pp_datum ) { 244 unlock( this ); 245 pre_park_then_park( pp_fn, pp_datum ); 246 return 0; 247 } 221 248 222 249 // to set recursion count after getting signalled; … … 288 315 289 316 static inline void on_notify( go_mutex & f, thread$ * t){ unpark( t ); } 290 static inline size_t on_wait( go_mutex & f ) { unlock( f ); park(); return 0; } 317 static inline size_t on_wait( go_mutex & this, __cfa_pre_park pp_fn, void * pp_datum ) { 318 unlock( this ); 319 pre_park_then_park( pp_fn, pp_datum ); 320 return 0; 321 } 291 322 static inline void on_wakeup( go_mutex & f, size_t recursion ) {} 292 323 … … 362 393 363 394 static inline void on_notify( exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark( t ); } 364 static inline size_t on_wait( exp_backoff_then_block_lock & this ) { unlock( this ); park(); return 0; } 395 static inline size_t on_wait( exp_backoff_then_block_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { 396 unlock( this ); 397 pre_park_then_park( pp_fn, pp_datum ); 398 return 0; 399 } 365 400 static inline void on_wakeup( exp_backoff_then_block_lock & this, size_t recursion ) { lock( this ); } 366 401 … … 419 454 unlock( lock ); 420 455 } 421 static inline size_t on_wait( fast_block_lock & this) { unlock(this); park(); return 0; } 456 static inline size_t on_wait( fast_block_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { 457 unlock( this ); 458 pre_park_then_park( pp_fn, pp_datum ); 459 return 0; 460 } 422 461 static inline void on_wakeup( fast_block_lock & this, size_t recursion ) { } 423 462 … … 497 536 } 498 537 499 static inline void on_notify( simple_owner_lock & this, thread$ * t ) with(this) {538 static inline void on_notify( simple_owner_lock & this, thread$ * t ) with(this) { 500 539 lock( lock __cfaabi_dbg_ctx2 ); 501 540 // lock held … … 512 551 } 513 552 514 static inline size_t on_wait( simple_owner_lock & this ) with(this) {553 static inline size_t on_wait( simple_owner_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) with(this) { 515 554 lock( lock __cfaabi_dbg_ctx2 ); 516 555 /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this ); … … 524 563 active_thread()->link_node = (void *)&node; 525 564 unlock( lock ); 526 park(); 565 566 pre_park_then_park( pp_fn, pp_datum ); 527 567 528 568 return ret; … … 624 664 unpark(t); 625 665 } 626 static inline size_t on_wait( spin_queue_lock & this ) { unlock( this ); park(); return 0; } 666 static inline size_t on_wait( spin_queue_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { 667 unlock( this ); 668 pre_park_then_park( pp_fn, pp_datum ); 669 return 0; 670 } 627 671 static inline void on_wakeup( spin_queue_lock & this, size_t recursion ) { lock( this ); } 628 672 … … 665 709 666 710 static inline void on_notify( mcs_block_spin_lock & this, struct thread$ * t ) { unpark( t ); } 667 static inline size_t on_wait( mcs_block_spin_lock & this) { unlock( this ); park(); return 0; } 711 static inline size_t on_wait( mcs_block_spin_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { 712 unlock( this ); 713 pre_park_then_park( pp_fn, pp_datum ); 714 return 0; 715 } 668 716 static inline void on_wakeup( mcs_block_spin_lock & this, size_t recursion ) {lock( this ); } 669 717 … … 717 765 unpark(t); 718 766 } 719 static inline size_t on_wait( block_spin_lock & this ) { unlock( this ); park(); return 0; } 767 static inline size_t on_wait( block_spin_lock & this, __cfa_pre_park pp_fn, void * pp_datum ) { 768 unlock( this ); 769 pre_park_then_park( pp_fn, pp_datum ); 770 return 0; 771 } 720 772 static inline void on_wakeup( block_spin_lock & this, size_t recursion ) with(this) { 721 773 // now we acquire the entire block_spin_lock upon waking up … … 724 776 unlock( lock ); // Now we release the internal fast_spin_lock 725 777 } 726 727 //-----------------------------------------------------------------------------728 // is_blocking_lock729 forall( L & | sized(L) )730 trait is_blocking_lock {731 // For synchronization locks to use when acquiring732 void on_notify( L &, struct thread$ * );733 734 // For synchronization locks to use when releasing735 size_t on_wait( L & );736 737 // to set recursion count after getting signalled;738 void on_wakeup( L &, size_t recursion );739 };740 778 741 779 //-----------------------------------------------------------------------------
Note: See TracChangeset
for help on using the changeset viewer.