Changeset beeff61e for libcfa/src/concurrency/locks.cfa
- Timestamp:
- May 1, 2023, 4:00:06 PM (13 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 73bf7ddc
- Parents:
- bb7422a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.cfa
rbb7422a rbeeff61e 79 79 // lock is held by some other thread 80 80 if ( owner != 0p && owner != thrd ) { 81 insert_last( blocked_threads, *thrd ); 81 select_node node; 82 insert_last( blocked_threads, node ); 82 83 wait_count++; 83 84 unlock( lock ); 84 85 park( ); 85 } 86 // multi acquisition lock is held by current thread 87 else if ( owner == thrd && multi_acquisition ) { 86 return; 87 } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread 88 88 recursion_count++; 89 unlock( lock ); 90 } 91 // lock isn't held 92 else { 89 } else { // lock isn't held 93 90 owner = thrd; 94 91 recursion_count = 1; 95 unlock( lock );96 } 92 } 93 unlock( lock ); 97 94 } 98 95 … … 117 114 } 118 115 119 static void pop_and_set_new_owner( blocking_lock & this ) with( this ) { 120 thread$ * t = &try_pop_front( blocked_threads ); 121 owner = t; 122 recursion_count = ( t ? 1 : 0 ); 123 if ( t ) wait_count--; 124 unpark( t ); 116 // static void pop_and_set_new_owner( blocking_lock & this ) with( this ) { 117 // thread$ * t = &try_pop_front( blocked_threads ); 118 // owner = t; 119 // recursion_count = ( t ? 1 : 0 ); 120 // if ( t ) wait_count--; 121 // unpark( t ); 122 // } 123 124 static inline void pop_node( blocking_lock & this ) with( this ) { 125 __handle_waituntil_OR( blocked_threads ); 126 select_node * node = &try_pop_front( blocked_threads ); 127 if ( node ) { 128 wait_count--; 129 owner = node->blocked_thread; 130 recursion_count = 1; 131 // if ( !node->clause_status || __make_select_node_available( *node ) ) unpark( node->blocked_thread ); 132 wake_one( blocked_threads, *node ); 133 } else { 134 owner = 0p; 135 recursion_count = 0; 136 } 125 137 } 126 138 … … 134 146 recursion_count--; 135 147 if ( recursion_count == 0 ) { 136 pop_ and_set_new_owner( this );148 pop_node( this ); 137 149 } 138 150 unlock( lock ); … … 147 159 // lock held 148 160 if ( owner != 0p ) { 149 insert_last( blocked_threads, * t);161 insert_last( blocked_threads, *(select_node *)t->link_node ); 150 162 wait_count++; 151 unlock( lock );152 163 } 153 164 // lock not held … … 156 167 recursion_count = 1; 157 168 unpark( t ); 158 unlock( lock );159 } 169 } 170 unlock( lock ); 160 171 } 161 172 … … 167 178 size_t ret = recursion_count; 168 179 169 pop_and_set_new_owner( this ); 180 pop_node( this ); 181 182 select_node node; 183 active_thread()->link_node = (void *)&node; 170 184 unlock( lock ); 185 186 park(); 187 171 188 return ret; 172 189 } … … 175 192 recursion_count = recursion; 176 193 } 194 195 // waituntil() support 196 bool register_select( blocking_lock & this, select_node & node ) with(this) { 197 lock( lock __cfaabi_dbg_ctx2 ); 198 thread$ * thrd = active_thread(); 199 200 // single acquisition lock is held by current thread 201 /* paranoid */ verifyf( owner != thrd || multi_acquisition, "Single acquisition lock holder (%p) attempted to reacquire the lock %p resulting in a deadlock.", owner, &this ); 202 203 if ( !node.park_counter && ( (owner == thrd && multi_acquisition) || owner == 0p ) ) { // OR special case 204 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering 205 unlock( lock ); 206 return false; 207 } 208 } 209 210 // lock is held by some other thread 211 if ( owner != 0p && owner != thrd ) { 212 insert_last( blocked_threads, node ); 213 wait_count++; 214 unlock( lock ); 215 return false; 216 } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread 217 recursion_count++; 218 } else { // lock isn't held 219 owner = thrd; 220 recursion_count = 1; 221 } 222 223 if ( node.park_counter ) __make_select_node_available( node ); 224 unlock( lock ); 225 return true; 226 } 227 228 bool unregister_select( blocking_lock & this, select_node & node ) with(this) { 229 lock( lock __cfaabi_dbg_ctx2 ); 230 if ( node`isListed ) { 231 remove( node ); 232 wait_count--; 233 unlock( lock ); 234 return false; 235 } 236 237 if ( owner == active_thread() ) { 238 /* paranoid */ verifyf( recursion_count == 1 || multi_acquisition, "Thread %p attempted to unlock owner lock %p in waituntil unregister, which is not recursive but has a recursive count of %zu", active_thread(), &this, recursion_count ); 239 // if recursion count is zero release lock and set new owner if one is waiting 240 recursion_count--; 241 if ( recursion_count == 0 ) { 242 pop_node( this ); 243 } 244 } 245 unlock( lock ); 246 return false; 247 } 248 249 bool on_selected( blocking_lock & this, select_node & node ) { return true; } 177 250 178 251 //----------------------------------------------------------------------------- … … 311 384 int counter( condition_variable(L) & this ) with(this) { return count; } 312 385 313 static size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {386 static void enqueue_thread( condition_variable(L) & this, info_thread(L) * i ) with(this) { 314 387 // add info_thread to waiting queue 315 388 insert_last( blocked_threads, *i ); 316 389 count++; 317 size_t recursion_count = 0; 318 if (i->lock) { 390 // size_t recursion_count = 0; 391 // if (i->lock) { 392 // // if lock was passed get recursion count to reset to after waking thread 393 // recursion_count = on_wait( *i->lock ); 394 // } 395 // return recursion_count; 396 } 397 398 static size_t block_and_get_recursion( info_thread(L) & i ) { 399 size_t recursion_count = 0; 400 if ( i.lock ) { 319 401 // if lock was passed get recursion count to reset to after waking thread 320 recursion_count = on_wait( *i ->lock );321 } 322 323 402 recursion_count = on_wait( *i.lock ); // this call blocks 403 } else park( ); 404 return recursion_count; 405 } 324 406 325 407 // helper for wait()'s' with no timeout 326 408 static void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) { 327 409 lock( lock __cfaabi_dbg_ctx2 ); 328 size_t recursion_count = queue_and_get_recursion(this, &i); 410 enqueue_thread( this, &i ); 411 // size_t recursion_count = queue_and_get_recursion( this, &i ); 329 412 unlock( lock ); 330 413 331 414 // blocks here 332 park( ); 415 size_t recursion_count = block_and_get_recursion( i ); 416 // park( ); 333 417 334 418 // resets recursion count here after waking 335 if ( i.lock) on_wakeup(*i.lock, recursion_count);419 if ( i.lock ) on_wakeup( *i.lock, recursion_count ); 336 420 } 337 421 … … 343 427 static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 344 428 lock( lock __cfaabi_dbg_ctx2 ); 345 size_t recursion_count = queue_and_get_recursion(this, &info); 429 enqueue_thread( this, &info ); 430 // size_t recursion_count = queue_and_get_recursion( this, &info ); 346 431 alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info }; 347 432 unlock( lock ); … … 351 436 352 437 // blocks here 353 park(); 438 size_t recursion_count = block_and_get_recursion( info ); 439 // park(); 354 440 355 441 // unregisters alarm so it doesn't go off if this happens first … … 357 443 358 444 // resets recursion count here after waking 359 if ( info.lock) on_wakeup(*info.lock, recursion_count);445 if ( info.lock ) on_wakeup( *info.lock, recursion_count ); 360 446 } 361 447 … … 417 503 info_thread( L ) i = { active_thread(), info, &l }; 418 504 insert_last( blocked_threads, i ); 419 size_t recursion_count = on_wait( *i.lock ); 420 park( );505 size_t recursion_count = on_wait( *i.lock ); // blocks here 506 // park( ); 421 507 on_wakeup(*i.lock, recursion_count); 422 508 } … … 459 545 bool empty ( pthread_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty; } 460 546 461 static size_t queue_and_get_recursion( pthread_cond_var(L) & this, info_thread(L) * i ) with(this) { 462 // add info_thread to waiting queue 463 insert_last( blocked_threads, *i ); 464 size_t recursion_count = 0; 465 recursion_count = on_wait( *i->lock ); 466 return recursion_count; 467 } 547 // static size_t queue_and_get_recursion( pthread_cond_var(L) & this, info_thread(L) * i ) with(this) { 548 // // add info_thread to waiting queue 549 // insert_last( blocked_threads, *i ); 550 // size_t recursion_count = 0; 551 // recursion_count = on_wait( *i->lock ); 552 // return recursion_count; 553 // } 554 468 555 469 556 static void queue_info_thread_timeout( pthread_cond_var(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 470 557 lock( lock __cfaabi_dbg_ctx2 ); 471 size_t recursion_count = queue_and_get_recursion(this, &info); 558 // size_t recursion_count = queue_and_get_recursion(this, &info); 559 insert_last( blocked_threads, info ); 472 560 pthread_alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info }; 473 561 unlock( lock ); … … 477 565 478 566 // blocks here 479 park(); 567 size_t recursion_count = block_and_get_recursion( info ); 568 // park(); 480 569 481 570 // unregisters alarm so it doesn't go off if this happens first … … 483 572 484 573 // resets recursion count here after waking 485 if ( info.lock) on_wakeup(*info.lock, recursion_count);574 if ( info.lock ) on_wakeup( *info.lock, recursion_count ); 486 575 } 487 576 … … 493 582 lock( lock __cfaabi_dbg_ctx2 ); 494 583 info_thread( L ) i = { active_thread(), info, &l }; 495 size_t recursion_count = queue_and_get_recursion(this, &i); 496 unlock( lock ); 497 park( ); 498 on_wakeup(*i.lock, recursion_count); 584 insert_last( blocked_threads, i ); 585 // size_t recursion_count = queue_and_get_recursion( this, &i ); 586 unlock( lock ); 587 588 // blocks here 589 size_t recursion_count = block_and_get_recursion( i ); 590 // park(); 591 on_wakeup( *i.lock, recursion_count ); 499 592 } 500 593
Note: See TracChangeset
for help on using the changeset viewer.