00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __TBB_task_scheduler_observer_H
00030 #define __TBB_task_scheduler_observer_H
00031
00032 #include "atomic.h"
00033 #if __TBB_TASK_ARENA
00034 #include "task_arena.h"
00035 #endif //__TBB_TASK_ARENA
00036
00037 #if __TBB_SCHEDULER_OBSERVER
00038
00039 namespace tbb {
00040 namespace interface6 {
00041 class task_scheduler_observer;
00042 }
00043 namespace internal {
00044
00045 class observer_proxy;
00046 class observer_list;
00047
00048 class task_scheduler_observer_v3 {
00049 friend class observer_proxy;
00050 friend class observer_list;
00051 friend class interface6::task_scheduler_observer;
00052
00054
00055 observer_proxy* my_proxy;
00056
00058
00059 atomic<intptr_t> my_busy_count;
00060
00061 public:
00063
00067 void __TBB_EXPORTED_METHOD observe( bool state=true );
00068
00070 bool is_observing() const {return my_proxy!=NULL;}
00071
00073 task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store<relaxed>(0); }
00074
00076
00083 virtual void on_scheduler_entry( bool ) {}
00084
00086
00091 virtual void on_scheduler_exit( bool ) {}
00092
00094 virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);}
00095 };
00096
00097 }
00098
00099 #if TBB_PREVIEW_LOCAL_OBSERVER
00100 namespace interface6 {
00101 class task_scheduler_observer : public internal::task_scheduler_observer_v3 {
00102 friend class internal::task_scheduler_observer_v3;
00103 friend class internal::observer_proxy;
00104 friend class internal::observer_list;
00105
00108
00109 static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1);
00110
00112 intptr_t my_context_tag;
00113 enum { global_tag = 0, implicit_tag = 1 };
00114
00115 public:
00117
00126 task_scheduler_observer( bool local = false ) {
00127 my_busy_count.store<relaxed>(v6_trait);
00128 my_context_tag = local? implicit_tag : global_tag;
00129 }
00130
00131 #if __TBB_TASK_ARENA
00133
00136 task_scheduler_observer( task_arena & a) {
00137 my_busy_count.store<relaxed>(v6_trait);
00138 my_context_tag = (intptr_t)&a;
00139 }
00140 #endif //__TBB_TASK_ARENA
00141
00143
00146 virtual bool on_scheduler_leaving() { return true; }
00147
00149
00150
00151 virtual ~task_scheduler_observer() { if(my_proxy) observe(false);}
00152 };
00153
00154 }
00155 using interface6::task_scheduler_observer;
00156 #else
00157 typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer;
00158 #endif
00159
00160 }
00161
00162 #endif
00163
00164 #endif