aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
diff options
context:
space:
mode:
authorBrad Davis <[email protected]>2014-10-24 12:56:30 -0700
committerBrad Davis <[email protected]>2014-10-24 12:56:30 -0700
commit496894ecced1b0a4ae5ab176902bbd0f43a31ed1 (patch)
tree8b7d4be1fc8508253d399d98da6143212ceb8f3c /LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
parent911239601768bacf9420ab9cfeffed7e861844ac (diff)
Updating to 0.4.3 SDK0.4.3-official
Diffstat (limited to 'LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp')
-rw-r--r--LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp118
1 files changed, 99 insertions, 19 deletions
diff --git a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
index c1a368a..bdca233 100644
--- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
+++ b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
@@ -6,16 +6,16 @@ Content : Windows specific thread-related (safe) functionality
Created : September 19, 2012
Notes :
-Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
-Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
+Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
you may not use the Oculus VR Rift SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
-http://www.oculusvr.com/licenses/LICENSE-3.1
+http://www.oculusvr.com/licenses/LICENSE-3.2
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
distributed under the License is distributed on an "AS IS" BASIS,
@@ -68,7 +68,12 @@ MutexImpl::MutexImpl(bool recursive)
{
Recursive = recursive;
LockCount = 0;
+#if defined(OVR_OS_WIN32) // Older versions of Windows don't support CreateSemaphoreEx, so stick with CreateSemaphore for portability.
hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL);
+#else
+ // No CreateSemaphore() call, so emulate it.
+ hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphoreEx(NULL, 1, 1, NULL, 0, SEMAPHORE_ALL_ACCESS);
+#endif
}
MutexImpl::~MutexImpl()
{
@@ -827,19 +832,79 @@ int Thread::GetOSPriority(ThreadPriority p)
{
switch(p)
{
- case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL;
- case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST;
- case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL;
- case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL;
- case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL;
- case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST;
- case Thread::IdlePriority: return THREAD_PRIORITY_IDLE;
+ // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14.
+ case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; // 15
+ case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; // 2
+ case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; // 1
+ case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; // 0
+ case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; // -1
+ case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; // -2
+ case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; // -15
}
return THREAD_PRIORITY_NORMAL;
}
+/* static */
+Thread::ThreadPriority Thread::GetOVRPriority(int osPriority)
+{
+ // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14.
+ // As a result, it's possible for those cases that an unknown/invalid ThreadPriority enum be returned. However,
+ // in practice we don't expect to be using such processes.
+
+ // The ThreadPriority types aren't linearly distributed, so we need to check for some values explicitly.
+ if(osPriority == THREAD_PRIORITY_TIME_CRITICAL)
+ return Thread::CriticalPriority;
+ if(osPriority == THREAD_PRIORITY_IDLE)
+ return Thread::IdlePriority;
+ return (ThreadPriority)(Thread::NormalPriority - osPriority);
+}
+
+Thread::ThreadPriority Thread::GetPriority()
+{
+ int osPriority = ::GetThreadPriority(ThreadHandle);
+
+ if(osPriority != THREAD_PRIORITY_ERROR_RETURN)
+ {
+ return GetOVRPriority(osPriority);
+ }
+
+ return NormalPriority;
+}
+
+/* static */
+Thread::ThreadPriority Thread::GetCurrentPriority()
+{
+ int osPriority = ::GetThreadPriority(::GetCurrentThread());
+
+ if(osPriority != THREAD_PRIORITY_ERROR_RETURN)
+ {
+ return GetOVRPriority(osPriority);
+ }
+
+ return NormalPriority;
+}
+
+bool Thread::SetPriority(ThreadPriority p)
+{
+ BOOL ret = ::SetThreadPriority(ThreadHandle, Thread::GetOSPriority(p));
+ return (ret != FALSE);
+}
+
+/* static */
+bool Thread::SetCurrentPriority(ThreadPriority p)
+{
+ BOOL ret = ::SetThreadPriority(::GetCurrentThread(), Thread::GetOSPriority(p));
+ return (ret != FALSE);
+}
+
+
+
// The actual first function called on thread start
+#if defined(OVR_OS_WIN32)
unsigned WINAPI Thread_Win32StartFn(void * phandle)
+#else // Other Micorosft OSs...
+DWORD WINAPI Thread_Win32StartFn(void *phandle)
+#endif
{
Thread * pthread = (Thread*)phandle;
if (pthread->Processor != -1)
@@ -886,8 +951,15 @@ bool Thread::Start(ThreadState initialState)
ExitCode = 0;
SuspendCount = 0;
ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
+#if defined(OVR_OS_WIN32)
ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize,
Thread_Win32StartFn, this, 0, (unsigned*)&IdValue);
+#else // Other Micorosft OSs...
+ DWORD TheThreadId;
+ ThreadHandle = CreateThread(0, (unsigned)StackSize,
+ Thread_Win32StartFn, this, 0, &TheThreadId);
+ IdValue = (ThreadId)TheThreadId;
+#endif
// Failed? Fail the function
if (ThreadHandle == 0)
@@ -959,7 +1031,11 @@ void Thread::Exit(int exitCode)
ThreadList::RemoveRunningThread(this);
// Call the exit function.
+#if defined(OVR_OS_WIN32) // _endthreadex doesn't exist on other Microsoft OSs and instead we need to call ExitThread directly.
_endthreadex((unsigned)exitCode);
+#else
+ ExitThread((unsigned)exitCode);
+#endif
}
@@ -990,13 +1066,15 @@ bool Thread::MSleep(unsigned msecs)
void Thread::SetThreadName( const char* name )
{
#if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING)
- // Looks ugly, but it is the recommended way to name a thread.
- typedef struct tagTHREADNAME_INFO {
+ // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+ #pragma pack(push,8)
+ struct THREADNAME_INFO {
DWORD dwType; // Must be 0x1000
LPCSTR szName; // Pointer to name (in user address space)
DWORD dwThreadID; // Thread ID (-1 for caller thread)
DWORD dwFlags; // Reserved for future use; must be zero
- } THREADNAME_INFO;
+ };
+ #pragma pack(pop)
THREADNAME_INFO info;
@@ -1007,11 +1085,7 @@ void Thread::SetThreadName( const char* name )
__try
{
-#ifdef _WIN64
- RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (const ULONG_PTR *)&info );
-#else
- RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD *)&info );
-#endif
+ RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR *>(&info));
}
__except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER )
{
@@ -1024,7 +1098,13 @@ void Thread::SetThreadName( const char* name )
int Thread::GetCPUCount()
{
SYSTEM_INFO sysInfo;
- GetSystemInfo(&sysInfo);
+
+ #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) // GetNativeSystemInfo requires WinXP+ and a corresponding SDK (0x0501) or later.
+ GetNativeSystemInfo(&sysInfo);
+ #else
+ GetSystemInfo(&sysInfo);
+ #endif
+
return (int) sysInfo.dwNumberOfProcessors;
}