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_arena_H
00030 #define __TBB_task_arena_H
00031
00032 #include "task.h"
00033 #include "tbb_exception.h"
00034
00035 #if __TBB_TASK_ARENA
00036
00037 namespace tbb {
00038
00040 namespace internal {
00042
00043 class arena;
00044 class task_scheduler_observer_v3;
00045 }
00047
00048 namespace interface6 {
00050 namespace internal {
00051 using namespace tbb::internal;
00052
00053 template<typename F>
00054 class enqueued_function_task : public task {
00055 F my_func;
00056 task* execute() {
00057 my_func();
00058 return NULL;
00059 }
00060 public:
00061 enqueued_function_task ( const F& f ) : my_func(f) {}
00062 };
00063
00064 class delegate_base : no_assign {
00065 public:
00066 virtual void run() = 0;
00067 virtual ~delegate_base() {}
00068 };
00069
00070 template<typename F>
00071 class delegated_function : public delegate_base {
00072 F &my_func;
00073 void run() {
00074 my_func();
00075 }
00076 public:
00077 delegated_function ( F& f ) : my_func(f) {}
00078 };
00079 }
00081
00088 class task_arena {
00089 friend class internal::task_scheduler_observer_v3;
00091 int my_max_concurrency;
00092
00094 internal::arena* my_arena;
00095
00096
00097 internal::arena* __TBB_EXPORTED_METHOD internal_initialize( int ) const;
00098 void __TBB_EXPORTED_METHOD internal_terminate( );
00099 void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const;
00100 void __TBB_EXPORTED_METHOD internal_execute( internal::delegate_base& ) const;
00101 void __TBB_EXPORTED_METHOD internal_wait() const;
00102
00103 inline void check_init() {
00104 if( !my_arena )
00105 my_arena = internal_initialize( my_max_concurrency );
00106 }
00107
00108 public:
00110 static const int automatic = -1;
00111
00113 task_arena(int max_concurrency = automatic)
00114 : my_max_concurrency(max_concurrency)
00115 , my_arena(0)
00116 {}
00117
00119 task_arena(const task_arena &s)
00120 : my_max_concurrency(s.my_max_concurrency)
00121 , my_arena(0)
00122 {}
00123
00126 ~task_arena() {
00127 internal_terminate();
00128 }
00129
00132 template<typename F>
00133 void enqueue( const F& f ) {
00134 check_init();
00135 internal_enqueue( *new( task::allocate_root() ) internal::enqueued_function_task<F>(f), 0 );
00136 }
00137
00138 #if __TBB_TASK_PRIORITY
00141 template<typename F>
00142 void enqueue( const F& f, priority_t p ) {
00143 __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" );
00144 check_init();
00145 internal_enqueue( *new( task::allocate_root() ) internal::enqueued_function_task<F>(f), (intptr_t)p );
00146 }
00147 #endif// __TBB_TASK_PRIORITY
00148
00152 template<typename F>
00153 void execute(F& f) {
00154 check_init();
00155 internal::delegated_function<F> d(f);
00156 internal_execute( d );
00157 }
00158
00162 template<typename F>
00163 void execute(const F& f) {
00164 check_init();
00165 internal::delegated_function<const F> d(f);
00166 internal_execute( d );
00167 }
00168
00172 void wait_until_empty() {
00173 check_init();
00174 internal_wait();
00175 }
00176
00178 inline void initialize(int max_concurrency) {
00179 my_max_concurrency = max_concurrency;
00180 __TBB_ASSERT( !my_arena, "task_arena was initialized already");
00181 check_init();
00182 }
00183
00185 static int __TBB_EXPORTED_FUNC current_slot();
00186 };
00187
00188 }
00189
00190 using interface6::task_arena;
00191
00192 }
00193
00194 #endif
00195
00196 #endif