ATTENTION: This method is mostly the same as generic_scheduler::lock_task_pool(), with a little different logic of slot state checks (slot is either locked or points to our task pool). Thus if either of them is changed, consider changing the counterpart as well. **/
| 468 | to our task pool). |
| 469 | Thus if either of them is changed, consider changing the counterpart as well. **/ |
| 470 | inline void generic_scheduler::acquire_task_pool() const { |
| 471 | if ( !in_arena() ) |
| 472 | return; // we are not in arena - nothing to lock |
| 473 | bool sync_prepare_done = false; |
| 474 | for( atomic_backoff b;;b.pause() ) { |
| 475 | #if TBB_USE_ASSERT |
| 476 | __TBB_ASSERT( my_arena_slot == my_arena->my_slots + my_arena_index, "invalid arena slot index" ); |
| 477 | // Local copy of the arena slot task pool pointer is necessary for the next |
| 478 | // assertion to work correctly to exclude asynchronous state transition effect. |
| 479 | task** tp = my_arena_slot->task_pool; |
| 480 | __TBB_ASSERT( tp == LockedTaskPool || tp == my_arena_slot->task_pool_ptr, "slot ownership corrupt?" ); |
| 481 | #endif |
| 482 | if( my_arena_slot->task_pool != LockedTaskPool && |
| 483 | as_atomic(my_arena_slot->task_pool).compare_and_swap(LockedTaskPool, my_arena_slot->task_pool_ptr ) == my_arena_slot->task_pool_ptr ) |
| 484 | { |
| 485 | // We acquired our own slot |
| 486 | ITT_NOTIFY(sync_acquired, my_arena_slot); |
| 487 | break; |
| 488 | } |
| 489 | else if( !sync_prepare_done ) { |
| 490 | // Start waiting |
| 491 | ITT_NOTIFY(sync_prepare, my_arena_slot); |
| 492 | sync_prepare_done = true; |
| 493 | } |
| 494 | // Someone else acquired a lock, so pause and do exponential backoff. |
| 495 | } |
| 496 | __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "not really acquired task pool" ); |
| 497 | } // generic_scheduler::acquire_task_pool |
| 498 | |
| 499 | inline void generic_scheduler::release_task_pool() const { |
| 500 | if ( !in_arena() ) |
nothing calls this directly
no test coverage detected