OVR_Threads.h
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 PublicHeader:   None
00004 Filename    :   OVR_Threads.h
00005 Content     :   Contains thread-related (safe) functionality
00006 Created     :   September 19, 2012
00007 Notes       : 
00008 
00009 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00010 
00011 Use of this software is subject to the terms of the Oculus license
00012 agreement provided at the time of installation or download, or which
00013 otherwise accompanies this software in either electronic or hard copy form.
00014 
00015 ************************************************************************************/
00016 #ifndef OVR_Threads_h
00017 #define OVR_Threads_h
00018 
00019 #include "OVR_Types.h"
00020 #include "OVR_Atomic.h"
00021 #include "OVR_RefCount.h"
00022 #include "OVR_Array.h"
00023 
00024 // Defines the infinite wait delay timeout
00025 #define OVR_WAIT_INFINITE 0xFFFFFFFF
00026 
00027 // To be defined in the project configuration options
00028 #ifdef OVR_ENABLE_THREADS
00029 
00030 
00031 namespace OVR {
00032 
00033 //-----------------------------------------------------------------------------------
00034 // ****** Declared classes
00035 
00036 // Declared with thread support only
00037 class   Mutex;
00038 class   WaitCondition;
00039 class   Event;
00040 // Implementation forward declarations
00041 class MutexImpl;
00042 class WaitConditionImpl;
00043 
00044 
00045 
00046 //-----------------------------------------------------------------------------------
00047 // ***** Mutex
00048 
00049 // Mutex class represents a system Mutex synchronization object that provides access 
00050 // serialization between different threads, allowing one thread mutually exclusive access 
00051 // to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
00052 
00053 class Mutex
00054 {
00055     friend class WaitConditionImpl;    
00056     friend class MutexImpl;
00057 
00058     MutexImpl  *pImpl; 
00059 
00060 public:
00061     // Constructor/destructor
00062     Mutex(bool recursive = 1);
00063     ~Mutex();
00064 
00065     // Locking functions
00066     void  DoLock();
00067     bool  TryLock();
00068     void  Unlock();
00069 
00070     // Returns 1 if the mutes is currently locked by another thread
00071     // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. 
00072     bool  IsLockedByAnotherThread();
00073     
00074     // Locker class; Used for automatic locking of a mutex withing scope    
00075     class Locker
00076     {
00077     public:
00078         Mutex *pMutex;
00079         Locker(Mutex *pmutex)
00080             { pMutex = pmutex; pMutex->DoLock(); }
00081         ~Locker()
00082             { pMutex->Unlock(); }
00083     };
00084 };
00085 
00086 
00087 //-----------------------------------------------------------------------------------
00088 // ***** WaitCondition
00089 
00090 /*
00091     WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
00092     Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
00093     call Notify() or NotifyAll().
00094 
00095     The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then 
00096     starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
00097     resource, this ensures that any condition checked for while the mutex was locked does not change before
00098     the wait on the condition is actually initiated.
00099 */
00100 
00101 class WaitCondition
00102 {
00103     friend class WaitConditionImpl;
00104     // Internal implementation structure
00105     WaitConditionImpl *pImpl;
00106 
00107 public:
00108     // Constructor/destructor
00109     WaitCondition();
00110     ~WaitCondition();
00111 
00112     // Release mutex and wait for condition. The mutex is re-aquired after the wait.
00113     // Delay is specified in milliseconds (1/1000 of a second).
00114     bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
00115 
00116     // Notify a condition, releasing at one object waiting
00117     void    Notify();
00118     // Notify a condition, releasing all objects waiting
00119     void    NotifyAll();
00120 };
00121 
00122 
00123 //-----------------------------------------------------------------------------------
00124 // ***** Event
00125 
00126 // Event is a wait-able synchronization object similar to Windows event.
00127 // Event can be waited on until it's signaled by another thread calling
00128 // either SetEvent or PulseEvent.
00129 
00130 class Event
00131 {
00132     // Event state, its mutex and the wait condition
00133     volatile bool   State;
00134     volatile bool   Temporary;  
00135     mutable Mutex   StateMutex;
00136     WaitCondition   StateWaitCondition;
00137 
00138     void updateState(bool newState, bool newTemp, bool mustNotify);
00139 
00140 public:    
00141     Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
00142     ~Event() { }
00143 
00144     // Wait on an event condition until it is set
00145     // Delay is specified in milliseconds (1/1000 of a second).
00146     bool  Wait(unsigned delay = OVR_WAIT_INFINITE);
00147     
00148     // Set an event, releasing objects waiting on it
00149     void  SetEvent()
00150     { updateState(true, false, true); }
00151 
00152     // Reset an event, un-signaling it
00153     void  ResetEvent()
00154     { updateState(false, false, false); }
00155 
00156     // Set and then reset an event once a waiter is released.
00157     // If threads are already waiting, they will be notified and released
00158     // If threads are not waiting, the event is set until the first thread comes in
00159     void  PulseEvent()
00160     { updateState(true, true, true); }
00161 };
00162 
00163 
00164 //-----------------------------------------------------------------------------------
00165 // ***** Thread class
00166 
00167 // ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
00168 // Thread::GetThreadId.
00169 typedef void* ThreadId;
00170 
00171 
00172 // *** Thread flags
00173 
00174 // Indicates that the thread is has been started, i.e. Start method has been called, and threads
00175 // OnExit() method has not yet been called/returned.
00176 #define OVR_THREAD_STARTED               0x01
00177 // This flag is set once the thread has ran, and finished.
00178 #define OVR_THREAD_FINISHED              0x02
00179 // This flag is set temporarily if this thread was started suspended. It is used internally.
00180 #define OVR_THREAD_START_SUSPENDED       0x08
00181 // This flag is used to ask a thread to exit. Message driven threads will usually check this flag
00182 // and finish once it is set.
00183 #define OVR_THREAD_EXIT                  0x10
00184 
00185 
00186 class Thread : public RefCountBase<Thread>
00187 { // NOTE: Waitable must be the first base since it implements RefCountImpl.    
00188 
00189 public:
00190 
00191     // *** Callback functions, can be used instead of overriding Run
00192 
00193     // Run function prototypes.    
00194     // Thread function and user handle passed to it, executed by the default
00195     // Thread::Run implementation if not null.
00196     typedef int (*ThreadFn)(Thread *pthread, void* h);
00197     
00198     // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
00199     ThreadFn    ThreadFunction;    
00200     // User handle passes to a thread
00201     void*       UserHandle;
00202 
00203     // Thread state to start a thread with
00204     enum ThreadState
00205     {
00206         NotRunning  = 0,
00207         Running     = 1,
00208         Suspended   = 2
00209     };
00210 
00211     // Thread priority
00212     enum ThreadPriority
00213     {
00214         CriticalPriority,
00215         HighestPriority,
00216         AboveNormalPriority,
00217         NormalPriority,
00218         BelowNormalPriority,
00219         LowestPriority,
00220         IdlePriority,
00221     };
00222 
00223     // Thread constructor parameters
00224     struct CreateParams
00225     {
00226         CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024, 
00227                      int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
00228                      : threadFunction(func), userHandle(hand), stackSize(ssize), 
00229                        processor(proc), initialState(state), priority(prior) {}
00230         ThreadFn       threadFunction;   // Thread function
00231         void*          userHandle;       // User handle passes to a thread
00232         UPInt          stackSize;        // Thread stack size
00233         int            processor;        // Thread hardware processor
00234         ThreadState    initialState;     // 
00235         ThreadPriority priority;         // Thread priority
00236     };
00237 
00238     // *** Constructors
00239 
00240     // A default constructor always creates a thread in NotRunning state, because
00241     // the derived class has not yet been initialized. The derived class can call Start explicitly.
00242     // "processor" parameter specifies which hardware processor this thread will be run on. 
00243     // -1 means OS decides this. Implemented only on Win32
00244     Thread(UPInt stackSize = 128 * 1024, int processor = -1);
00245     // Constructors that initialize the thread with a pointer to function.
00246     // An option to start a thread is available, but it should not be used if classes are derived from Thread.
00247     // "processor" parameter specifies which hardware processor this thread will be run on. 
00248     // -1 means OS decides this. Implemented only on Win32
00249     Thread(ThreadFn threadFunction, void*  userHandle = 0, UPInt stackSize = 128 * 1024,
00250            int processor = -1, ThreadState initialState = NotRunning);
00251     // Constructors that initialize the thread with a create parameters structure.
00252     explicit Thread(const CreateParams& params);
00253 
00254     // Destructor.
00255     virtual ~Thread();
00256 
00257     // Waits for all Threads to finish; should be called only from the root
00258     // application thread. Once this function returns, we know that all other
00259     // thread's references to Thread object have been released.
00260     static  void OVR_CDECL FinishAllThreads();
00261 
00262 
00263     // *** Overridable Run function for thread processing
00264 
00265     // - returning from this method will end the execution of the thread
00266     // - return value is usually 0 for success 
00267     virtual int   Run();
00268     // Called after return/exit function
00269     virtual void  OnExit();
00270 
00271 
00272     // *** Thread management
00273 
00274     // Starts the thread if its not already running
00275     // - internally sets up the threading and calls Run()
00276     // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
00277     // - returns the exit code
00278     virtual bool  Start(ThreadState initialState = Running);
00279 
00280     // Quits with an exit code
00281     virtual void  Exit(int exitCode=0);
00282 
00283     // Suspend the thread until resumed
00284     // Returns 1 for success, 0 for failure.
00285     bool  Suspend();
00286     // Resumes currently suspended thread
00287     // Returns 1 for success, 0 for failure.
00288     bool  Resume();
00289 
00290     // Static function to return a pointer to the current thread
00291     //static Thread* GetThread();
00292 
00293 
00294     // *** Thread status query functions
00295 
00296     bool          GetExitFlag() const;
00297     void          SetExitFlag(bool exitFlag);
00298 
00299     // Determines whether the thread was running and is now finished
00300     bool          IsFinished() const;
00301     // Determines if the thread is currently suspended
00302     bool          IsSuspended() const;
00303     // Returns current thread state
00304     ThreadState   GetThreadState() const;
00305 
00306     // Returns the number of available CPUs on the system 
00307     static int    GetCPUCount();
00308 
00309     // Returns the thread exit code. Exit code is initialized to 0,
00310     // and set to the return value if Run function after the thread is finished.
00311     inline int    GetExitCode() const { return ExitCode; }
00312     // Returns an OS handle 
00313 #if defined(OVR_OS_WIN32)
00314     void*          GetOSHandle() const { return ThreadHandle; }
00315 #else
00316     pthread_t      GetOSHandle() const { return ThreadHandle; }
00317 #endif
00318 
00319 #if defined(OVR_OS_WIN32)
00320     ThreadId       GetThreadId() const { return IdValue; }
00321 #else
00322     ThreadId       GetThreadId() const { return (ThreadId)GetOSHandle(); }
00323 #endif
00324 
00325     static int      GetOSPriority(ThreadPriority);
00326     // *** Sleep
00327 
00328     // Sleep secs seconds
00329     static bool    Sleep(unsigned secs);
00330     // Sleep msecs milliseconds
00331     static bool    MSleep(unsigned msecs);
00332 
00333 
00334     // *** Debugging functionality
00335 #if defined(OVR_OS_WIN32)
00336     virtual void    SetThreadName( const char* name );
00337 #else
00338     virtual void    SetThreadName( const char* name ) { OVR_UNUSED(name); }
00339 #endif
00340 
00341 private:
00342 #if defined(OVR_OS_WIN32)
00343     friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
00344 
00345 #else
00346     friend void *Thread_PthreadStartFn(void * phandle);
00347 
00348     static int            InitAttr;
00349     static pthread_attr_t Attr;
00350 #endif
00351 
00352 protected:    
00353     // Thread state flags
00354     AtomicInt<UInt32>   ThreadFlags;
00355     AtomicInt<SInt32>   SuspendCount;
00356     UPInt               StackSize;
00357 
00358     // Hardware processor which this thread is running on.
00359     int            Processor;
00360     ThreadPriority Priority;
00361 
00362 #if defined(OVR_OS_WIN32)
00363     void*               ThreadHandle;
00364     volatile ThreadId   IdValue;
00365 
00366     // System-specific cleanup function called from destructor
00367     void                CleanupSystemThread();
00368 
00369 #else
00370     pthread_t           ThreadHandle;
00371 #endif
00372 
00373     // Exit code of the thread, as returned by Run.
00374     int                 ExitCode;
00375 
00376     // Internal run function.
00377     int                 PRun();    
00378     // Finishes the thread and releases internal reference to it.
00379     void                FinishAndRelease();
00380 
00381     void                Init(const CreateParams& params);
00382 
00383     // Protected copy constructor
00384     Thread(const Thread &source) { OVR_UNUSED(source); }
00385 
00386 };
00387 
00388 // Returns the unique Id of a thread it is called on, intended for
00389 // comparison purposes.
00390 ThreadId GetCurrentThreadId();
00391 
00392 
00393 } // OVR
00394 
00395 #endif // OVR_ENABLE_THREADS
00396 #endif // OVR_Threads_h


oculus_sdk
Author(s): Tully Foote
autogenerated on Thu Jun 6 2019 20:13:48