| 853 | #endif /* __TBB_TASK_PRIORITY */ |
| 854 | |
| 855 | inline task* generic_scheduler::get_task() { |
| 856 | __TBB_ASSERT( in_arena(), NULL ); |
| 857 | task* result = NULL; |
| 858 | size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror |
| 859 | retry: |
| 860 | __TBB_store_relaxed(my_arena_slot->tail, --T); |
| 861 | atomic_fence(); |
| 862 | if ( (intptr_t)__TBB_load_relaxed(my_arena_slot->head) > (intptr_t)T ) { |
| 863 | acquire_task_pool(); |
| 864 | size_t H = __TBB_load_relaxed(my_arena_slot->head); // mirror |
| 865 | if ( (intptr_t)H <= (intptr_t)T ) { |
| 866 | // The thief backed off - grab the task |
| 867 | result = my_arena_slot->task_pool_ptr[T]; |
| 868 | __TBB_ASSERT( !is_poisoned(result), NULL ); |
| 869 | poison_pointer( my_arena_slot->task_pool_ptr[T] ); |
| 870 | } |
| 871 | else { |
| 872 | __TBB_ASSERT ( H == __TBB_load_relaxed(my_arena_slot->head) |
| 873 | && T == __TBB_load_relaxed(my_arena_slot->tail) |
| 874 | && H == T + 1, "victim/thief arbitration algorithm failure" ); |
| 875 | } |
| 876 | if ( (intptr_t)H < (intptr_t)T ) |
| 877 | release_task_pool(); |
| 878 | else |
| 879 | reset_deque_and_leave_arena( /*locked=*/true ); |
| 880 | } |
| 881 | else { |
| 882 | __TBB_control_consistency_helper(); // on my_arena_slot->head |
| 883 | result = my_arena_slot->task_pool_ptr[T]; |
| 884 | __TBB_ASSERT( !is_poisoned(result), NULL ); |
| 885 | poison_pointer( my_arena_slot->task_pool_ptr[T] ); |
| 886 | } |
| 887 | if( result && is_proxy(*result) ) { |
| 888 | task_proxy &tp = *(task_proxy*)result; |
| 889 | result = tp.extract_task<task_proxy::pool_bit>(); |
| 890 | if( !result ) { |
| 891 | // Proxy was empty, so it's our responsibility to free it |
| 892 | free_task<small_task>(tp); |
| 893 | if ( in_arena() ) |
| 894 | goto retry; |
| 895 | __TBB_ASSERT( is_quiescent_local_task_pool_reset(), NULL ); |
| 896 | return NULL; |
| 897 | } |
| 898 | GATHER_STATISTIC( ++my_counters.proxies_executed ); |
| 899 | // Following assertion should be true because TBB 2.0 tasks never specify affinity, and hence are not proxied. |
| 900 | __TBB_ASSERT( is_version_3_task(*result), "backwards compatibility with TBB 2.0 broken" ); |
| 901 | // Task affinity has changed. |
| 902 | my_innermost_running_task = result; |
| 903 | result->note_affinity(my_affinity_id); |
| 904 | } |
| 905 | __TBB_ASSERT( result || is_quiescent_local_task_pool_reset(), NULL ); |
| 906 | return result; |
| 907 | } // generic_scheduler::get_task |
| 908 | |
| 909 | task* generic_scheduler::steal_task( arena_slot& victim_slot ) { |
| 910 | task** victim_pool = lock_task_pool( &victim_slot ); |
nothing calls this directly
no test coverage detected