TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
GThread.h
Go to the documentation of this file.
1 
9 #ifndef G3D_GThread_h
10 #define G3D_GThread_h
11 
12 #include "G3D/platform.h"
13 #include "G3D/ReferenceCount.h"
14 #include "G3D/ThreadSet.h"
15 #include "G3D/Vector2int32.h"
16 #include "G3D/SpawnBehavior.h"
17 #include <string>
18 
19 #ifndef G3D_WINDOWS
20 # include <pthread.h>
21 # include <signal.h>
22 #endif
23 
24 
25 namespace G3D {
26 
27 typedef shared_ptr<class GThread> GThreadRef;
28 
29 
30 
43 private:
44  // "Status" is a reserved word on FreeBSD
46 
47  // Not implemented on purpose, don't use
48  GThread(const GThread &);
49  GThread& operator=(const GThread&);
50  bool operator==(const GThread&);
51 
52 #ifdef G3D_WINDOWS
53  static DWORD WINAPI internalThreadProc(LPVOID param);
54 #else
55  static void* internalThreadProc(void* param);
56 #endif //G3D_WINDOWS
57 
58  volatile GStatus m_status;
59 
60  // Thread handle to hold HANDLE and pthread_t
61 #ifdef G3D_WINDOWS
63  HANDLE m_event;
64 #else
65  pthread_t m_handle;
66 #endif //G3D_WINDOWS
67 
68  std::string m_name;
69 
70 protected:
71 
73  virtual void threadMain() = 0;
74 
75 public:
76 
78  static int numCores();
79 
80  typedef shared_ptr<class GThread> Ref;
81 
82  GThread(const std::string& name);
83 
84  virtual ~GThread();
85 
89  static GThreadRef create(const std::string& name, void (*proc)(void*), void* param = NULL);
90 
98  bool start(SpawnBehavior behavior = USE_NEW_THREAD);
99 
102  void terminate();
103 
108  bool running() const;
109 
112  bool started() const;
113 
115  bool completed() const;
116 
118  void waitForCompletion();
119 
121  const std::string& name() {
122  return m_name;
123  }
124 
129 
130  enum {
133  NUM_CORES = -100
134  };
135 
162  template<class Class>
163  static void runConcurrently2D
164  (const Vector2int32& start,
165  const Vector2int32& upTo,
166  Class* object,
167  void (Class::*method)(int x, int y),
168  int maxThreads = NUM_CORES) {
169  _internal_runConcurrently2DHelper(start, upTo, object, method, static_cast<void (Class::*)(int, int, int)>(NULL), maxThreads);
170  }
171 
176  template<class Class>
177  static void runConcurrently2D
178  (const Vector2int32& start,
179  const Vector2int32& upTo,
180  Class* object,
181  void (Class::*method)(int x, int y, int threadID),
182  int maxThreads = NUM_CORES) {
183  _internal_runConcurrently2DHelper(start, upTo, object, static_cast<void (Class::*)(int, int)>(NULL), method, maxThreads);
184  }
185 
186 };
187 
188 
189 
190  // Can't use an inherited class inside of its parent on g++ 4.2.1 if it is later a template parameter
191 
194  template<class Class>
196  public:
198  const int threadID;
202  Class* object;
203  void (Class::*method1)(int x, int y);
204  void (Class::*method2)(int x, int y, int threadID);
205 
207  const Vector2int32& start,
208  const Vector2int32& upTo,
209  Class* object,
210  void (Class::*method1)(int x, int y),
211  void (Class::*method2)(int x, int y, int threadID),
212  const Vector2int32& stride) :
213  GThread("runConcurrently2D worker"),
214  threadID(threadID),
215  start(start),
216  upTo(upTo),
217  stride(stride),
218  object(object),
219  method1(method1),
220  method2(method2) {}
221 
222  virtual void threadMain() {
223  for (int y = start.y; y < upTo.y; y += stride.y) {
224  // Run whichever method was provided
225  if (method1) {
226  for (int x = start.x; x < upTo.x; x += stride.x) {
227  (object->*method1)(x, y);
228  }
229  } else {
230  for (int x = start.x; x < upTo.x; x += stride.x) {
231  (object->*method2)(x, y, threadID);
232  }
233  }
234  }
235  }
236  };
237 
238 
239  template<class Class>
241  (const Vector2int32& start,
242  const Vector2int32& upTo,
243  Class* object,
244  void (Class::*method1)(int x, int y),
245  void (Class::*method2)(int x, int y, int threadID),
246  int maxThreads) {
247 
248  // Create a group of threads
249  if (maxThreads == GThread::NUM_CORES) {
250  maxThreads = GThread::numCores();
251  }
252 
253  const int numRows = upTo.y - start.y;
254  const int numThreads = min(maxThreads, numRows);
255  const Vector2int32 stride(1, numThreads);
256  ThreadSet threadSet;
257  for (int t = 0; t < numThreads; ++t) {
258  threadSet.insert(shared_ptr<_internalGThreadWorker<Class> >(new _internalGThreadWorker<Class>(t, start + Vector2int32(0, t), upTo, object, method1, method2, stride)));
259  }
260 
261  // Run the threads, reusing the current thread and blocking until
262  // all complete
263  threadSet.start(USE_CURRENT_THREAD);
264  threadSet.waitForCompletion();
265  }
266 
267 
268 } // namespace G3D
269 
270 #endif //G3D_GTHREAD_H
Definition: GThread.h:195
Definition: GThread.h:45
std::string m_name
Definition: GThread.h:68
static const SpawnBehavior USE_CURRENT_THREAD
Definition: GThread.h:126
void(Class::* method1)(int x, int y)
Definition: GThread.h:203
void(Class::* method2)(int x, int y, int threadID)
Definition: GThread.h:204
void * HANDLE
Definition: CascPort.h:146
void terminate()
Definition: GThread.cpp:153
Definition: GThread.h:45
void _internal_runConcurrently2DHelper(const Vector2int32 &start, const Vector2int32 &upTo, Class *object, void(Class::*method1)(int x, int y), void(Class::*method2)(int x, int y, int threadID), int maxThreads)
Definition: GThread.h:241
volatile GStatus m_status
Definition: GThread.h:58
bool operator==(const GThread &)
pthread_t m_handle
Definition: GThread.h:65
SpawnBehavior
Definition: SpawnBehavior.h:4
static int numCores()
Definition: GThread.cpp:77
bool start(SpawnBehavior behavior=USE_NEW_THREAD)
Definition: GThread.cpp:108
Definition: AABox.h:25
arena_t NULL
Definition: jemalloc_internal.h:624
GThread(const GThread &)
static const SpawnBehavior USE_NEW_THREAD
Definition: GThread.h:128
void start(SpawnBehavior lastThreadBehavior=USE_NEW_THREAD) const
Definition: ThreadSet.cpp:29
shared_ptr< class GThread > Ref
Definition: GThread.h:80
const std::string & name()
Definition: GThread.h:121
#define WINAPI
Definition: CascPort.h:163
void waitForCompletion() const
Definition: ThreadSet.cpp:74
shared_ptr< class GThread > GThreadRef
Definition: GThread.h:27
Definition: ReferenceCount.h:24
T min(const T &x, const T &y)
Definition: g3dmath.h:305
int insert(const ThreadRef &t)
Definition: ThreadSet.cpp:109
virtual ~GThread()
Definition: GThread.cpp:49
const Vector2int32 start
Definition: GThread.h:199
static void * internalThreadProc(void *param)
Definition: GThread.cpp:203
bool started() const
Definition: GThread.cpp:72
static GThreadRef create(const std::string &name, void(*proc)(void *), void *param=NULL)
Definition: GThread.cpp:67
const int threadID
Definition: GThread.h:198
Definition: GThread.h:133
G3D::int16 y
Definition: Vector2int16.h:38
GStatus
Definition: GThread.h:45
Class * object
Definition: GThread.h:202
Vector2int32
Definition: Vector2int32.h:27
unsigned int DWORD
Definition: CascPort.h:139
virtual void threadMain()=0
bool running() const
Definition: GThread.cpp:166
Definition: GThread.h:45
const Vector2int32 upTo
Definition: GThread.h:200
virtual void threadMain()
Definition: GThread.h:222
void waitForCompletion()
Definition: GThread.cpp:176
Definition: SpawnBehavior.h:4
G3D::int16 x
Definition: Vector2int16.h:37
Definition: ThreadSet.h:18
Definition: GThread.h:45
Definition: GThread.h:42
GThread & operator=(const GThread &)
_internalGThreadWorker(int threadID, const Vector2int32 &start, const Vector2int32 &upTo, Class *object, void(Class::*method1)(int x, int y), void(Class::*method2)(int x, int y, int threadID), const Vector2int32 &stride)
Definition: GThread.h:206
static void runConcurrently2D(const Vector2int32 &start, const Vector2int32 &upTo, Class *object, void(Class::*method)(int x, int y), int maxThreads=NUM_CORES)
Iterates over a 2D region using multiple threads and blocks until all threads have completed...
Definition: GThread.h:164
bool completed() const
Definition: GThread.cpp:171
Definition: SpawnBehavior.h:4
const Vector2int32 stride
Definition: GThread.h:201