| 827 | }; |
| 828 | |
| 829 | void task_arena_base::internal_wait() const { |
| 830 | __TBB_ASSERT(my_arena, NULL); |
| 831 | generic_scheduler* s = governor::local_scheduler(); |
| 832 | __TBB_ASSERT(s, "Scheduler is not initialized"); |
| 833 | __TBB_ASSERT(s->my_arena != my_arena || s->my_arena_index == 0, "task_arena::wait_until_empty() is not supported within a worker context" ); |
| 834 | if( s->my_arena == my_arena ) { |
| 835 | //unsupported, but try do something for outermost master |
| 836 | __TBB_ASSERT(s->master_outermost_level(), "unsupported"); |
| 837 | if( !s->my_arena_index ) |
| 838 | while( my_arena->num_workers_active() ) |
| 839 | s->wait_until_empty(); |
| 840 | } else for(;;) { |
| 841 | while( my_arena->my_pool_state != arena::SNAPSHOT_EMPTY ) { |
| 842 | if( !__TBB_load_with_acquire(my_arena->my_slots[0].my_scheduler) // TODO TEMP: one master, make more masters |
| 843 | && as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap(s, NULL) == NULL ) { |
| 844 | nested_arena_context a(s, my_arena, !my_master_slots, true); |
| 845 | s->wait_until_empty(); |
| 846 | } else { |
| 847 | binary_semaphore waiter; // TODO: replace by a single event notification from is_out_of_work |
| 848 | internal_enqueue( *new( task::allocate_root(__TBB_CONTEXT_ARG1(*my_context)) ) wait_task(waiter), 0 ); // TODO: priority? |
| 849 | waiter.P(); // TODO: concurrent_monitor |
| 850 | } |
| 851 | } |
| 852 | if( !my_arena->num_workers_active() && !my_arena->my_slots[0].my_scheduler) // no activity |
| 853 | break; // spin until workers active but avoid spinning in a worker |
| 854 | __TBB_Yield(); // wait until workers and master leave |
| 855 | } |
| 856 | } |
| 857 | |
| 858 | /*static*/ int task_arena_base::internal_current_slot() { |
| 859 | generic_scheduler* s = governor::local_scheduler_if_initialized(); |
nothing calls this directly
no test coverage detected