PFUNC 1.0
pfunc/parallel_while.hpp
Go to the documentation of this file.
00001 #ifndef PFUNC_PARALLEL_WHILE_HPP
00002 #define PFUNC_PARALLEL_WHILE_HPP
00003 
00004 #include <pfunc/pfunc.hpp>
00005 #include <iostream>
00006 
00007 namespace pfunc {
00021 template <typename PFuncInstanceType, /*type of PFunc instance*/
00022           typename InputIterator, /*type of the iterator*/
00023           typename WhileExecutable> /*type of the function object*/
00024 struct parallel_while : pfunc::virtual_functor {
00025   public:
00026   typedef typename PFuncInstanceType::taskmgr TaskMgrType;
00027   typedef typename PFuncInstanceType::task TaskType;
00028   typedef typename InputIterator::value_type ValueType;
00029 
00030   private:
00031   InputIterator first;
00032   InputIterator last;
00033   const WhileExecutable& func;
00034   TaskMgrType& taskmgr;
00035 
00042   struct while_wrapper : pfunc::virtual_functor {
00043     private:
00044     const WhileExecutable& func;
00045     const ValueType& value;
00046 
00047     public:
00053     while_wrapper (const WhileExecutable& func, const ValueType& value) :
00054       func (func), value (value) {}
00055 
00059     void operator()(void) { func (value); }
00060   };
00061 
00062   public:
00072   parallel_while (InputIterator first,
00073                   InputIterator last,
00074                   const WhileExecutable& func,
00075                   TaskMgrType& taskmgr) : 
00076      first (first), last(last), func(func), taskmgr (taskmgr) {}
00077 
00081   void operator() (void) {
00082     std::vector<TaskType*> tasks;
00083     std::vector<while_wrapper*> functors;
00084     // Go through each element in the list and spawn a new task for each 
00085     // element in [first, last). One optimization that we might want to 
00086     // perform is that we pick elements from this list in parallel instead 
00087     // of sequentially --- but that is for later.
00088     int task_index = 0;
00089     while (first != last) {
00090       tasks.push_back (new TaskType());
00091       functors.push_back (new while_wrapper (func, *first));
00092       pfunc::spawn (taskmgr, 
00093                     *(tasks [task_index]),
00094                     *(functors [task_index]));
00095       ++first;
00096       ++task_index;
00097     }
00098 
00099     // Now that all of them have been spawned, wait on them.
00100     pfunc::wait_all (taskmgr, tasks.begin(), tasks.end());
00101 
00102     // Deallocate everything.
00103     for (int i=0; i<task_index; ++i) {
00104       delete tasks[i];
00105       delete functors[i];
00106     }
00107   }
00108 };
00109 }
00110 
00111 #endif // PFUNC_PARALLEL_WHILE_HPP