| 585 | } |
| 586 | |
| 587 | void generic_scheduler::nested_arena_exit(nested_arena_context& c) { |
| 588 | if( my_arena == c.my_orig_state.my_arena ) { |
| 589 | #if __TBB_TASK_GROUP_CONTEXT |
| 590 | free_task<small_local_task>(*(task*)c.my_orig_ptr); // TODO: use scoped_task instead? |
| 591 | #endif |
| 592 | return; |
| 593 | } |
| 594 | if( c.my_adjusting ) my_arena->my_market->adjust_demand(*my_arena, 1); |
| 595 | #if __TBB_ARENA_OBSERVER |
| 596 | my_arena->my_observers.notify_exit_observers( my_last_local_observer, /*worker=*/false ); |
| 597 | #endif /* __TBB_SCHEDULER_OBSERVER */ |
| 598 | |
| 599 | #if __TBB_TASK_PRIORITY |
| 600 | if ( my_offloaded_tasks ) |
| 601 | my_arena->orphan_offloaded_tasks( *this ); |
| 602 | my_local_reload_epoch = *c.my_orig_state.my_ref_reload_epoch; |
| 603 | while ( as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap( NULL, this) != this ) |
| 604 | __TBB_Yield(); // TODO: task priority can use master slot for locking while accessing the scheduler |
| 605 | #else |
| 606 | // Free the master slot. TODO: support multiple masters |
| 607 | __TBB_store_with_release(my_arena->my_slots[0].my_scheduler, (generic_scheduler*)NULL); |
| 608 | #endif |
| 609 | my_arena->my_exit_monitors.notify_all_relaxed(); // TODO: fix concurrent monitor to use notify_one (test MultipleMastersPart4 fails) |
| 610 | #if __TBB_TASK_GROUP_CONTEXT |
| 611 | // restore context of dummy task |
| 612 | my_dummy_task->prefix().context = (task_group_context*)c.my_orig_ptr; |
| 613 | #endif |
| 614 | } |
| 615 | |
| 616 | void generic_scheduler::wait_until_empty() { |
| 617 | my_dummy_task->prefix().ref_count++; // prevents exit from local_wait_for_all when local work is done enforcing the stealing |
no test coverage detected