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

Method bind_to

benchmarks/tbb/task_group_context.cpp:260–318  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

258}
259
260void task_group_context::bind_to ( generic_scheduler *local_sched ) {
261 __TBB_ASSERT ( __TBB_load_relaxed(my_kind) == binding_required, "Already bound or isolated?" );
262 __TBB_ASSERT ( !my_parent, "Parent is set before initial binding" );
263 my_parent = local_sched->my_innermost_running_task->prefix().context;
264#if __TBB_FP_CONTEXT
265 // Inherit FPU settings only if the context has not captured FPU settings yet.
266 if ( !(my_version_and_traits & fp_settings) )
267 copy_fp_settings(*my_parent);
268#endif
269
270 // Condition below prevents unnecessary thrashing parent context's cache line
271 if ( !(my_parent->my_state & may_have_children) )
272 my_parent->my_state |= may_have_children; // full fence is below
273 if ( my_parent->my_parent ) {
274 // Even if this context were made accessible for state change propagation
275 // (by placing __TBB_store_with_release(s->my_context_list_head.my_next, &my_node)
276 // above), it still could be missed if state propagation from a grand-ancestor
277 // was underway concurrently with binding.
278 // Speculative propagation from the parent together with epoch counters
279 // detecting possibility of such a race allow to avoid taking locks when
280 // there is no contention.
281
282 // Acquire fence is necessary to prevent reordering subsequent speculative
283 // loads of parent state data out of the scope where epoch counters comparison
284 // can reliably validate it.
285 uintptr_t local_count_snapshot = __TBB_load_with_acquire( my_parent->my_owner->my_context_state_propagation_epoch );
286 // Speculative propagation of parent's state. The speculation will be
287 // validated by the epoch counters check further on.
288 my_cancellation_requested = my_parent->my_cancellation_requested;
289#if __TBB_TASK_PRIORITY
290 my_priority = my_parent->my_priority;
291#endif /* __TBB_TASK_PRIORITY */
292 register_with( local_sched ); // Issues full fence
293
294 // If no state propagation was detected by the following condition, the above
295 // full fence guarantees that the parent had correct state during speculative
296 // propagation before the fence. Otherwise the propagation from parent is
297 // repeated under the lock.
298 if ( local_count_snapshot != the_context_state_propagation_epoch ) {
299 // Another thread may be propagating state change right now. So resort to lock.
300 context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex);
301 my_cancellation_requested = my_parent->my_cancellation_requested;
302#if __TBB_TASK_PRIORITY
303 my_priority = my_parent->my_priority;
304#endif /* __TBB_TASK_PRIORITY */
305 }
306 }
307 else {
308 register_with( local_sched ); // Issues full fence
309 // As we do not have grand-ancestors, concurrent state propagation (if any)
310 // may originate only from the parent context, and thus it is safe to directly
311 // copy the state from it.
312 my_cancellation_requested = my_parent->my_cancellation_requested;
313#if __TBB_TASK_PRIORITY
314 my_priority = my_parent->my_priority;
315#endif /* __TBB_TASK_PRIORITY */
316 }
317 __TBB_store_relaxed(my_kind, binding_completed);

Callers 2

task.cppFile · 0.80
change_groupMethod · 0.80

Calls 3

__TBB_load_relaxedFunction · 0.85
__TBB_load_with_acquireFunction · 0.85
__TBB_store_relaxedFunction · 0.85

Tested by

no test coverage detected