166 lines
4.6 KiB
Diff
166 lines
4.6 KiB
Diff
|
diff --git a/prboom2/CMakeLists.txt b/prboom2/CMakeLists.txt
|
||
|
index d317ddec..c86f76b0 100644
|
||
|
--- a/prboom2/CMakeLists.txt
|
||
|
+++ b/prboom2/CMakeLists.txt
|
||
|
@@ -53,6 +53,15 @@ endif()
|
||
|
check_symbol_exists(getopt "unistd.h" HAVE_GETOPT)
|
||
|
check_symbol_exists(mmap "sys/mman.h" HAVE_MMAP)
|
||
|
check_symbol_exists(CreateFileMapping "windows.h" HAVE_CREATE_FILE_MAPPING)
|
||
|
+if(NOT WIN32)
|
||
|
+ set(CMAKE_REQUIRED_DEFINITIONS_PREV ${CMAKE_REQUIRED_DEFINITIONS})
|
||
|
+ set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE)
|
||
|
+ check_symbol_exists(sched_setaffinity "sched.h" HAVE_SCHED_SETAFFINITY)
|
||
|
+ set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS_PREV})
|
||
|
+ if(HAVE_SCHED_SETAFFINITY)
|
||
|
+ add_definitions(-D_GNU_SOURCE)
|
||
|
+ endif()
|
||
|
+endif()
|
||
|
check_symbol_exists(strsignal "string.h" HAVE_STRSIGNAL)
|
||
|
check_symbol_exists(mkstemp "stdlib.h" HAVE_MKSTEMP)
|
||
|
|
||
|
diff --git a/prboom2/cmake/config.h.cin b/prboom2/cmake/config.h.cin
|
||
|
index f92f3d88..2ad70033 100644
|
||
|
--- a/prboom2/cmake/config.h.cin
|
||
|
+++ b/prboom2/cmake/config.h.cin
|
||
|
@@ -11,6 +11,7 @@
|
||
|
#cmakedefine HAVE_GETOPT
|
||
|
#cmakedefine HAVE_MMAP
|
||
|
#cmakedefine HAVE_CREATE_FILE_MAPPING
|
||
|
+#cmakedefine HAVE_SCHED_SETAFFINITY
|
||
|
#cmakedefine HAVE_STRSIGNAL
|
||
|
#cmakedefine HAVE_MKSTEMP
|
||
|
|
||
|
diff --git a/prboom2/src/SDL/i_main.c b/prboom2/src/SDL/i_main.c
|
||
|
index 7537c53f..670f3dbd 100644
|
||
|
--- a/prboom2/src/SDL/i_main.c
|
||
|
+++ b/prboom2/src/SDL/i_main.c
|
||
|
@@ -45,6 +45,9 @@
|
||
|
#ifdef _WIN32
|
||
|
#define WIN32_LEAN_AND_MEAN
|
||
|
#include <windows.h>
|
||
|
+typedef BOOL (WINAPI *SetAffinityFunc)(HANDLE hProcess, DWORD mask);
|
||
|
+#else
|
||
|
+#include <sched.h>
|
||
|
#endif
|
||
|
|
||
|
#include <errno.h>
|
||
|
@@ -373,6 +376,83 @@ static void I_Quit (void)
|
||
|
uid_t stored_euid = -1;
|
||
|
#endif
|
||
|
|
||
|
+//
|
||
|
+// Ability to use only the allowed CPUs
|
||
|
+//
|
||
|
+
|
||
|
+static void I_SetAffinityMask(void)
|
||
|
+{
|
||
|
+ // This was only set for the sdl music backend,
|
||
|
+ // but now the backend changes based on the music type.
|
||
|
+ // Not sure what the consequences are for this...
|
||
|
+ process_affinity_mask = 1;
|
||
|
+
|
||
|
+ // Set the process affinity mask so that all threads
|
||
|
+ // run on the same processor. This is a workaround for a bug in
|
||
|
+ // SDL_mixer that causes occasional crashes.
|
||
|
+ if (process_affinity_mask)
|
||
|
+ {
|
||
|
+ const char *errbuf = NULL;
|
||
|
+#ifdef _WIN32
|
||
|
+ HMODULE kernel32_dll;
|
||
|
+ SetAffinityFunc SetAffinity = NULL;
|
||
|
+ int ok = false;
|
||
|
+
|
||
|
+ // Find the kernel interface DLL.
|
||
|
+ kernel32_dll = LoadLibrary("kernel32.dll");
|
||
|
+
|
||
|
+ if (kernel32_dll)
|
||
|
+ {
|
||
|
+ // Find the SetProcessAffinityMask function.
|
||
|
+ SetAffinity = (SetAffinityFunc)GetProcAddress(kernel32_dll, "SetProcessAffinityMask");
|
||
|
+
|
||
|
+ // If the function was not found, we are on an old (Win9x) system
|
||
|
+ // that doesn't have this function. That's no problem, because
|
||
|
+ // those systems don't support SMP anyway.
|
||
|
+
|
||
|
+ if (SetAffinity)
|
||
|
+ {
|
||
|
+ ok = SetAffinity(GetCurrentProcess(), process_affinity_mask);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!ok)
|
||
|
+ {
|
||
|
+ errbuf = WINError();
|
||
|
+ }
|
||
|
+#elif defined(HAVE_SCHED_SETAFFINITY)
|
||
|
+ // POSIX version:
|
||
|
+ int i;
|
||
|
+ {
|
||
|
+ cpu_set_t set;
|
||
|
+
|
||
|
+ CPU_ZERO(&set);
|
||
|
+
|
||
|
+ for(i = 0; i < 16; i++)
|
||
|
+ {
|
||
|
+ CPU_SET((process_affinity_mask>>i)&1, &set);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
|
||
|
+ {
|
||
|
+ errbuf = strerror(errno);
|
||
|
+ }
|
||
|
+ }
|
||
|
+#else
|
||
|
+ return;
|
||
|
+#endif
|
||
|
+
|
||
|
+ if (errbuf == NULL)
|
||
|
+ {
|
||
|
+ lprintf(LO_INFO, "I_SetAffinityMask: manual affinity mask is %d\n", process_affinity_mask);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ lprintf(LO_ERROR, "I_SetAffinityMask: failed to set process affinity mask (%s)\n", errbuf);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
//
|
||
|
// Sets the priority class for the prboom-plus process
|
||
|
//
|
||
|
@@ -482,6 +562,9 @@ int main(int argc, char **argv)
|
||
|
signal(SIGABRT, I_SignalHandler);
|
||
|
#endif
|
||
|
|
||
|
+ // Ability to use only the allowed CPUs
|
||
|
+ I_SetAffinityMask();
|
||
|
+
|
||
|
// Priority class for the prboom-plus process
|
||
|
I_SetProcessPriority();
|
||
|
|
||
|
diff --git a/prboom2/src/SDL/i_video.c b/prboom2/src/SDL/i_video.c
|
||
|
index 5a564a5a..9b68aee7 100644
|
||
|
--- a/prboom2/src/SDL/i_video.c
|
||
|
+++ b/prboom2/src/SDL/i_video.c
|
||
|
@@ -895,6 +895,7 @@ static void I_ClosestResolution (int *width, int *height)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+int process_affinity_mask;
|
||
|
int process_priority;
|
||
|
|
||
|
// e6y
|
||
|
diff --git a/prboom2/src/i_video.h b/prboom2/src/i_video.h
|
||
|
index 46f0fb71..c39a197e 100644
|
||
|
--- a/prboom2/src/i_video.h
|
||
|
+++ b/prboom2/src/i_video.h
|
||
|
@@ -109,6 +109,8 @@ void I_UpdateRenderSize(void); // Handle potential
|
||
|
extern int renderW; // resolution scaling
|
||
|
extern int renderH; // - DTIED
|
||
|
|
||
|
+// Set the process affinity mask so that all threads
|
||
|
+extern int process_affinity_mask;
|
||
|
// Priority class for the prboom-plus process
|
||
|
extern int process_priority;
|
||
|
// Use vanilla keybaord mapping
|