PFUNC  1.0
pfunc/task.hpp
Go to the documentation of this file.
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, 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