00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_task_arena_H
00022 #define __TBB_task_arena_H
00023
00024 #include "task.h"
00025 #include "tbb_exception.h"
00026
00027 #if __TBB_TASK_ARENA
00028
00029 namespace tbb {
00030
00032 namespace internal {
00034
00035 class arena;
00036 class task_scheduler_observer_v3;
00037 }
00039
00040 namespace interface6 {
00042 namespace internal {
00043 using namespace tbb::internal;
00044
00045 template<typename F>
00046 class enqueued_function_task : public task {
00047 F my_func;
00048 task* execute() {
00049 my_func();
00050 return NULL;
00051 }
00052 public:
00053 enqueued_function_task ( const F& f ) : my_func(f) {}
00054 };
00055
00056 class delegate_base : no_assign {
00057 public:
00058 virtual void run() = 0;
00059 virtual ~delegate_base() {}
00060 };
00061
00062 template<typename F>
00063 class delegated_function : public delegate_base {
00064 F &my_func;
00065 void run() {
00066 my_func();
00067 }
00068 public:
00069 delegated_function ( F& f ) : my_func(f) {}
00070 };
00071 }
00073
00080 class task_arena {
00081 friend class internal::task_scheduler_observer_v3;
00083 int my_max_concurrency;
00084
00086 internal::arena* my_arena;
00087
00088
00089 internal::arena* __TBB_EXPORTED_METHOD internal_initialize( int ) const;
00090 void __TBB_EXPORTED_METHOD internal_terminate( );
00091 void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const;
00092 void __TBB_EXPORTED_METHOD internal_execute( internal::delegate_base& ) const;
00093 void __TBB_EXPORTED_METHOD internal_wait() const;
00094
00095 inline void check_init() {
00096 if( !my_arena )
00097 my_arena = internal_initialize( my_max_concurrency );
00098 }
00099
00100 public:
00102 static const int automatic = -1;
00103
00105 task_arena(int max_concurrency = automatic)
00106 : my_max_concurrency(max_concurrency)
00107 , my_arena(0)
00108 {}
00109
00111 task_arena(const task_arena &s)
00112 : my_max_concurrency(s.my_max_concurrency)
00113 , my_arena(0)
00114 {}
00115
00118 ~task_arena() {
00119 internal_terminate();
00120 }
00121
00124 template<typename F>
00125 void enqueue( const F& f ) {
00126 check_init();
00127 internal_enqueue( *new( task::allocate_root() ) internal::enqueued_function_task<F>(f), 0 );
00128 }
00129
00130 #if __TBB_TASK_PRIORITY
00133 template<typename F>
00134 void enqueue( const F& f, priority_t p ) {
00135 __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" );
00136 check_init();
00137 internal_enqueue( *new( task::allocate_root() ) internal::enqueued_function_task<F>(f), (intptr_t)p );
00138 }
00139 #endif// __TBB_TASK_PRIORITY
00140
00144 template<typename F>
00145 void execute(F& f) {
00146 check_init();
00147 internal::delegated_function<F> d(f);
00148 internal_execute( d );
00149 }
00150
00154 template<typename F>
00155 void execute(const F& f) {
00156 check_init();
00157 internal::delegated_function<const F> d(f);
00158 internal_execute( d );
00159 }
00160
00164 void wait_until_empty() {
00165 check_init();
00166 internal_wait();
00167 }
00168
00170 inline void initialize(int max_concurrency) {
00171 my_max_concurrency = max_concurrency;
00172 __TBB_ASSERT( !my_arena, "task_arena was initialized already");
00173 check_init();
00174 }
00175
00177 static int __TBB_EXPORTED_FUNC current_slot();
00178 };
00179
00180 }
00181
00182 using interface6::task_arena;
00183
00184 }
00185
00186 #endif
00187
00188 #endif