MCPcopy Create free account
hub / github.com/cameron314/concurrentqueue / process

Method process

benchmarks/tbb/arena.cpp:36–131  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

34namespace internal {
35
36void arena::process( generic_scheduler& s ) {
37 __TBB_ASSERT( is_alive(my_guard), NULL );
38 __TBB_ASSERT( governor::is_set(&s), NULL );
39 __TBB_ASSERT( !s.my_innermost_running_task, NULL );
40 __TBB_ASSERT( !s.my_dispatching_task, NULL );
41
42 __TBB_ASSERT( my_num_slots != 1, NULL );
43 // Start search for an empty slot from the one we occupied the last time
44 unsigned index = s.my_arena_index < my_num_slots ? s.my_arena_index : s.my_random.get() % (my_num_slots - 1) + 1,
45 end = index;
46 __TBB_ASSERT( index != 0, "A worker cannot occupy slot 0" );
47 __TBB_ASSERT( index < my_num_slots, NULL );
48
49 // Find a vacant slot
50 for ( ;; ) {
51 if ( !my_slots[index].my_scheduler && as_atomic(my_slots[index].my_scheduler).compare_and_swap(&s, NULL ) == NULL )
52 break;
53 if ( ++index == my_num_slots )
54 index = 1;
55 if ( index == end ) {
56 // Likely this arena is already saturated
57 goto quit;
58 }
59 }
60 ITT_NOTIFY(sync_acquired, my_slots + index);
61 s.my_arena = this;
62 s.my_arena_index = index;
63 s.my_arena_slot = my_slots + index;
64#if __TBB_TASK_PRIORITY
65 s.my_local_reload_epoch = *s.my_ref_reload_epoch;
66 __TBB_ASSERT( !s.my_offloaded_tasks, NULL );
67#endif /* __TBB_TASK_PRIORITY */
68 s.attach_mailbox( affinity_id(index+1) );
69
70 s.my_arena_slot->hint_for_pop = index; // initial value for round-robin
71
72#if !__TBB_FP_CONTEXT
73 my_cpu_ctl_env.set_env();
74#endif
75
76#if __TBB_SCHEDULER_OBSERVER
77 __TBB_ASSERT( !s.my_last_local_observer, "There cannot be notified local observers when entering arena" );
78 my_observers.notify_entry_observers( s.my_last_local_observer, /*worker=*/true );
79#endif /* __TBB_SCHEDULER_OBSERVER */
80
81 atomic_update( my_limit, index + 1, std::less<unsigned>() );
82
83 for ( ;; ) {
84 // Try to steal a task.
85 // Passing reference count is technically unnecessary in this context,
86 // but omitting it here would add checks inside the function.
87 __TBB_ASSERT( is_alive(my_guard), NULL );
88 task* t = s.receive_or_steal_task( s.my_dummy_task->prefix().ref_count, /*return_if_no_work=*/true );
89 if (t) {
90 // A side effect of receive_or_steal_task is that my_innermost_running_task can be set.
91 // But for the outermost dispatch loop of a worker it has to be NULL.
92 s.my_innermost_running_task = NULL;
93 __TBB_ASSERT( !s.my_dispatching_task, NULL );

Callers 1

runMethod · 0.45

Calls 15

is_aliveFunction · 0.85
is_setFunction · 0.85
atomic_updateFunction · 0.85
__TBB_load_relaxedFunction · 0.85
num_workers_activeFunction · 0.85
__TBB_store_with_releaseFunction · 0.85
attach_mailboxMethod · 0.80
notify_exit_observersMethod · 0.80
is_idle_stateMethod · 0.80
getMethod · 0.45
compare_and_swapMethod · 0.45

Tested by

no test coverage detected