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

Method observe

benchmarks/tbb/observer_proxy.cpp:351–415  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

349#endif//__TBB_SLEEP_PERMISSION
350
351void task_scheduler_observer_v3::observe( bool enable ) {
352 if( enable ) {
353 if( !my_proxy ) {
354 my_proxy = new observer_proxy( *this );
355 my_busy_count = 0; // proxy stores versioning information, clear it
356 if ( !my_proxy->is_global() ) {
357 // Local observer activation
358 generic_scheduler* s = governor::local_scheduler_if_initialized();
359#if __TBB_TASK_ARENA
360 __TBB_ASSERT( my_proxy->get_v6_observer(), NULL );
361 intptr_t tag = my_proxy->get_v6_observer()->my_context_tag;
362 if( tag != interface6::task_scheduler_observer::implicit_tag ) { // explicit arena
363 task_arena *a = reinterpret_cast<task_arena*>(tag);
364 a->initialize();
365 my_proxy->my_list = &a->my_arena->my_observers;
366 } else
367#endif
368 {
369 if( !s ) s = governor::init_scheduler( (unsigned)task_scheduler_init::automatic, 0, true );
370 __TBB_ASSERT( __TBB_InitOnce::initialization_done(), NULL );
371 __TBB_ASSERT( s && s->my_arena, NULL );
372 my_proxy->my_list = &s->my_arena->my_observers;
373 }
374 my_proxy->my_list->insert(my_proxy);
375 // Notify newly activated observer and other pending ones if it belongs to current arena
376 if(s && &s->my_arena->my_observers == my_proxy->my_list )
377 my_proxy->my_list->notify_entry_observers( s->my_last_local_observer, s->is_worker() );
378 } else {
379 // Obsolete. Global observer activation
380 if( !__TBB_InitOnce::initialization_done() )
381 DoOneTimeInitializations();
382 my_proxy->my_list = &the_global_observer_list;
383 my_proxy->my_list->insert(my_proxy);
384 if( generic_scheduler* s = governor::local_scheduler_if_initialized() ) {
385 // Notify newly created observer of its own thread.
386 // Any other pending observers are notified too.
387 the_global_observer_list.notify_entry_observers( s->my_last_global_observer, s->is_worker() );
388 }
389 }
390 }
391 } else {
392 // Make sure that possible concurrent proxy list cleanup does not conflict
393 // with the observer destruction here.
394 if ( observer_proxy* proxy = (observer_proxy*)__TBB_FetchAndStoreW(&my_proxy, 0) ) {
395 // List destruction should not touch this proxy after we've won the above interlocked exchange.
396 __TBB_ASSERT( proxy->my_observer == this, NULL );
397 __TBB_ASSERT( is_alive(proxy->my_ref_count), "Observer's proxy died prematurely" );
398 __TBB_ASSERT( proxy->my_ref_count >= 1, "reference for observer missing" );
399 observer_list &list = *proxy->my_list;
400 {
401 // Ensure that none of the list walkers relies on observer pointer validity
402 observer_list::scoped_lock lock(list.mutex(), /*is_writer=*/true);
403 proxy->my_observer = NULL;
404 // Proxy may still be held by other threads (to track the last notified observer)
405 if( !--proxy->my_ref_count ) {// nobody can increase it under exclusive lock
406 list.remove(proxy);
407 __TBB_ASSERT( !proxy->my_ref_count, NULL );
408 delete proxy;

Callers

nothing calls this directly

Calls 10

DoOneTimeInitializationsFunction · 0.85
is_aliveFunction · 0.85
is_globalMethod · 0.80
get_v6_observerMethod · 0.80
is_workerMethod · 0.80
initializeMethod · 0.45
insertMethod · 0.45
mutexMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected