Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OVR_Threads.h
Go to the documentation of this file.
1 /************************************************************************************
2 
3 PublicHeader: None
4 Filename : OVR_Threads.h
5 Content : Contains thread-related (safe) functionality
6 Created : September 19, 2012
7 Notes :
8 
9 Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
10 
11 Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
12 you may not use the Oculus VR Rift SDK except in compliance with the License,
13 which is provided at the time of installation or download, or which
14 otherwise accompanies this software in either electronic or hard copy form.
15 
16 You may obtain a copy of the License at
17 
18 http://www.oculusvr.com/licenses/LICENSE-3.1
19 
20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
21 distributed under the License is distributed on an "AS IS" BASIS,
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License for the specific language governing permissions and
24 limitations under the License.
25 
26 ************************************************************************************/
27 #ifndef OVR_Threads_h
28 #define OVR_Threads_h
29 
30 #include "OVR_Types.h"
31 #include "OVR_Atomic.h"
32 #include "OVR_RefCount.h"
33 #include "OVR_Array.h"
34 
35 // Defines the infinite wait delay timeout
36 #define OVR_WAIT_INFINITE 0xFFFFFFFF
37 
38 // To be defined in the project configuration options
39 #ifdef OVR_ENABLE_THREADS
40 
41 
42 namespace OVR {
43 
44 //-----------------------------------------------------------------------------------
45 // ****** Declared classes
46 
47 // Declared with thread support only
48 class Mutex;
49 class WaitCondition;
50 class Event;
51 // Implementation forward declarations
52 class MutexImpl;
53 class WaitConditionImpl;
54 
55 
56 
57 //-----------------------------------------------------------------------------------
58 // ***** Mutex
59 
60 // Mutex class represents a system Mutex synchronization object that provides access
61 // serialization between different threads, allowing one thread mutually exclusive access
62 // to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
63 
64 class Mutex
65 {
66  friend class WaitConditionImpl;
67  friend class MutexImpl;
68 
70 
71 public:
72  // Constructor/destructor
73  Mutex(bool recursive = 1);
74  ~Mutex();
75 
76  // Locking functions
77  void DoLock();
78  bool TryLock();
79  void Unlock();
80 
81  // Returns 1 if the mutes is currently locked by another thread
82  // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired.
84 
85  // Locker class; Used for automatic locking of a mutex withing scope
86  class Locker
87  {
88  public:
90  Locker(Mutex *pmutex)
91  { pMutex = pmutex; pMutex->DoLock(); }
93  { pMutex->Unlock(); }
94  };
95 };
96 
97 
98 //-----------------------------------------------------------------------------------
99 // ***** WaitCondition
100 
101 /*
102  WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
103  Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
104  call Notify() or NotifyAll().
105 
106  The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then
107  starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
108  resource, this ensures that any condition checked for while the mutex was locked does not change before
109  the wait on the condition is actually initiated.
110 */
111 
113 {
114  friend class WaitConditionImpl;
115  // Internal implementation structure
117 
118 public:
119  // Constructor/destructor
120  WaitCondition();
121  ~WaitCondition();
122 
123  // Release mutex and wait for condition. The mutex is re-aquired after the wait.
124  // Delay is specified in milliseconds (1/1000 of a second).
125  bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
126 
127  // Notify a condition, releasing at one object waiting
128  void Notify();
129  // Notify a condition, releasing all objects waiting
130  void NotifyAll();
131 };
132 
133 
134 //-----------------------------------------------------------------------------------
135 // ***** Event
136 
137 // Event is a wait-able synchronization object similar to Windows event.
138 // Event can be waited on until it's signaled by another thread calling
139 // either SetEvent or PulseEvent.
140 
141 class Event
142 {
143  // Event state, its mutex and the wait condition
144  volatile bool State;
145  volatile bool Temporary;
146  mutable Mutex StateMutex;
148 
149  void updateState(bool newState, bool newTemp, bool mustNotify);
150 
151 public:
152  Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
153  ~Event() { }
154 
155  // Wait on an event condition until it is set
156  // Delay is specified in milliseconds (1/1000 of a second).
157  bool Wait(unsigned delay = OVR_WAIT_INFINITE);
158 
159  // Set an event, releasing objects waiting on it
160  void SetEvent()
161  { updateState(true, false, true); }
162 
163  // Reset an event, un-signaling it
164  void ResetEvent()
165  { updateState(false, false, false); }
166 
167  // Set and then reset an event once a waiter is released.
168  // If threads are already waiting, they will be notified and released
169  // If threads are not waiting, the event is set until the first thread comes in
170  void PulseEvent()
171  { updateState(true, true, true); }
172 };
173 
174 
175 //-----------------------------------------------------------------------------------
176 // ***** Thread class
177 
178 // ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
179 // Thread::GetThreadId.
180 typedef void* ThreadId;
181 
182 
183 // *** Thread flags
184 
185 // Indicates that the thread is has been started, i.e. Start method has been called, and threads
186 // OnExit() method has not yet been called/returned.
187 #define OVR_THREAD_STARTED 0x01
188 // This flag is set once the thread has ran, and finished.
189 #define OVR_THREAD_FINISHED 0x02
190 // This flag is set temporarily if this thread was started suspended. It is used internally.
191 #define OVR_THREAD_START_SUSPENDED 0x08
192 // This flag is used to ask a thread to exit. Message driven threads will usually check this flag
193 // and finish once it is set.
194 #define OVR_THREAD_EXIT 0x10
195 
196 
197 class Thread : public RefCountBase<Thread>
198 { // NOTE: Waitable must be the first base since it implements RefCountImpl.
199 
200 public:
201 
202  // *** Callback functions, can be used instead of overriding Run
203 
204  // Run function prototypes.
205  // Thread function and user handle passed to it, executed by the default
206  // Thread::Run implementation if not null.
207  typedef int (*ThreadFn)(Thread *pthread, void* h);
208 
209  // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
211  // User handle passes to a thread
212  void* UserHandle;
213 
214  // Thread state to start a thread with
216  {
218  Running = 1,
220  };
221 
222  // Thread priority
224  {
232  };
233 
234  // Thread constructor parameters
236  {
237  CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024,
238  int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
239  : threadFunction(func), userHandle(hand), stackSize(ssize),
240  processor(proc), initialState(state), priority(prior) {}
241  ThreadFn threadFunction; // Thread function
242  void* userHandle; // User handle passes to a thread
243  UPInt stackSize; // Thread stack size
244  int processor; // Thread hardware processor
246  ThreadPriority priority; // Thread priority
247  };
248 
249  // *** Constructors
250 
251  // A default constructor always creates a thread in NotRunning state, because
252  // the derived class has not yet been initialized. The derived class can call Start explicitly.
253  // "processor" parameter specifies which hardware processor this thread will be run on.
254  // -1 means OS decides this. Implemented only on Win32
255  Thread(UPInt stackSize = 128 * 1024, int processor = -1);
256  // Constructors that initialize the thread with a pointer to function.
257  // An option to start a thread is available, but it should not be used if classes are derived from Thread.
258  // "processor" parameter specifies which hardware processor this thread will be run on.
259  // -1 means OS decides this. Implemented only on Win32
260  Thread(ThreadFn threadFunction, void* userHandle = 0, UPInt stackSize = 128 * 1024,
261  int processor = -1, ThreadState initialState = NotRunning);
262  // Constructors that initialize the thread with a create parameters structure.
263  explicit Thread(const CreateParams& params);
264 
265  // Destructor.
266  virtual ~Thread();
267 
268  // Waits for all Threads to finish; should be called only from the root
269  // application thread. Once this function returns, we know that all other
270  // thread's references to Thread object have been released.
271  static void OVR_CDECL FinishAllThreads();
272 
273 
274  // *** Overridable Run function for thread processing
275 
276  // - returning from this method will end the execution of the thread
277  // - return value is usually 0 for success
278  virtual int Run();
279  // Called after return/exit function
280  virtual void OnExit();
281 
282 
283  // *** Thread management
284 
285  // Starts the thread if its not already running
286  // - internally sets up the threading and calls Run()
287  // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
288  // - returns the exit code
289  virtual bool Start(ThreadState initialState = Running);
290 
291  // Quits with an exit code
292  virtual void Exit(int exitCode=0);
293 
294  // Suspend the thread until resumed
295  // Returns 1 for success, 0 for failure.
296  bool Suspend();
297  // Resumes currently suspended thread
298  // Returns 1 for success, 0 for failure.
299  bool Resume();
300 
301  // Static function to return a pointer to the current thread
302  //static Thread* GetThread();
303 
304 
305  // *** Thread status query functions
306 
307  bool GetExitFlag() const;
308  void SetExitFlag(bool exitFlag);
309 
310  // Determines whether the thread was running and is now finished
311  bool IsFinished() const;
312  // Determines if the thread is currently suspended
313  bool IsSuspended() const;
314  // Returns current thread state
315  ThreadState GetThreadState() const;
316 
317  // Returns the number of available CPUs on the system
318  static int GetCPUCount();
319 
320  // Returns the thread exit code. Exit code is initialized to 0,
321  // and set to the return value if Run function after the thread is finished.
322  inline int GetExitCode() const { return ExitCode; }
323  // Returns an OS handle
324 #if defined(OVR_OS_WIN32)
325  void* GetOSHandle() const { return ThreadHandle; }
326 #else
327  pthread_t GetOSHandle() const { return ThreadHandle; }
328 #endif
329 
330 #if defined(OVR_OS_WIN32)
331  ThreadId GetThreadId() const { return IdValue; }
332 #else
333  ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); }
334 #endif
335 
336  static int GetOSPriority(ThreadPriority);
337  // *** Sleep
338 
339  // Sleep secs seconds
340  static bool Sleep(unsigned secs);
341  // Sleep msecs milliseconds
342  static bool MSleep(unsigned msecs);
343 
344 
345  // *** Debugging functionality
346 #if defined(OVR_OS_WIN32)
347  virtual void SetThreadName( const char* name );
348 #else
349  virtual void SetThreadName( const char* name ) { OVR_UNUSED(name); }
350 #endif
351 
352 private:
353 #if defined(OVR_OS_WIN32)
354  friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
355 
356 #else
357  friend void *Thread_PthreadStartFn(void * phandle);
358 
359  static int InitAttr;
361 #endif
362 
363 protected:
364  // Thread state flags
368 
369  // Hardware processor which this thread is running on.
372 
373 #if defined(OVR_OS_WIN32)
374  void* ThreadHandle;
375  volatile ThreadId IdValue;
376 
377  // System-specific cleanup function called from destructor
378  void CleanupSystemThread();
379 
380 #else
382 #endif
383 
384  // Exit code of the thread, as returned by Run.
385  int ExitCode;
386 
387  // Internal run function.
388  int PRun();
389  // Finishes the thread and releases internal reference to it.
390  void FinishAndRelease();
391 
392  void Init(const CreateParams& params);
393 
394  // Protected copy constructor
395  Thread(const Thread &source) : RefCountBase<Thread>() { OVR_UNUSED(source); }
396 
397 };
398 
399 // Returns the unique Id of a thread it is called on, intended for
400 // comparison purposes.
402 
403 
404 } // OVR
405 
406 #endif // OVR_ENABLE_THREADS
407 #endif // OVR_Threads_h
virtual void OnExit()
#define OVR_WAIT_INFINITE
Definition: OVR_Threads.h:36
#define OVR_CDECL
AtomicInt< SInt32 > SuspendCount
Definition: OVR_Threads.h:366
void SetEvent()
Definition: OVR_Threads.h:160
virtual int Run()
bool IsSuspended() const
static void OVR_CDECL FinishAllThreads()
static int GetCPUCount()
volatile bool Temporary
Definition: OVR_Threads.h:145
static bool MSleep(unsigned msecs)
static int InitAttr
Definition: OVR_Threads.h:359
bool IsLockedByAnotherThread()
WaitCondition StateWaitCondition
Definition: OVR_Threads.h:147
virtual void SetThreadName(const char *name)
Definition: OVR_Threads.h:349
pthread_t ThreadHandle
Definition: OVR_Threads.h:381
static pthread_attr_t Attr
Definition: OVR_Threads.h:360
bool Wait(unsigned delay=OVR_WAIT_INFINITE)
#define OVR_UNUSED(a)
ThreadState GetThreadState() const
bool IsFinished() const
size_t UPInt
Definition: OVR_Types.h:218
ThreadPriority priority
Definition: OVR_Threads.h:246
Event(bool setInitially=0)
Definition: OVR_Threads.h:152
void updateState(bool newState, bool newTemp, bool mustNotify)
Thread(UPInt stackSize=128 *1024, int processor=-1)
pthread_t GetOSHandle() const
Definition: OVR_Threads.h:327
volatile bool State
Definition: OVR_Threads.h:144
void * UserHandle
Definition: OVR_Threads.h:212
virtual void Exit(int exitCode=0)
static bool Sleep(unsigned secs)
static int GetOSPriority(ThreadPriority)
WaitConditionImpl * pImpl
Definition: OVR_Threads.h:116
Mutex(bool recursive=1)
int GetExitCode() const
Definition: OVR_Threads.h:322
CreateParams(ThreadFn func=0, void *hand=0, UPInt ssize=128 *1024, int proc=-1, ThreadState state=NotRunning, ThreadPriority prior=NormalPriority)
Definition: OVR_Threads.h:237
Locker(Mutex *pmutex)
Definition: OVR_Threads.h:90
virtual bool Start(ThreadState initialState=Running)
void * ThreadId
Definition: OVR_Threads.h:180
Thread(const Thread &source)
Definition: OVR_Threads.h:395
ThreadId GetThreadId() const
Definition: OVR_Threads.h:333
UPInt StackSize
Definition: OVR_Threads.h:367
void SetExitFlag(bool exitFlag)
ThreadFn ThreadFunction
Definition: OVR_Threads.h:210
void ResetEvent()
Definition: OVR_Threads.h:164
Mutex StateMutex
Definition: OVR_Threads.h:146
AtomicInt< UInt32 > ThreadFlags
Definition: OVR_Threads.h:365
void Init(const CreateParams &params)
ThreadId GetCurrentThreadId()
bool Wait(Mutex *pmutex, unsigned delay=OVR_WAIT_INFINITE)
bool GetExitFlag() const
MutexImpl * pImpl
Definition: OVR_Threads.h:69
void PulseEvent()
Definition: OVR_Threads.h:170
friend void * Thread_PthreadStartFn(void *phandle)
int(* ThreadFn)(Thread *pthread, void *h)
Definition: OVR_Threads.h:207
ThreadPriority Priority
Definition: OVR_Threads.h:371
unsigned long int pthread_t
Definition: OVR_Types.h:60