00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_task_scheduler_observer_H
00022 #define __TBB_task_scheduler_observer_H
00023
00024 #include "atomic.h"
00025 #if __TBB_TASK_ARENA
00026 #include "task_arena.h"
00027 #endif //__TBB_TASK_ARENA
00028
00029 #if __TBB_SCHEDULER_OBSERVER
00030
00031 namespace tbb {
00032 namespace interface6 {
00033 class task_scheduler_observer;
00034 }
00035 namespace internal {
00036
00037 class observer_proxy;
00038 class observer_list;
00039
00040 class task_scheduler_observer_v3 {
00041 friend class observer_proxy;
00042 friend class observer_list;
00043 friend class interface6::task_scheduler_observer;
00044
00046
00047 observer_proxy* my_proxy;
00048
00050
00051 atomic<intptr_t> my_busy_count;
00052
00053 public:
00055
00059 void __TBB_EXPORTED_METHOD observe( bool state=true );
00060
00062 bool is_observing() const {return my_proxy!=NULL;}
00063
00065 task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store<relaxed>(0); }
00066
00068
00075 virtual void on_scheduler_entry( bool ) {}
00076
00078
00083 virtual void on_scheduler_exit( bool ) {}
00084
00086 virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);}
00087 };
00088
00089 }
00090
00091 #if TBB_PREVIEW_LOCAL_OBSERVER
00092 namespace interface6 {
00093 class task_scheduler_observer : public internal::task_scheduler_observer_v3 {
00094 friend class internal::task_scheduler_observer_v3;
00095 friend class internal::observer_proxy;
00096 friend class internal::observer_list;
00097
00100
00101 static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1);
00102
00104 intptr_t my_context_tag;
00105 enum { global_tag = 0, implicit_tag = 1 };
00106
00107 public:
00109
00118 task_scheduler_observer( bool local = false ) {
00119 my_busy_count.store<relaxed>(v6_trait);
00120 my_context_tag = local? implicit_tag : global_tag;
00121 }
00122
00123 #if __TBB_TASK_ARENA
00125
00128 task_scheduler_observer( task_arena & a) {
00129 my_busy_count.store<relaxed>(v6_trait);
00130 my_context_tag = (intptr_t)&a;
00131 }
00132 #endif //__TBB_TASK_ARENA
00133
00135
00138 virtual bool on_scheduler_leaving() { return true; }
00139
00141
00142
00143 virtual ~task_scheduler_observer() { if(my_proxy) observe(false);}
00144 };
00145
00146 }
00147 using interface6::task_scheduler_observer;
00148 #else
00149 typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer;
00150 #endif
00151
00152 }
00153
00154 #endif
00155
00156 #endif