00001 #ifndef MTQUEUE_HEADER
00002 #define MTQUEUE_HEADER
00003
00004
00005
00018
00019
00020
00021
00022 #include <stdlib.h>
00023
00024 #ifdef _STANDARD_C_PLUS_PLUS
00025 #include <queue>
00026 #include <vector>
00027 #include <list>
00028 using namespace std;
00029 #else
00030 #include <stack.h>
00031 #include <vector.h>
00032 #include <list.h>
00033 #endif
00034
00035
00036
00037 #include"MTsync.hh"
00038
00039
00040
00041 namespace RazorBack {
00042
00051 class MTjobbase_
00052 {
00053
00054 private:
00055
00056 double Complexity;
00057
00058
00059 public:
00060
00062 MTjobbase_(): Complexity(0.0) {}
00063
00065 MTjobbase_(const MTjobbase_& Jb): Complexity(Jb.complexity()) {}
00066
00068 virtual ~MTjobbase_() {}
00069
00070 public:
00071
00084 virtual void* task() =0;
00085
00091 double complexity() const { return Complexity; }
00092
00094 bool operator<(const MTjobbase_& Rhs) const
00095 {
00096 return (complexity()<Rhs.complexity());
00097 }
00098
00099
00100 protected:
00101
00103 void complexity(double C) { Complexity=C; }
00104 };
00105
00106
00112 class MTqueue_
00113 {
00115 public:
00116
00122 struct Jobq_
00123 {
00125 MTjobbase_ *Jobptr;
00126 Semaphore_ *Doneptr;
00127
00132 explicit Jobq_(MTjobbase_ *Jptr=NULL, Semaphore_ *Dptr=NULL):
00133 Jobptr(Jptr), Doneptr(Dptr) {}
00134 bool operator<(const Jobq_& Rhs) const
00135 {
00136 return Jobptr->complexity()<Rhs.Jobptr->complexity();
00137 }
00138 bool empty() const { return Jobptr==NULL; }
00139 };
00140
00141
00142
00143 private:
00144
00145 priority_queue<Jobq_> Jobqueue;
00146 mutable Mutex_ Qmutex;
00147 mutable Condvar_ Todo;
00148
00149
00150 public:
00151
00153 MTqueue_(): Jobqueue(), Qmutex(), Todo() {}
00154
00165 template <class Fwditer_>
00166 void submit_jobs(Fwditer_ First, Fwditer_ Last);
00167
00172 void wait_4job() const { Todo.wait(); }
00173
00180 MTqueue_::Jobq_ pop_job();
00181
00182 };
00183
00184
00185
00186 template <class Fwditer_>
00187 void MTqueue_::submit_jobs(Fwditer_ First, Fwditer_ Last)
00188 {
00189
00190
00191 Semaphore_ Done;
00192 size_t Jobno;
00193 Qmutex.lock();
00194 for (Jobno=0; First!=Last; ++First, ++Jobno)
00195 {
00196 Jobq_ Jq(&(*First), &Done);
00197 Jobqueue.push(Jq);
00198 Todo.signal();
00199 }
00200 Done.increment(Jobno);
00201 Qmutex.unlock();
00202
00203
00204
00205 Done.wait();
00206 }
00207
00208
00209
00220 void* MTqueue_start_workthread(void* Qptr);
00221
00222 }
00223
00224
00225
00226 #endif // MTQUEUE_HEADER