00001 #ifndef __THREADUTILS_H__
00002 #define __THREADUTILS_H__
00003
00004 #include <stdint.h>
00005 #include <queue>
00006 #include <map>
00007 #include <set>
00008
00009 #ifdef _WIN32
00010 #include <windows.h>
00011 #else
00012 #include <pthread.h>
00013 #endif
00014
00015 #include "stm_export.h"
00016 #include <iostream>
00017
00018 namespace thread {
00019
00020 #ifdef _WIN32
00021
00022 struct _STM_SIGNAL
00023 {
00024 HANDLE handles[2];
00025 };
00026
00027
00028
00029
00030
00031
00032 typedef HANDLE STM_THREAD_TYPE;
00033 typedef HANDLE STM_MUTEX_TYPE;
00034 typedef struct _STM_SIGNAL STM_SIGNAL_TYPE;
00035
00036 #else
00037
00038 typedef pthread_t STM_THREAD_TYPE;
00039 typedef pthread_mutex_t STM_MUTEX_TYPE;
00040 typedef pthread_cond_t STM_SIGNAL_TYPE;
00041 typedef unsigned long DWORD;
00042
00043 #endif
00044
00046
00047 uint32_t STM_EXPORT GetProcessorCount(void);
00048
00050
00051 class STM_EXPORT Mutex
00052 {
00053 friend class Condition;
00054 public:
00055 Mutex();
00056 ~Mutex();
00057
00058 void Lock(void);
00059 bool TryLock(void);
00060 void Unlock(void);
00061 protected:
00062 STM_MUTEX_TYPE &GetMutex(void) {return m_mutex;}
00063 private:
00064 STM_MUTEX_TYPE m_mutex;
00065 };
00066
00068
00069 class STM_EXPORT Condition
00070 {
00071 public:
00072 Condition();
00073 ~Condition();
00074
00075 void Wait(Mutex &);
00076 void TimedWait(Mutex &, uint32_t ms);
00077 void Signal(void);
00078 void Broadcast(void);
00079 private:
00080 STM_SIGNAL_TYPE m_cond;
00081 };
00082
00084
00085 template<class T>
00086 class Fifo
00087 {
00088 public:
00089 Fifo()
00090 {
00091 }
00092 ~Fifo()
00093 {
00094 }
00095
00096 size_t Push(T *item)
00097 {
00098 size_t result(0);
00099
00100 m_lock.Lock();
00101
00102 if(item)
00103 {
00104 m_queue.push(item);
00105 }
00106 result = m_queue.size();
00107 m_signal.Signal();
00108 m_lock.Unlock();
00109
00110 return result;
00111 }
00112
00113 void Ping(void)
00114 {
00115 m_signal.Broadcast();
00116 }
00117
00118 T *Pop(void)
00119 {
00120 T *result = NULL;
00121
00122 m_lock.Lock();
00123
00124 if(m_queue.size())
00125 {
00126 result = m_queue.front();
00127 m_queue.pop();
00128 }
00129 else
00130 {
00131 m_signal.Wait(m_lock);
00132
00133 if(m_queue.size())
00134 {
00135 result = m_queue.front();
00136 m_queue.pop();
00137 }
00138 }
00139
00140 m_lock.Unlock();
00141
00142 return result;
00143 }
00144
00145 T *Peek(void)
00146 {
00147 T *result = NULL;
00148 m_lock.Lock();
00149 if(m_queue.size())
00150 {
00151 result = m_queue.front();
00152 }
00153 m_lock.Unlock();
00154
00155 return result;
00156 }
00157
00158 private:
00159 std::queue<T *> m_queue;
00160 Mutex m_lock;
00161 Condition m_signal;
00162 };
00163
00165
00166 class STM_EXPORT Lockable
00167 {
00168 friend class Lock;
00169 public:
00170 Lockable();
00171 virtual ~Lockable();
00172 protected:
00173 class Lock
00174 {
00175 public:
00176 Lock(Lockable *obj);
00177 ~Lock();
00178 private:
00179 Lockable *m_obj;
00180 };
00181
00182 Mutex &GetLock() {return m_lock;}
00183 private:
00184 Mutex m_lock;
00185 };
00186
00188
00189 class STM_EXPORT Thread : public Lockable
00190 {
00191 public:
00192 Thread()
00193 : Lockable()
00194 {};
00195 virtual ~Thread() {};
00196
00197 void Start(void);
00198
00199 void Join(void);
00200
00201 STM_THREAD_TYPE GetThread(void) const {return m_thread;}
00202 protected:
00203 virtual void *MainLoop(void) = 0;
00204 private:
00205 static void *Entry(void *);
00206 static DWORD WinEntry(void *);
00207
00208 STM_THREAD_TYPE m_thread;
00209 };
00210
00211 }
00212
00213 #endif