From cdd3680b9e94640cc4956ae30de734cbe1e9bf76 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 3 Mar 2009 19:26:20 +0000 Subject: Look up SetProcessAffinityMask function at runtime, so that the program should work under Win9x again. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 1443 --- src/i_main.c | 92 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 24 deletions(-) (limited to 'src/i_main.c') diff --git a/src/i_main.c b/src/i_main.c index c103296b..7c5b16e7 100644 --- a/src/i_main.c +++ b/src/i_main.c @@ -46,47 +46,91 @@ #include "m_argv.h" #include "d_main.h" -#if !defined(_WIN32) && !defined(HAVE_SCHED_SETAFFINITY) -#warning No known way to set processor affinity on this platform. -#warning You may experience crashes due to SDL_mixer. -#endif +#if defined(_WIN32) -int main(int argc, char **argv) -{ - // save arguments +typedef BOOL WINAPI (*SetAffinityFunc)(HANDLE hProcess, DWORD_PTR mask); - myargc = argc; - myargv = argv; +// This is a bit more complicated than it really needs to be. We really +// just need to call the SetProcessAffinityMask function, but that +// function doesn't exist on systems before Windows 2000. Instead, +// dynamically look up the function and call the pointer to it. This +// way, the program will run on older versions of Windows (Win9x, etc.) -#ifdef _WIN32 +static void LockCPUAffinity(void) +{ + HMODULE kernel32_dll; + SetAffinityFunc SetAffinity; - // 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. + // Find the kernel interface DLL. - if (!SetProcessAffinityMask(GetCurrentProcess(), 1)) + kernel32_dll = LoadLibrary("kernel32.dll"); + + if (kernel32_dll == NULL) { - fprintf(stderr, "Failed to set process affinity mask (%d)\n", - (int) GetLastError()); + // This should never happen... + + fprintf(stderr, "Failed to load kernel32.dll\n"); + return; } -#endif + // Find the SetProcessAffinityMask function. -#ifdef HAVE_SCHED_SETAFFINITY + SetAffinity = GetProcAddress(kernel32_dll, "SetProcessAffinityMask"); - // Linux version: + // 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 != NULL) { - cpu_set_t set; + if (!SetAffinity(GetCurrentProcess(), 1)) + { + fprintf(stderr, "Failed to set process affinity (%d)\n", + (int) GetLastError()); + } + } +} - CPU_ZERO(&set); - CPU_SET(0, &set); +#elif defined(HAVE_SCHED_SETAFFINITY) - sched_setaffinity(getpid(), sizeof(set), &set); - } +// Unix (Linux) version: + +static void LockCPUAffinity(void) +{ + cpu_set_t set; + + CPU_ZERO(&set); + CPU_SET(0, &set); + + sched_setaffinity(getpid(), sizeof(set), &set); +} + +#else + +#warning No known way to set processor affinity on this platform. +#warning You may experience crashes due to SDL_mixer. + +static void LockCPUAffinity(void) +{ + fprintf(stderr, + "WARNING: No known way to set processor affinity on this platform.\n" + " You may experience crashes due to SDL_mixer.\n"); +} #endif +int main(int argc, char **argv) +{ + // save arguments + + myargc = argc; + myargv = argv; + + // Only schedule on a single core, if we have multiple + // cores. This is to work around a bug in SDL_mixer. + + LockCPUAffinity(); + // start doom D_DoomMain (); -- cgit v1.2.3