00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __threading_hpp__
00022 #define __threading_hpp__
00023
00024 #ifdef THREADS_CPUCOUNT
00025 #define PTHREADS
00026 #else
00027 #define THREADS_CPUCOUNT 1
00028 #endif
00029
00030 #ifdef PTHREADS
00031 #include <pthread.h>
00032 #define HAVE_THREADS
00033 #endif
00034
00035 #include <vector>
00036
00037 class Task
00038 {
00039 protected:
00040 virtual void execute () = 0;
00041 virtual ~Task () { }
00042
00043 friend class TaskManager;
00044
00045 private:
00046 Task *next;
00047 };
00048
00049 class Mutex
00050 {
00051 public:
00052 Mutex ();
00053 ~Mutex ();
00054
00055 void lock ();
00056 void unlock ();
00057 bool trylock ();
00058
00059 private:
00060 #ifdef PTHREADS
00061 pthread_mutex_t m;
00062 #endif
00063 friend class Condition;
00064 };
00065
00066 class AutoMutex
00067 {
00068 public:
00069 inline AutoMutex (Mutex& m) : m(m) { this->m.lock(); }
00070 inline AutoMutex (Mutex* m) : m(*m) { this->m.lock(); }
00071 inline ~AutoMutex () { m.unlock(); }
00072
00073 private:
00074 Mutex& m;
00075
00076
00077 AutoMutex (const AutoMutex& m);
00078 AutoMutex& operator= (const AutoMutex&);
00079 };
00080
00081 class Condition
00082 {
00083 public:
00084 Condition (Mutex& m);
00085 ~Condition ();
00086
00087 void wait ();
00088
00089 void signal ();
00090 void broadcast ();
00091
00092 private:
00093 Mutex& m;
00094 #ifdef PTHREADS
00095 pthread_cond_t cond;
00096 #endif
00097 };
00098
00099 class TaskManager
00100 {
00101 public:
00102 TaskManager (int threads = THREADS_CPUCOUNT);
00103 ~TaskManager ();
00104
00105 void addTask (Task *task);
00106
00107 Task *run();
00108
00109 private:
00110 Task *queue;
00111 Task *complete;
00112 Mutex lock;
00113 Condition work_cond;
00114 Condition ready_cond;
00115 volatile bool terminate;
00116 size_t working;
00117
00118 #ifdef PTHREADS
00119 typedef std::vector<pthread_t> threads_t;
00120 threads_t threads;
00121 #endif
00122
00123 static void *run_thread (void *ptr);
00124 };
00125
00126 #endif // __threading_hpp__
00127