Win32 thread priority isolation layer
other changes merged in this commit: Update RageSoundReader_ThreadedBuffer.h Update GameLoop.cpp Update CMakeData-os.cmake
This commit is contained in:
@@ -57,6 +57,7 @@ else()
|
|||||||
"archutils/Win32/RegistryAccess.cpp"
|
"archutils/Win32/RegistryAccess.cpp"
|
||||||
"archutils/Win32/RestartProgram.cpp"
|
"archutils/Win32/RestartProgram.cpp"
|
||||||
"archutils/Win32/SpecialDirs.cpp"
|
"archutils/Win32/SpecialDirs.cpp"
|
||||||
|
"archutils/Win32/ThreadPriorityHelper.cpp"
|
||||||
"archutils/Win32/USB.cpp"
|
"archutils/Win32/USB.cpp"
|
||||||
"archutils/Win32/VideoDriverInfo.cpp"
|
"archutils/Win32/VideoDriverInfo.cpp"
|
||||||
"archutils/Win32/WindowIcon.cpp"
|
"archutils/Win32/WindowIcon.cpp"
|
||||||
@@ -82,6 +83,7 @@ else()
|
|||||||
"archutils/Win32/RegistryAccess.h"
|
"archutils/Win32/RegistryAccess.h"
|
||||||
"archutils/Win32/RestartProgram.h"
|
"archutils/Win32/RestartProgram.h"
|
||||||
"archutils/Win32/SpecialDirs.h"
|
"archutils/Win32/SpecialDirs.h"
|
||||||
|
"archutils/Win32/ThreadPriorityHelper.h"
|
||||||
"archutils/Win32/USB.h"
|
"archutils/Win32/USB.h"
|
||||||
"archutils/Win32/VideoDriverInfo.h"
|
"archutils/Win32/VideoDriverInfo.h"
|
||||||
"archutils/Win32/WindowIcon.h"
|
"archutils/Win32/WindowIcon.h"
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "archutils/Win32/ThreadPriorityHelper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static RageTimer g_GameplayTimer;
|
static RageTimer g_GameplayTimer;
|
||||||
|
|
||||||
@@ -410,6 +413,13 @@ void ConcurrentRenderer::RenderThread()
|
|||||||
|
|
||||||
if( m_State == RENDERING_START )
|
if( m_State == RENDERING_START )
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool setThreadSuccess = BoostThreadPriorityToHighest();
|
||||||
|
if (!setThreadSuccess)
|
||||||
|
{
|
||||||
|
ASSERT_M(0, "Failed to set thread priority to highest.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* We're starting to render. Set up, and then kick the event to wake
|
/* We're starting to render. Set up, and then kick the event to wake
|
||||||
* up the calling thread. */
|
* up the calling thread. */
|
||||||
DISPLAY->BeginConcurrentRendering();
|
DISPLAY->BeginConcurrentRendering();
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
#include "RageThreads.h"
|
#include "RageThreads.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "archutils/Win32/ThreadPriorityHelper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class RageThread;
|
class RageThread;
|
||||||
class RageSoundReader_ThreadedBuffer: public RageSoundReader_Filter
|
class RageSoundReader_ThreadedBuffer: public RageSoundReader_Filter
|
||||||
{
|
{
|
||||||
@@ -70,7 +74,19 @@ private:
|
|||||||
|
|
||||||
RageThread m_Thread;
|
RageThread m_Thread;
|
||||||
bool m_bShutdownThread;
|
bool m_bShutdownThread;
|
||||||
static int StartBufferingThread( void *p ) { ((RageSoundReader_ThreadedBuffer *) p)->BufferingThread(); return 0; }
|
static int StartBufferingThread(void* p)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool setThreadSuccess = BoostThreadPriorityToHighest();
|
||||||
|
if (!setThreadSuccess)
|
||||||
|
{
|
||||||
|
ASSERT_M(0, "Failed to set thread priority to highest.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
((RageSoundReader_ThreadedBuffer*)p)->BufferingThread();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void BufferingThread();
|
void BufferingThread();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#include "ThreadPriorityHelper.h"
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
bool SetThreadPriorityLevel(int priorityLevel)
|
||||||
|
{
|
||||||
|
return SetThreadPriority(GetCurrentThread(), priorityLevel) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoostThreadPriorityToBelowNormal()
|
||||||
|
{
|
||||||
|
return SetThreadPriorityLevel(THREAD_PRIORITY_BELOW_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoostThreadPriorityToNormal()
|
||||||
|
{
|
||||||
|
return SetThreadPriorityLevel(THREAD_PRIORITY_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoostThreadPriorityToAboveNormal()
|
||||||
|
{
|
||||||
|
return SetThreadPriorityLevel(THREAD_PRIORITY_ABOVE_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoostThreadPriorityToHighest()
|
||||||
|
{
|
||||||
|
return SetThreadPriorityLevel(THREAD_PRIORITY_HIGHEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoostThreadPriorityToTimeCritical()
|
||||||
|
{
|
||||||
|
return SetThreadPriorityLevel(THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*++
|
||||||
|
|
||||||
|
A layer to isolate windows.h from other source files while retaining the ability to set thread priorities.
|
||||||
|
|
||||||
|
One possible way to call it if you don't need to store the result is like so:
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool SuccessStatus = BoostThreadPriorityToHighest();
|
||||||
|
if (!SuccessStatus)
|
||||||
|
{
|
||||||
|
ASSERT_M(0, "Failed to set thread priority to highest.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Please refer to the Windows SetThreadPriority function documentation for more information.
|
||||||
|
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
|
||||||
|
|
||||||
|
Please maintain this priority structure for the threads:
|
||||||
|
|
||||||
|
Highest or Time Critical
|
||||||
|
* Rendering thread
|
||||||
|
* Audio mixing thread
|
||||||
|
- If this is not high enough priority, it can negatively affect the game clock
|
||||||
|
|
||||||
|
Above Normal or Highest
|
||||||
|
* Audio decoding thread
|
||||||
|
* Audio streaming thread
|
||||||
|
* Audio buffering thread
|
||||||
|
|
||||||
|
Normal
|
||||||
|
* Main game thread
|
||||||
|
- Please keep this below the audio thread priority
|
||||||
|
|
||||||
|
Below Normal
|
||||||
|
* Worker threads
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
bool SetThreadPriorityLevel(int priorityLevel);
|
||||||
|
|
||||||
|
bool BoostThreadPriorityToBelowNormal();
|
||||||
|
bool BoostThreadPriorityToNormal();
|
||||||
|
bool BoostThreadPriorityToAboveNormal();
|
||||||
|
bool BoostThreadPriorityToHighest();
|
||||||
|
bool BoostThreadPriorityToTimeCritical();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (c) sukibaby 2024
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, and/or sell copies of the Software, and to permit persons to
|
||||||
|
* whom the Software is furnished to do so, provided that the above
|
||||||
|
* copyright notice(s) and this permission notice appear in all copies of
|
||||||
|
* the Software and that both the above copyright notice(s) and this
|
||||||
|
* permission notice appear in supporting documentation.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||||
|
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
||||||
|
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
||||||
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user