oculus1

diff libovr/Src/Kernel/OVR_Threads.h @ 3:b069a5c27388

added a couple more stuff, fixed all the LibOVR line endings
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 15 Sep 2013 04:10:05 +0300
parents e2f9e4603129
children
line diff
     1.1 --- a/libovr/Src/Kernel/OVR_Threads.h	Sat Sep 14 17:51:03 2013 +0300
     1.2 +++ b/libovr/Src/Kernel/OVR_Threads.h	Sun Sep 15 04:10:05 2013 +0300
     1.3 @@ -1,1 +1,396 @@
     1.4 -/************************************************************************************
     1.5 
     1.6 PublicHeader:   None
     1.7 Filename    :   OVR_Threads.h
     1.8 Content     :   Contains thread-related (safe) functionality
     1.9 Created     :   September 19, 2012
    1.10 Notes       : 
    1.11 
    1.12 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
    1.13 
    1.14 Use of this software is subject to the terms of the Oculus license
    1.15 agreement provided at the time of installation or download, or which
    1.16 otherwise accompanies this software in either electronic or hard copy form.
    1.17 
    1.18 ************************************************************************************/
    1.19 #ifndef OVR_Threads_h
    1.20 #define OVR_Threads_h
    1.21 
    1.22 #include "OVR_Types.h"
    1.23 #include "OVR_Atomic.h"
    1.24 #include "OVR_RefCount.h"
    1.25 #include "OVR_Array.h"
    1.26 
    1.27 // Defines the infinite wait delay timeout
    1.28 #define OVR_WAIT_INFINITE 0xFFFFFFFF
    1.29 
    1.30 // To be defined in the project configuration options
    1.31 #ifdef OVR_ENABLE_THREADS
    1.32 
    1.33 
    1.34 namespace OVR {
    1.35 
    1.36 //-----------------------------------------------------------------------------------
    1.37 // ****** Declared classes
    1.38 
    1.39 // Declared with thread support only
    1.40 class   Mutex;
    1.41 class   WaitCondition;
    1.42 class   Event;
    1.43 // Implementation forward declarations
    1.44 class MutexImpl;
    1.45 class WaitConditionImpl;
    1.46 
    1.47 
    1.48 
    1.49 //-----------------------------------------------------------------------------------
    1.50 // ***** Mutex
    1.51 
    1.52 // Mutex class represents a system Mutex synchronization object that provides access 
    1.53 // serialization between different threads, allowing one thread mutually exclusive access 
    1.54 // to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
    1.55 
    1.56 class Mutex
    1.57 {
    1.58     friend class WaitConditionImpl;    
    1.59     friend class MutexImpl;
    1.60 
    1.61     MutexImpl  *pImpl; 
    1.62 
    1.63 public:
    1.64     // Constructor/destructor
    1.65     Mutex(bool recursive = 1);
    1.66     ~Mutex();
    1.67 
    1.68     // Locking functions
    1.69     void  DoLock();
    1.70     bool  TryLock();
    1.71     void  Unlock();
    1.72 
    1.73     // Returns 1 if the mutes is currently locked by another thread
    1.74     // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. 
    1.75     bool  IsLockedByAnotherThread();
    1.76     
    1.77     // Locker class; Used for automatic locking of a mutex withing scope    
    1.78     class Locker
    1.79     {
    1.80     public:
    1.81         Mutex *pMutex;
    1.82         Locker(Mutex *pmutex)
    1.83             { pMutex = pmutex; pMutex->DoLock(); }
    1.84         ~Locker()
    1.85             { pMutex->Unlock(); }
    1.86     };
    1.87 };
    1.88 
    1.89 
    1.90 //-----------------------------------------------------------------------------------
    1.91 // ***** WaitCondition
    1.92 
    1.93 /*
    1.94     WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
    1.95     Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
    1.96     call Notify() or NotifyAll().
    1.97 
    1.98     The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then 
    1.99     starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
   1.100     resource, this ensures that any condition checked for while the mutex was locked does not change before
   1.101     the wait on the condition is actually initiated.
   1.102 */
   1.103 
   1.104 class WaitCondition
   1.105 {
   1.106     friend class WaitConditionImpl;
   1.107     // Internal implementation structure
   1.108     WaitConditionImpl *pImpl;
   1.109 
   1.110 public:
   1.111     // Constructor/destructor
   1.112     WaitCondition();
   1.113     ~WaitCondition();
   1.114 
   1.115     // Release mutex and wait for condition. The mutex is re-aquired after the wait.
   1.116     // Delay is specified in milliseconds (1/1000 of a second).
   1.117     bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
   1.118 
   1.119     // Notify a condition, releasing at one object waiting
   1.120     void    Notify();
   1.121     // Notify a condition, releasing all objects waiting
   1.122     void    NotifyAll();
   1.123 };
   1.124 
   1.125 
   1.126 //-----------------------------------------------------------------------------------
   1.127 // ***** Event
   1.128 
   1.129 // Event is a wait-able synchronization object similar to Windows event.
   1.130 // Event can be waited on until it's signaled by another thread calling
   1.131 // either SetEvent or PulseEvent.
   1.132 
   1.133 class Event
   1.134 {
   1.135     // Event state, its mutex and the wait condition
   1.136     volatile bool   State;
   1.137     volatile bool   Temporary;  
   1.138     mutable Mutex   StateMutex;
   1.139     WaitCondition   StateWaitCondition;
   1.140 
   1.141     void updateState(bool newState, bool newTemp, bool mustNotify);
   1.142 
   1.143 public:    
   1.144     Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
   1.145     ~Event() { }
   1.146 
   1.147     // Wait on an event condition until it is set
   1.148     // Delay is specified in milliseconds (1/1000 of a second).
   1.149     bool  Wait(unsigned delay = OVR_WAIT_INFINITE);
   1.150     
   1.151     // Set an event, releasing objects waiting on it
   1.152     void  SetEvent()
   1.153     { updateState(true, false, true); }
   1.154 
   1.155     // Reset an event, un-signaling it
   1.156     void  ResetEvent()
   1.157     { updateState(false, false, false); }
   1.158 
   1.159     // Set and then reset an event once a waiter is released.
   1.160     // If threads are already waiting, they will be notified and released
   1.161     // If threads are not waiting, the event is set until the first thread comes in
   1.162     void  PulseEvent()
   1.163     { updateState(true, true, true); }
   1.164 };
   1.165 
   1.166 
   1.167 //-----------------------------------------------------------------------------------
   1.168 // ***** Thread class
   1.169 
   1.170 // ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
   1.171 // Thread::GetThreadId.
   1.172 typedef void* ThreadId;
   1.173 
   1.174 
   1.175 // *** Thread flags
   1.176 
   1.177 // Indicates that the thread is has been started, i.e. Start method has been called, and threads
   1.178 // OnExit() method has not yet been called/returned.
   1.179 #define OVR_THREAD_STARTED               0x01
   1.180 // This flag is set once the thread has ran, and finished.
   1.181 #define OVR_THREAD_FINISHED              0x02
   1.182 // This flag is set temporarily if this thread was started suspended. It is used internally.
   1.183 #define OVR_THREAD_START_SUSPENDED       0x08
   1.184 // This flag is used to ask a thread to exit. Message driven threads will usually check this flag
   1.185 // and finish once it is set.
   1.186 #define OVR_THREAD_EXIT                  0x10
   1.187 
   1.188 
   1.189 class Thread : public RefCountBase<Thread>
   1.190 { // NOTE: Waitable must be the first base since it implements RefCountImpl.    
   1.191 
   1.192 public:
   1.193 
   1.194     // *** Callback functions, can be used instead of overriding Run
   1.195 
   1.196     // Run function prototypes.    
   1.197     // Thread function and user handle passed to it, executed by the default
   1.198     // Thread::Run implementation if not null.
   1.199     typedef int (*ThreadFn)(Thread *pthread, void* h);
   1.200     
   1.201     // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
   1.202     ThreadFn    ThreadFunction;    
   1.203     // User handle passes to a thread
   1.204     void*       UserHandle;
   1.205 
   1.206     // Thread state to start a thread with
   1.207     enum ThreadState
   1.208     {
   1.209         NotRunning  = 0,
   1.210         Running     = 1,
   1.211         Suspended   = 2
   1.212     };
   1.213 
   1.214     // Thread priority
   1.215     enum ThreadPriority
   1.216     {
   1.217         CriticalPriority,
   1.218         HighestPriority,
   1.219         AboveNormalPriority,
   1.220         NormalPriority,
   1.221         BelowNormalPriority,
   1.222         LowestPriority,
   1.223         IdlePriority,
   1.224     };
   1.225 
   1.226     // Thread constructor parameters
   1.227     struct CreateParams
   1.228     {
   1.229         CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024, 
   1.230                      int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
   1.231                      : threadFunction(func), userHandle(hand), stackSize(ssize), 
   1.232                        processor(proc), initialState(state), priority(prior) {}
   1.233         ThreadFn       threadFunction;   // Thread function
   1.234         void*          userHandle;       // User handle passes to a thread
   1.235         UPInt          stackSize;        // Thread stack size
   1.236         int            processor;        // Thread hardware processor
   1.237         ThreadState    initialState;     // 
   1.238         ThreadPriority priority;         // Thread priority
   1.239     };
   1.240 
   1.241     // *** Constructors
   1.242 
   1.243     // A default constructor always creates a thread in NotRunning state, because
   1.244     // the derived class has not yet been initialized. The derived class can call Start explicitly.
   1.245     // "processor" parameter specifies which hardware processor this thread will be run on. 
   1.246     // -1 means OS decides this. Implemented only on Win32
   1.247     Thread(UPInt stackSize = 128 * 1024, int processor = -1);
   1.248     // Constructors that initialize the thread with a pointer to function.
   1.249     // An option to start a thread is available, but it should not be used if classes are derived from Thread.
   1.250     // "processor" parameter specifies which hardware processor this thread will be run on. 
   1.251     // -1 means OS decides this. Implemented only on Win32
   1.252     Thread(ThreadFn threadFunction, void*  userHandle = 0, UPInt stackSize = 128 * 1024,
   1.253            int processor = -1, ThreadState initialState = NotRunning);
   1.254     // Constructors that initialize the thread with a create parameters structure.
   1.255     explicit Thread(const CreateParams& params);
   1.256 
   1.257     // Destructor.
   1.258     virtual ~Thread();
   1.259 
   1.260     // Waits for all Threads to finish; should be called only from the root
   1.261     // application thread. Once this function returns, we know that all other
   1.262     // thread's references to Thread object have been released.
   1.263     static  void OVR_CDECL FinishAllThreads();
   1.264 
   1.265 
   1.266     // *** Overridable Run function for thread processing
   1.267 
   1.268     // - returning from this method will end the execution of the thread
   1.269     // - return value is usually 0 for success 
   1.270     virtual int   Run();
   1.271     // Called after return/exit function
   1.272     virtual void  OnExit();
   1.273 
   1.274 
   1.275     // *** Thread management
   1.276 
   1.277     // Starts the thread if its not already running
   1.278     // - internally sets up the threading and calls Run()
   1.279     // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
   1.280     // - returns the exit code
   1.281     virtual bool  Start(ThreadState initialState = Running);
   1.282 
   1.283     // Quits with an exit code
   1.284     virtual void  Exit(int exitCode=0);
   1.285 
   1.286     // Suspend the thread until resumed
   1.287     // Returns 1 for success, 0 for failure.
   1.288     bool  Suspend();
   1.289     // Resumes currently suspended thread
   1.290     // Returns 1 for success, 0 for failure.
   1.291     bool  Resume();
   1.292 
   1.293     // Static function to return a pointer to the current thread
   1.294     //static Thread* GetThread();
   1.295 
   1.296 
   1.297     // *** Thread status query functions
   1.298 
   1.299     bool          GetExitFlag() const;
   1.300     void          SetExitFlag(bool exitFlag);
   1.301 
   1.302     // Determines whether the thread was running and is now finished
   1.303     bool          IsFinished() const;
   1.304     // Determines if the thread is currently suspended
   1.305     bool          IsSuspended() const;
   1.306     // Returns current thread state
   1.307     ThreadState   GetThreadState() const;
   1.308 
   1.309     // Returns the number of available CPUs on the system 
   1.310     static int    GetCPUCount();
   1.311 
   1.312     // Returns the thread exit code. Exit code is initialized to 0,
   1.313     // and set to the return value if Run function after the thread is finished.
   1.314     inline int    GetExitCode() const { return ExitCode; }
   1.315     // Returns an OS handle 
   1.316 #if defined(OVR_OS_WIN32)
   1.317     void*          GetOSHandle() const { return ThreadHandle; }
   1.318 #else
   1.319     pthread_t      GetOSHandle() const { return ThreadHandle; }
   1.320 #endif
   1.321 
   1.322 #if defined(OVR_OS_WIN32)
   1.323     ThreadId       GetThreadId() const { return IdValue; }
   1.324 #else
   1.325     ThreadId       GetThreadId() const { return (ThreadId)GetOSHandle(); }
   1.326 #endif
   1.327 
   1.328     static int      GetOSPriority(ThreadPriority);
   1.329     // *** Sleep
   1.330 
   1.331     // Sleep secs seconds
   1.332     static bool    Sleep(unsigned secs);
   1.333     // Sleep msecs milliseconds
   1.334     static bool    MSleep(unsigned msecs);
   1.335 
   1.336 
   1.337     // *** Debugging functionality
   1.338 #if defined(OVR_OS_WIN32)
   1.339     virtual void    SetThreadName( const char* name );
   1.340 #else
   1.341     virtual void    SetThreadName( const char* name ) { OVR_UNUSED(name); }
   1.342 #endif
   1.343 
   1.344 private:
   1.345 #if defined(OVR_OS_WIN32)
   1.346     friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
   1.347 
   1.348 #else
   1.349     friend void *Thread_PthreadStartFn(void * phandle);
   1.350 
   1.351     static int            InitAttr;
   1.352     static pthread_attr_t Attr;
   1.353 #endif
   1.354 
   1.355 protected:    
   1.356     // Thread state flags
   1.357     AtomicInt<UInt32>   ThreadFlags;
   1.358     AtomicInt<SInt32>   SuspendCount;
   1.359     UPInt               StackSize;
   1.360 
   1.361     // Hardware processor which this thread is running on.
   1.362     int            Processor;
   1.363     ThreadPriority Priority;
   1.364 
   1.365 #if defined(OVR_OS_WIN32)
   1.366     void*               ThreadHandle;
   1.367     volatile ThreadId   IdValue;
   1.368 
   1.369     // System-specific cleanup function called from destructor
   1.370     void                CleanupSystemThread();
   1.371 
   1.372 #else
   1.373     pthread_t           ThreadHandle;
   1.374 #endif
   1.375 
   1.376     // Exit code of the thread, as returned by Run.
   1.377     int                 ExitCode;
   1.378 
   1.379     // Internal run function.
   1.380     int                 PRun();    
   1.381     // Finishes the thread and releases internal reference to it.
   1.382     void                FinishAndRelease();
   1.383 
   1.384     void                Init(const CreateParams& params);
   1.385 
   1.386     // Protected copy constructor
   1.387     Thread(const Thread &source) { OVR_UNUSED(source); }
   1.388 
   1.389 };
   1.390 
   1.391 // Returns the unique Id of a thread it is called on, intended for
   1.392 // comparison purposes.
   1.393 ThreadId GetCurrentThreadId();
   1.394 
   1.395 
   1.396 } // OVR
   1.397 
   1.398 #endif // OVR_ENABLE_THREADS
   1.399 #endif // OVR_Threads_h
   1.400 \ No newline at end of file
   1.401 +/************************************************************************************
   1.402 +
   1.403 +PublicHeader:   None
   1.404 +Filename    :   OVR_Threads.h
   1.405 +Content     :   Contains thread-related (safe) functionality
   1.406 +Created     :   September 19, 2012
   1.407 +Notes       : 
   1.408 +
   1.409 +Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
   1.410 +
   1.411 +Use of this software is subject to the terms of the Oculus license
   1.412 +agreement provided at the time of installation or download, or which
   1.413 +otherwise accompanies this software in either electronic or hard copy form.
   1.414 +
   1.415 +************************************************************************************/
   1.416 +#ifndef OVR_Threads_h
   1.417 +#define OVR_Threads_h
   1.418 +
   1.419 +#include "OVR_Types.h"
   1.420 +#include "OVR_Atomic.h"
   1.421 +#include "OVR_RefCount.h"
   1.422 +#include "OVR_Array.h"
   1.423 +
   1.424 +// Defines the infinite wait delay timeout
   1.425 +#define OVR_WAIT_INFINITE 0xFFFFFFFF
   1.426 +
   1.427 +// To be defined in the project configuration options
   1.428 +#ifdef OVR_ENABLE_THREADS
   1.429 +
   1.430 +
   1.431 +namespace OVR {
   1.432 +
   1.433 +//-----------------------------------------------------------------------------------
   1.434 +// ****** Declared classes
   1.435 +
   1.436 +// Declared with thread support only
   1.437 +class   Mutex;
   1.438 +class   WaitCondition;
   1.439 +class   Event;
   1.440 +// Implementation forward declarations
   1.441 +class MutexImpl;
   1.442 +class WaitConditionImpl;
   1.443 +
   1.444 +
   1.445 +
   1.446 +//-----------------------------------------------------------------------------------
   1.447 +// ***** Mutex
   1.448 +
   1.449 +// Mutex class represents a system Mutex synchronization object that provides access 
   1.450 +// serialization between different threads, allowing one thread mutually exclusive access 
   1.451 +// to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition.
   1.452 +
   1.453 +class Mutex
   1.454 +{
   1.455 +    friend class WaitConditionImpl;    
   1.456 +    friend class MutexImpl;
   1.457 +
   1.458 +    MutexImpl  *pImpl; 
   1.459 +
   1.460 +public:
   1.461 +    // Constructor/destructor
   1.462 +    Mutex(bool recursive = 1);
   1.463 +    ~Mutex();
   1.464 +
   1.465 +    // Locking functions
   1.466 +    void  DoLock();
   1.467 +    bool  TryLock();
   1.468 +    void  Unlock();
   1.469 +
   1.470 +    // Returns 1 if the mutes is currently locked by another thread
   1.471 +    // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. 
   1.472 +    bool  IsLockedByAnotherThread();
   1.473 +    
   1.474 +    // Locker class; Used for automatic locking of a mutex withing scope    
   1.475 +    class Locker
   1.476 +    {
   1.477 +    public:
   1.478 +        Mutex *pMutex;
   1.479 +        Locker(Mutex *pmutex)
   1.480 +            { pMutex = pmutex; pMutex->DoLock(); }
   1.481 +        ~Locker()
   1.482 +            { pMutex->Unlock(); }
   1.483 +    };
   1.484 +};
   1.485 +
   1.486 +
   1.487 +//-----------------------------------------------------------------------------------
   1.488 +// ***** WaitCondition
   1.489 +
   1.490 +/*
   1.491 +    WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor.
   1.492 +    Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that
   1.493 +    call Notify() or NotifyAll().
   1.494 +
   1.495 +    The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then 
   1.496 +    starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same
   1.497 +    resource, this ensures that any condition checked for while the mutex was locked does not change before
   1.498 +    the wait on the condition is actually initiated.
   1.499 +*/
   1.500 +
   1.501 +class WaitCondition
   1.502 +{
   1.503 +    friend class WaitConditionImpl;
   1.504 +    // Internal implementation structure
   1.505 +    WaitConditionImpl *pImpl;
   1.506 +
   1.507 +public:
   1.508 +    // Constructor/destructor
   1.509 +    WaitCondition();
   1.510 +    ~WaitCondition();
   1.511 +
   1.512 +    // Release mutex and wait for condition. The mutex is re-aquired after the wait.
   1.513 +    // Delay is specified in milliseconds (1/1000 of a second).
   1.514 +    bool    Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
   1.515 +
   1.516 +    // Notify a condition, releasing at one object waiting
   1.517 +    void    Notify();
   1.518 +    // Notify a condition, releasing all objects waiting
   1.519 +    void    NotifyAll();
   1.520 +};
   1.521 +
   1.522 +
   1.523 +//-----------------------------------------------------------------------------------
   1.524 +// ***** Event
   1.525 +
   1.526 +// Event is a wait-able synchronization object similar to Windows event.
   1.527 +// Event can be waited on until it's signaled by another thread calling
   1.528 +// either SetEvent or PulseEvent.
   1.529 +
   1.530 +class Event
   1.531 +{
   1.532 +    // Event state, its mutex and the wait condition
   1.533 +    volatile bool   State;
   1.534 +    volatile bool   Temporary;  
   1.535 +    mutable Mutex   StateMutex;
   1.536 +    WaitCondition   StateWaitCondition;
   1.537 +
   1.538 +    void updateState(bool newState, bool newTemp, bool mustNotify);
   1.539 +
   1.540 +public:    
   1.541 +    Event(bool setInitially = 0) : State(setInitially), Temporary(false) { }
   1.542 +    ~Event() { }
   1.543 +
   1.544 +    // Wait on an event condition until it is set
   1.545 +    // Delay is specified in milliseconds (1/1000 of a second).
   1.546 +    bool  Wait(unsigned delay = OVR_WAIT_INFINITE);
   1.547 +    
   1.548 +    // Set an event, releasing objects waiting on it
   1.549 +    void  SetEvent()
   1.550 +    { updateState(true, false, true); }
   1.551 +
   1.552 +    // Reset an event, un-signaling it
   1.553 +    void  ResetEvent()
   1.554 +    { updateState(false, false, false); }
   1.555 +
   1.556 +    // Set and then reset an event once a waiter is released.
   1.557 +    // If threads are already waiting, they will be notified and released
   1.558 +    // If threads are not waiting, the event is set until the first thread comes in
   1.559 +    void  PulseEvent()
   1.560 +    { updateState(true, true, true); }
   1.561 +};
   1.562 +
   1.563 +
   1.564 +//-----------------------------------------------------------------------------------
   1.565 +// ***** Thread class
   1.566 +
   1.567 +// ThreadId uniquely identifies a thread; returned by GetCurrentThreadId() and
   1.568 +// Thread::GetThreadId.
   1.569 +typedef void* ThreadId;
   1.570 +
   1.571 +
   1.572 +// *** Thread flags
   1.573 +
   1.574 +// Indicates that the thread is has been started, i.e. Start method has been called, and threads
   1.575 +// OnExit() method has not yet been called/returned.
   1.576 +#define OVR_THREAD_STARTED               0x01
   1.577 +// This flag is set once the thread has ran, and finished.
   1.578 +#define OVR_THREAD_FINISHED              0x02
   1.579 +// This flag is set temporarily if this thread was started suspended. It is used internally.
   1.580 +#define OVR_THREAD_START_SUSPENDED       0x08
   1.581 +// This flag is used to ask a thread to exit. Message driven threads will usually check this flag
   1.582 +// and finish once it is set.
   1.583 +#define OVR_THREAD_EXIT                  0x10
   1.584 +
   1.585 +
   1.586 +class Thread : public RefCountBase<Thread>
   1.587 +{ // NOTE: Waitable must be the first base since it implements RefCountImpl.    
   1.588 +
   1.589 +public:
   1.590 +
   1.591 +    // *** Callback functions, can be used instead of overriding Run
   1.592 +
   1.593 +    // Run function prototypes.    
   1.594 +    // Thread function and user handle passed to it, executed by the default
   1.595 +    // Thread::Run implementation if not null.
   1.596 +    typedef int (*ThreadFn)(Thread *pthread, void* h);
   1.597 +    
   1.598 +    // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried
   1.599 +    ThreadFn    ThreadFunction;    
   1.600 +    // User handle passes to a thread
   1.601 +    void*       UserHandle;
   1.602 +
   1.603 +    // Thread state to start a thread with
   1.604 +    enum ThreadState
   1.605 +    {
   1.606 +        NotRunning  = 0,
   1.607 +        Running     = 1,
   1.608 +        Suspended   = 2
   1.609 +    };
   1.610 +
   1.611 +    // Thread priority
   1.612 +    enum ThreadPriority
   1.613 +    {
   1.614 +        CriticalPriority,
   1.615 +        HighestPriority,
   1.616 +        AboveNormalPriority,
   1.617 +        NormalPriority,
   1.618 +        BelowNormalPriority,
   1.619 +        LowestPriority,
   1.620 +        IdlePriority,
   1.621 +    };
   1.622 +
   1.623 +    // Thread constructor parameters
   1.624 +    struct CreateParams
   1.625 +    {
   1.626 +        CreateParams(ThreadFn func = 0, void* hand = 0, UPInt ssize = 128 * 1024, 
   1.627 +                     int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority)
   1.628 +                     : threadFunction(func), userHandle(hand), stackSize(ssize), 
   1.629 +                       processor(proc), initialState(state), priority(prior) {}
   1.630 +        ThreadFn       threadFunction;   // Thread function
   1.631 +        void*          userHandle;       // User handle passes to a thread
   1.632 +        UPInt          stackSize;        // Thread stack size
   1.633 +        int            processor;        // Thread hardware processor
   1.634 +        ThreadState    initialState;     // 
   1.635 +        ThreadPriority priority;         // Thread priority
   1.636 +    };
   1.637 +
   1.638 +    // *** Constructors
   1.639 +
   1.640 +    // A default constructor always creates a thread in NotRunning state, because
   1.641 +    // the derived class has not yet been initialized. The derived class can call Start explicitly.
   1.642 +    // "processor" parameter specifies which hardware processor this thread will be run on. 
   1.643 +    // -1 means OS decides this. Implemented only on Win32
   1.644 +    Thread(UPInt stackSize = 128 * 1024, int processor = -1);
   1.645 +    // Constructors that initialize the thread with a pointer to function.
   1.646 +    // An option to start a thread is available, but it should not be used if classes are derived from Thread.
   1.647 +    // "processor" parameter specifies which hardware processor this thread will be run on. 
   1.648 +    // -1 means OS decides this. Implemented only on Win32
   1.649 +    Thread(ThreadFn threadFunction, void*  userHandle = 0, UPInt stackSize = 128 * 1024,
   1.650 +           int processor = -1, ThreadState initialState = NotRunning);
   1.651 +    // Constructors that initialize the thread with a create parameters structure.
   1.652 +    explicit Thread(const CreateParams& params);
   1.653 +
   1.654 +    // Destructor.
   1.655 +    virtual ~Thread();
   1.656 +
   1.657 +    // Waits for all Threads to finish; should be called only from the root
   1.658 +    // application thread. Once this function returns, we know that all other
   1.659 +    // thread's references to Thread object have been released.
   1.660 +    static  void OVR_CDECL FinishAllThreads();
   1.661 +
   1.662 +
   1.663 +    // *** Overridable Run function for thread processing
   1.664 +
   1.665 +    // - returning from this method will end the execution of the thread
   1.666 +    // - return value is usually 0 for success 
   1.667 +    virtual int   Run();
   1.668 +    // Called after return/exit function
   1.669 +    virtual void  OnExit();
   1.670 +
   1.671 +
   1.672 +    // *** Thread management
   1.673 +
   1.674 +    // Starts the thread if its not already running
   1.675 +    // - internally sets up the threading and calls Run()
   1.676 +    // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing
   1.677 +    // - returns the exit code
   1.678 +    virtual bool  Start(ThreadState initialState = Running);
   1.679 +
   1.680 +    // Quits with an exit code
   1.681 +    virtual void  Exit(int exitCode=0);
   1.682 +
   1.683 +    // Suspend the thread until resumed
   1.684 +    // Returns 1 for success, 0 for failure.
   1.685 +    bool  Suspend();
   1.686 +    // Resumes currently suspended thread
   1.687 +    // Returns 1 for success, 0 for failure.
   1.688 +    bool  Resume();
   1.689 +
   1.690 +    // Static function to return a pointer to the current thread
   1.691 +    //static Thread* GetThread();
   1.692 +
   1.693 +
   1.694 +    // *** Thread status query functions
   1.695 +
   1.696 +    bool          GetExitFlag() const;
   1.697 +    void          SetExitFlag(bool exitFlag);
   1.698 +
   1.699 +    // Determines whether the thread was running and is now finished
   1.700 +    bool          IsFinished() const;
   1.701 +    // Determines if the thread is currently suspended
   1.702 +    bool          IsSuspended() const;
   1.703 +    // Returns current thread state
   1.704 +    ThreadState   GetThreadState() const;
   1.705 +
   1.706 +    // Returns the number of available CPUs on the system 
   1.707 +    static int    GetCPUCount();
   1.708 +
   1.709 +    // Returns the thread exit code. Exit code is initialized to 0,
   1.710 +    // and set to the return value if Run function after the thread is finished.
   1.711 +    inline int    GetExitCode() const { return ExitCode; }
   1.712 +    // Returns an OS handle 
   1.713 +#if defined(OVR_OS_WIN32)
   1.714 +    void*          GetOSHandle() const { return ThreadHandle; }
   1.715 +#else
   1.716 +    pthread_t      GetOSHandle() const { return ThreadHandle; }
   1.717 +#endif
   1.718 +
   1.719 +#if defined(OVR_OS_WIN32)
   1.720 +    ThreadId       GetThreadId() const { return IdValue; }
   1.721 +#else
   1.722 +    ThreadId       GetThreadId() const { return (ThreadId)GetOSHandle(); }
   1.723 +#endif
   1.724 +
   1.725 +    static int      GetOSPriority(ThreadPriority);
   1.726 +    // *** Sleep
   1.727 +
   1.728 +    // Sleep secs seconds
   1.729 +    static bool    Sleep(unsigned secs);
   1.730 +    // Sleep msecs milliseconds
   1.731 +    static bool    MSleep(unsigned msecs);
   1.732 +
   1.733 +
   1.734 +    // *** Debugging functionality
   1.735 +#if defined(OVR_OS_WIN32)
   1.736 +    virtual void    SetThreadName( const char* name );
   1.737 +#else
   1.738 +    virtual void    SetThreadName( const char* name ) { OVR_UNUSED(name); }
   1.739 +#endif
   1.740 +
   1.741 +private:
   1.742 +#if defined(OVR_OS_WIN32)
   1.743 +    friend unsigned WINAPI Thread_Win32StartFn(void *pthread);
   1.744 +
   1.745 +#else
   1.746 +    friend void *Thread_PthreadStartFn(void * phandle);
   1.747 +
   1.748 +    static int            InitAttr;
   1.749 +    static pthread_attr_t Attr;
   1.750 +#endif
   1.751 +
   1.752 +protected:    
   1.753 +    // Thread state flags
   1.754 +    AtomicInt<UInt32>   ThreadFlags;
   1.755 +    AtomicInt<SInt32>   SuspendCount;
   1.756 +    UPInt               StackSize;
   1.757 +
   1.758 +    // Hardware processor which this thread is running on.
   1.759 +    int            Processor;
   1.760 +    ThreadPriority Priority;
   1.761 +
   1.762 +#if defined(OVR_OS_WIN32)
   1.763 +    void*               ThreadHandle;
   1.764 +    volatile ThreadId   IdValue;
   1.765 +
   1.766 +    // System-specific cleanup function called from destructor
   1.767 +    void                CleanupSystemThread();
   1.768 +
   1.769 +#else
   1.770 +    pthread_t           ThreadHandle;
   1.771 +#endif
   1.772 +
   1.773 +    // Exit code of the thread, as returned by Run.
   1.774 +    int                 ExitCode;
   1.775 +
   1.776 +    // Internal run function.
   1.777 +    int                 PRun();    
   1.778 +    // Finishes the thread and releases internal reference to it.
   1.779 +    void                FinishAndRelease();
   1.780 +
   1.781 +    void                Init(const CreateParams& params);
   1.782 +
   1.783 +    // Protected copy constructor
   1.784 +    Thread(const Thread &source) { OVR_UNUSED(source); }
   1.785 +
   1.786 +};
   1.787 +
   1.788 +// Returns the unique Id of a thread it is called on, intended for
   1.789 +// comparison purposes.
   1.790 +ThreadId GetCurrentThreadId();
   1.791 +
   1.792 +
   1.793 +} // OVR
   1.794 +
   1.795 +#endif // OVR_ENABLE_THREADS
   1.796 +#endif // OVR_Threads_h