- File:
-
- 1 edited
-
libcfa/src/concurrency/locks.cfa (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.cfa
rbeeff61e rf5f2768 79 79 // lock is held by some other thread 80 80 if ( owner != 0p && owner != thrd ) { 81 select_node node; 82 insert_last( blocked_threads, node ); 81 insert_last( blocked_threads, *thrd ); 83 82 wait_count++; 84 83 unlock( lock ); 85 84 park( ); 86 return; 87 } else if ( owner == thrd && multi_acquisition ) { // multi acquisition lock is held by current thread 85 } 86 // multi acquisition lock is held by current thread 87 else if ( owner == thrd && multi_acquisition ) { 88 88 recursion_count++; 89 } else { // lock isn't held 89 unlock( lock ); 90 } 91 // lock isn't held 92 else { 90 93 owner = thrd; 91 94 recursion_count = 1; 92 }93 unlock( lock ); 95 unlock( lock ); 96 } 94 97 } 95 98 … … 114 117 } 115 118 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 } 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 ); 137 125 } 138 126 … … 146 134 recursion_count--; 147 135 if ( recursion_count == 0 ) { 148 pop_ node( this );136 pop_and_set_new_owner( this ); 149 137 } 150 138 unlock( lock ); … … 159 147 // lock held 160 148 if ( owner != 0p ) { 161 insert_last( blocked_threads, * (select_node *)t->link_node);149 insert_last( blocked_threads, *t ); 162 150 wait_count++; 151 unlock( lock ); 163 152 } 164 153 // lock not held … … 167 156 recursion_count = 1; 168 157 unpark( t ); 169 }170 unlock( lock ); 158 unlock( lock ); 159 } 171 160 } 172 161 … … 178 167 size_t ret = recursion_count; 179 168 180 pop_node( this ); 181 182 select_node node; 183 active_thread()->link_node = (void *)&node; 169 pop_and_set_new_owner( this ); 184 170 unlock( lock ); 185 186 park();187 188 171 return ret; 189 172 } … … 192 175 recursion_count = recursion; 193 176 } 194 195 // waituntil() support196 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 thread201 /* 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 case204 if ( !__make_select_node_available( node ) ) { // we didn't win the race so give up on registering205 unlock( lock );206 return false;207 }208 }209 210 // lock is held by some other thread211 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 thread217 recursion_count++;218 } else { // lock isn't held219 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 waiting240 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; }250 177 251 178 //----------------------------------------------------------------------------- … … 384 311 int counter( condition_variable(L) & this ) with(this) { return count; } 385 312 386 static void enqueue_thread( condition_variable(L) & this, info_thread(L) * i ) with(this) {313 static size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) { 387 314 // add info_thread to waiting queue 388 315 insert_last( blocked_threads, *i ); 389 316 count++; 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 ) { 317 size_t recursion_count = 0; 318 if (i->lock) { 401 319 // if lock was passed get recursion count to reset to after waking thread 402 recursion_count = on_wait( *i .lock ); // this call blocks403 } else park( );404 return recursion_count;405 }320 recursion_count = on_wait( *i->lock ); 321 } 322 return recursion_count; 323 } 406 324 407 325 // helper for wait()'s' with no timeout 408 326 static void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) { 409 327 lock( lock __cfaabi_dbg_ctx2 ); 410 enqueue_thread( this, &i ); 411 // size_t recursion_count = queue_and_get_recursion( this, &i ); 328 size_t recursion_count = queue_and_get_recursion(this, &i); 412 329 unlock( lock ); 413 330 414 331 // blocks here 415 size_t recursion_count = block_and_get_recursion( i ); 416 // park( ); 332 park( ); 417 333 418 334 // resets recursion count here after waking 419 if ( i.lock ) on_wakeup( *i.lock, recursion_count);335 if (i.lock) on_wakeup(*i.lock, recursion_count); 420 336 } 421 337 … … 427 343 static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 428 344 lock( lock __cfaabi_dbg_ctx2 ); 429 enqueue_thread( this, &info ); 430 // size_t recursion_count = queue_and_get_recursion( this, &info ); 345 size_t recursion_count = queue_and_get_recursion(this, &info); 431 346 alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info }; 432 347 unlock( lock ); … … 436 351 437 352 // blocks here 438 size_t recursion_count = block_and_get_recursion( info ); 439 // park(); 353 park(); 440 354 441 355 // unregisters alarm so it doesn't go off if this happens first … … 443 357 444 358 // resets recursion count here after waking 445 if ( info.lock ) on_wakeup( *info.lock, recursion_count);359 if (info.lock) on_wakeup(*info.lock, recursion_count); 446 360 } 447 361 … … 503 417 info_thread( L ) i = { active_thread(), info, &l }; 504 418 insert_last( blocked_threads, i ); 505 size_t recursion_count = on_wait( *i.lock ); // blocks here506 //park( );419 size_t recursion_count = on_wait( *i.lock ); 420 park( ); 507 421 on_wakeup(*i.lock, recursion_count); 508 422 } … … 545 459 bool empty ( pthread_cond_var(L) & this ) with(this) { return blocked_threads`isEmpty; } 546 460 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 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 } 555 468 556 469 static void queue_info_thread_timeout( pthread_cond_var(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) { 557 470 lock( lock __cfaabi_dbg_ctx2 ); 558 // size_t recursion_count = queue_and_get_recursion(this, &info); 559 insert_last( blocked_threads, info ); 471 size_t recursion_count = queue_and_get_recursion(this, &info); 560 472 pthread_alarm_node_wrap(L) node_wrap = { t, 0`s, callback, &this, &info }; 561 473 unlock( lock ); … … 565 477 566 478 // blocks here 567 size_t recursion_count = block_and_get_recursion( info ); 568 // park(); 479 park(); 569 480 570 481 // unregisters alarm so it doesn't go off if this happens first … … 572 483 573 484 // resets recursion count here after waking 574 if ( info.lock ) on_wakeup( *info.lock, recursion_count);485 if (info.lock) on_wakeup(*info.lock, recursion_count); 575 486 } 576 487 … … 582 493 lock( lock __cfaabi_dbg_ctx2 ); 583 494 info_thread( L ) i = { active_thread(), info, &l }; 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 ); 495 size_t recursion_count = queue_and_get_recursion(this, &i); 496 unlock( lock ); 497 park( ); 498 on_wakeup(*i.lock, recursion_count); 592 499 } 593 500
Note:
See TracChangeset
for help on using the changeset viewer.