PFUNC 1.0
|
00001 #ifndef PFUNC_TASK_HPP 00002 #define PFUNC_TASK_HPP 00003 00010 #include <cstdlib> 00011 00012 #include <pfunc/no_copy.hpp> 00013 #include <pfunc/exception.hpp> 00014 #include <pfunc/event.hpp> 00015 #include <pfunc/trampolines.hpp> 00016 #include <pfunc/attribute.hpp> 00017 #include <pfunc/group.hpp> 00018 00019 namespace pfunc { namespace detail { 00020 00032 template <typename Attribute, 00033 typename Functor> 00034 struct task : public no_copy { 00035 typedef Attribute attribute; /* Type of the attribute. */ 00036 typedef Functor functor; /* Type of the functor. */ 00037 00038 private: 00039 attribute attr; 00040 group* grp; 00041 unsigned int gsize; 00042 unsigned int grank; 00043 functor* func; 00044 event<testable_event> testing_compl; 00045 event<waitable_event> waiting_compl; 00046 PFUNC_DEFINE_EXCEPT_PTR() 00047 00048 public: 00052 const attribute& get_attr() const { return attr;} 00053 00057 group* get_group() const { return grp;} 00058 00062 unsigned int get_size () const { return gsize; } 00063 00067 unsigned int get_rank () const { return grank; } 00068 00072 void set_attr (const attribute& at) { attr = at; } 00073 00077 void set_group (group* gp) { 00078 grp = gp; 00079 if (!attr.get_grouped()) return; 00080 else { 00081 gsize = grp->get_size(); 00082 grank = grp->join_group(); 00083 } 00084 } 00085 00089 void set_func (functor* fn) { func = fn; } 00090 00094 void reset_completion (const unsigned int& nwait = 1) { 00095 if (attr.get_nested ()) testing_compl.reset (nwait); 00096 else waiting_compl.reset (nwait); 00097 PFUNC_EXCEPT_PTR_CLEAR() 00098 } 00099 00103 void run () { 00104 PFUNC_START_TRY_BLOCK() 00105 (*func)(); 00106 PFUNC_END_TRY_BLOCK() 00107 PFUNC_CATCH_AND_STORE(task,run) 00108 } 00109 00115 template <typename TaskManager> 00116 void wait (TaskManager& taskmgr) { 00117 PFUNC_CHECK_AND_RETHROW() 00118 00119 PFUNC_START_TRY_BLOCK() 00120 if (attr.get_nested ()) { 00121 taskmgr.progress_wait (testing_compl); 00122 } else { 00123 waiting_compl.wait (); 00124 } 00125 if (attr.get_grouped ()) grp->leave_group (); 00126 PFUNC_END_TRY_BLOCK() 00127 PFUNC_CATCH_AND_RETHROW(task,run) 00128 } 00129 00135 template <typename TaskManager> 00136 bool test (TaskManager& taskmgr) { 00137 PFUNC_CHECK_AND_RETHROW() 00138 00139 bool return_value = false; 00140 PFUNC_START_TRY_BLOCK() 00141 if (attr.get_nested ()) return_value = testing_compl.test (); 00142 else return_value = waiting_compl.test (); 00143 00144 if (return_value && attr.get_grouped ()) grp->leave_group(); 00145 00146 PFUNC_END_TRY_BLOCK() 00147 PFUNC_CATCH_AND_RETHROW(task,run) 00148 00149 return return_value; 00150 } 00151 00156 void notify () { 00157 PFUNC_CHECK_AND_RETHROW() 00158 00159 PFUNC_START_TRY_BLOCK() 00160 if (attr.get_nested()) testing_compl.notify (); 00161 else waiting_compl.notify(); 00162 PFUNC_END_TRY_BLOCK() 00163 PFUNC_CATCH_AND_RETHROW(task,run) 00164 } 00165 00171 template <typename TaskManager> 00172 void barrier (TaskManager& taskmgr) { 00173 PFUNC_START_TRY_BLOCK() 00174 grp->barrier(taskmgr); 00175 PFUNC_END_TRY_BLOCK() 00176 PFUNC_CATCH_AND_RETHROW(task,run) 00177 } 00178 00182 task () : grp (NULL), 00183 gsize (0), 00184 grank (0), 00185 func (NULL) 00186 PFUNC_EXCEPT_PTR_INIT() {} 00187 00195 task (const attribute& attr, const group*& grp, functor*& func) : 00196 attr (attr), 00197 grp (grp), 00198 gsize (0), 00199 grank (0), 00200 func (NULL) 00201 PFUNC_EXCEPT_PTR_INIT() {} 00202 00206 ~task () { PFUNC_EXCEPT_PTR_CLEAR() } 00207 00216 friend bool operator<(const task& one, const task& two) { 00217 return (one.attr < two.attr); 00218 } 00219 00220 /* 00221 * Shallow copy of a task. This is used explicitly as the structure itself 00222 * is not copyable. 00223 * 00224 * \param [in] other The other task from which to shallow copy. 00225 */ 00226 void shallow_copy(const task& other) { 00227 attr = other.attr; 00228 grp = other.grp; 00229 gsize = other.gsize; 00230 grank = other.grank; 00231 } 00232 }; /* task */ 00233 00234 } /* namespace detail */ } /* namespace pfunc */ 00235 00236 #endif // PFUNC_TASK_HPP