MCPcopy Create free account
hub / github.com/cameron314/concurrentqueue / ~task_group_context

Method ~task_group_context

benchmarks/tbb/task_group_context.cpp:140–200  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

138//------------------------------------------------------------------------
139
140task_group_context::~task_group_context () {
141 if ( __TBB_load_relaxed(my_kind) == binding_completed ) {
142 if ( governor::is_set(my_owner) ) {
143 // Local update of the context list
144 uintptr_t local_count_snapshot = my_owner->my_context_state_propagation_epoch;
145 my_owner->my_local_ctx_list_update.store<relaxed>(1);
146 // Prevent load of nonlocal update flag from being hoisted before the
147 // store to local update flag.
148 atomic_fence();
149 if ( my_owner->my_nonlocal_ctx_list_update.load<relaxed>() ) {
150 spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex);
151 my_node.my_prev->my_next = my_node.my_next;
152 my_node.my_next->my_prev = my_node.my_prev;
153 my_owner->my_local_ctx_list_update.store<relaxed>(0);
154 }
155 else {
156 my_node.my_prev->my_next = my_node.my_next;
157 my_node.my_next->my_prev = my_node.my_prev;
158 // Release fence is necessary so that update of our neighbors in
159 // the context list was committed when possible concurrent destroyer
160 // proceeds after local update flag is reset by the following store.
161 my_owner->my_local_ctx_list_update.store<release>(0);
162 if ( local_count_snapshot != the_context_state_propagation_epoch ) {
163 // Another thread was propagating cancellation request when we removed
164 // ourselves from the list. We must ensure that it is not accessing us
165 // when this destructor finishes. We'll be able to acquire the lock
166 // below only after the other thread finishes with us.
167 spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex);
168 }
169 }
170 }
171 else {
172 // Nonlocal update of the context list
173 // Synchronizes with generic_scheduler::cleanup_local_context_list()
174 // TODO: evaluate and perhaps relax, or add some lock instead
175 if ( internal::as_atomic(my_kind).fetch_and_store(dying) == detached ) {
176 my_node.my_prev->my_next = my_node.my_next;
177 my_node.my_next->my_prev = my_node.my_prev;
178 }
179 else {
180 //TODO: evaluate and perhaps relax
181 my_owner->my_nonlocal_ctx_list_update.fetch_and_increment<full_fence>();
182 //TODO: evaluate and perhaps remove
183 spin_wait_until_eq( my_owner->my_local_ctx_list_update, 0u );
184 my_owner->my_context_list_mutex.lock();
185 my_node.my_prev->my_next = my_node.my_next;
186 my_node.my_next->my_prev = my_node.my_prev;
187 my_owner->my_context_list_mutex.unlock();
188 //TODO: evaluate and perhaps relax
189 my_owner->my_nonlocal_ctx_list_update.fetch_and_decrement<full_fence>();
190 }
191 }
192 }
193#if __TBB_FP_CONTEXT
194 internal::punned_cast<cpu_ctl_env*>(&my_cpu_ctl_env)->~cpu_ctl_env();
195#endif
196 poison_value(my_version_and_traits);
197 if ( my_exception )

Callers 1

free_arenaMethod · 0.80

Calls 10

__TBB_load_relaxedFunction · 0.85
is_setFunction · 0.85
atomic_fenceFunction · 0.85
spin_wait_until_eqFunction · 0.85
poison_valueFunction · 0.85
~cpu_ctl_envMethod · 0.80
fetch_and_storeMethod · 0.45
lockMethod · 0.45
unlockMethod · 0.45
destroyMethod · 0.45

Tested by

no test coverage detected