diff --git a/src/thread/windows/SDL_sysmutex.c b/src/thread/windows/SDL_sysmutex.c index 8440ae7dc..fbcb1d3e1 100644 --- a/src/thread/windows/SDL_sysmutex.c +++ b/src/thread/windows/SDL_sysmutex.c @@ -30,7 +30,7 @@ struct SDL_mutex { - HANDLE id; + CRITICAL_SECTION cs; }; /* Create a mutex */ @@ -38,17 +38,29 @@ SDL_mutex * SDL_CreateMutex(void) { SDL_mutex *mutex; + static DWORD (WINAPI*pf_SetCriticalSectionSpinCount)(LPCRITICAL_SECTION, DWORD) = NULL; + static HMODULE kernel32 = NULL; + + /* One time logic - detect WinNT */ + if(kernel32 == NULL) { + kernel32 = GetModuleHandleA("kernel32.dll"); + if(kernel32) { + /* Attempt to resolve symbol -- Win9x gets NULL */ + pf_SetCriticalSectionSpinCount = (DWORD (WINAPI*)(LPCRITICAL_SECTION, DWORD))GetProcAddress(kernel32, "SetCriticalSectionSpinCount"); + } + else + kernel32 = (HMODULE)0x01; /* don't try to init again */ + } + /* Allocate mutex memory */ mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); if (mutex) { - /* Create the mutex, with initial value signaled */ - mutex->id = CreateMutex(NULL, FALSE, NULL); - if (!mutex->id) { - SDL_SetError("Couldn't create mutex"); - SDL_free(mutex); - mutex = NULL; - } + /* Initialize */ + InitializeCriticalSection(&mutex->cs); + + /* On SMP systems, a non-zero spin count generally helps performance */ + if(pf_SetCriticalSectionSpinCount) pf_SetCriticalSectionSpinCount(&mutex->cs, 2000); } else { SDL_OutOfMemory(); } @@ -60,10 +72,7 @@ void SDL_DestroyMutex(SDL_mutex * mutex) { if (mutex) { - if (mutex->id) { - CloseHandle(mutex->id); - mutex->id = 0; - } + DeleteCriticalSection(&mutex->cs); SDL_free(mutex); } } @@ -76,10 +85,8 @@ SDL_mutexP(SDL_mutex * mutex) SDL_SetError("Passed a NULL mutex"); return -1; } - if (WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED) { - SDL_SetError("Couldn't wait on mutex"); - return -1; - } + + EnterCriticalSection(&mutex->cs); return (0); } @@ -91,10 +98,8 @@ SDL_mutexV(SDL_mutex * mutex) SDL_SetError("Passed a NULL mutex"); return -1; } - if (ReleaseMutex(mutex->id) == FALSE) { - SDL_SetError("Couldn't release mutex"); - return -1; - } + + LeaveCriticalSection(&mutex->cs); return (0); }