00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_pipeline_H
00022 #define __TBB_pipeline_H
00023
00024 #include "atomic.h"
00025 #include "task.h"
00026 #include <cstddef>
00027
00028 namespace tbb {
00029
00030 class pipeline;
00031 class filter;
00032
00034 namespace internal {
00035 const unsigned char IS_SERIAL = 0x1;
00036 const unsigned char SERIAL_MODE_MASK = 0x1;
00037
00038
00039 #define __TBB_PIPELINE_VERSION(x) (unsigned char)(x-2)<<1
00040 const unsigned char VERSION_MASK = 0x7<<1;
00041 const unsigned char CURRENT_VERSION = __TBB_PIPELINE_VERSION(3);
00042
00043 typedef unsigned long Token;
00044 typedef long tokendiff_t;
00045 class stage_task;
00046 class ordered_buffer;
00047
00048 }
00050
00052
00053 class filter {
00054 private:
00056 static filter* not_in_pipeline() {return reinterpret_cast<filter*>(internal::intptr(-1));}
00057 protected:
00059 enum mode {
00060 parallel = internal::CURRENT_VERSION,
00061 serial = internal::CURRENT_VERSION | internal::IS_SERIAL
00062 };
00063
00064 filter( bool is_serial_ ) :
00065 next_filter_in_pipeline(not_in_pipeline()),
00066 input_buffer(NULL),
00067 my_filter_mode(static_cast<unsigned char>(is_serial_ ? serial : parallel)),
00068 prev_filter_in_pipeline(not_in_pipeline()),
00069 my_pipeline(NULL)
00070 {}
00071
00072 filter( mode filter_mode ) :
00073 next_filter_in_pipeline(not_in_pipeline()),
00074 input_buffer(NULL),
00075 my_filter_mode(static_cast<unsigned char>(filter_mode)),
00076 prev_filter_in_pipeline(not_in_pipeline()),
00077 my_pipeline(NULL)
00078 {}
00079
00080
00081 public:
00083 bool is_serial() const {
00084 return (my_filter_mode & internal::SERIAL_MODE_MASK) == internal::IS_SERIAL;
00085 }
00086
00088
00089 virtual void* operator()( void* item ) = 0;
00090
00092
00093 virtual ~filter();
00094
00095 private:
00097 filter* next_filter_in_pipeline;
00098
00100 internal::ordered_buffer* input_buffer;
00101
00102 friend class internal::stage_task;
00103 friend class pipeline;
00104
00106 const unsigned char my_filter_mode;
00107
00109 filter* prev_filter_in_pipeline;
00110
00112 pipeline* my_pipeline;
00113 };
00114
00116
00117 class pipeline {
00118 public:
00120 pipeline();
00121
00123 virtual ~pipeline();
00124
00126 void add_filter( filter& filter_ );
00127
00129 void run( size_t max_number_of_live_tokens );
00130
00132 void clear();
00133
00134 private:
00135 friend class internal::stage_task;
00136 friend class filter;
00137
00139 filter* filter_list;
00140
00142 filter* filter_end;
00143
00145 empty_task* end_counter;
00146
00148 atomic<internal::Token> input_tokens;
00149
00151 internal::Token token_counter;
00152
00154 bool end_of_input;
00155
00157 void remove_filter( filter& filter_ );
00158
00160 void inject_token( task& self );
00161 };
00162
00163 }
00164
00165 #endif