X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fwin32%2FOSThreads.c;h=cb00bd602dfd41e5cef8891c48f094f6cd80506d;hb=09895ff7da70ae311b8deb47d77d612fe9964403;hp=00effdaaac83adb807a29959cac38ff8ac6e7109;hpb=88b35c172f9434fd98b700f706074d142914a8bb;p=ghc-hetmet.git diff --git a/rts/win32/OSThreads.c b/rts/win32/OSThreads.c index 00effda..cb00bd6 100644 --- a/rts/win32/OSThreads.c +++ b/rts/win32/OSThreads.c @@ -7,10 +7,12 @@ * * --------------------------------------------------------------------------*/ +#define _WIN32_WINNT 0x0500 + #include "Rts.h" #if defined(THREADED_RTS) -#include "OSThreads.h" #include "RtsUtils.h" +#include /* For reasons not yet clear, the entire contents of process.h is protected * by __STRICT_ANSI__ not being defined. @@ -38,7 +40,8 @@ initCondition( Condition* pCond ) NULL); /* unnamed => process-local. */ if ( h == NULL ) { - errorBelch("initCondition: unable to create"); + sysErrorBelch("initCondition: unable to create"); + stg_exit(EXIT_FAILURE); } *pCond = h; return; @@ -48,7 +51,7 @@ void closeCondition( Condition* pCond ) { if ( CloseHandle(*pCond) == 0 ) { - errorBelch("closeCondition: failed to close"); + sysErrorBelch("closeCondition: failed to close"); } return; } @@ -64,7 +67,8 @@ rtsBool signalCondition ( Condition* pCond ) { if (SetEvent(*pCond) == 0) { - barf("SetEvent: %d", GetLastError()); + sysErrorBelch("SetEvent"); + stg_exit(EXIT_FAILURE); } return rtsTrue; } @@ -82,7 +86,7 @@ waitCondition ( Condition* pCond, Mutex* pMut ) void yieldThread() { - Sleep(0); + SwitchToThread(); return; } @@ -90,6 +94,7 @@ void shutdownThread() { _endthreadex(0); + barf("_endthreadex returned"); // avoid gcc warning } int @@ -110,6 +115,22 @@ osThreadId() return GetCurrentThreadId(); } +rtsBool +osThreadIsAlive(OSThreadId id) +{ + DWORD exit_code; + HANDLE hdl; + if (!(hdl = OpenThread(THREAD_QUERY_INFORMATION,FALSE,id))) { + sysErrorBelch("osThreadIsAlive: OpenThread"); + stg_exit(EXIT_FAILURE); + } + if (!GetExitCodeThread(hdl, &exit_code)) { + sysErrorBelch("osThreadIsAlive: GetExitCodeThread"); + stg_exit(EXIT_FAILURE); + } + return (exit_code == STILL_ACTIVE); +} + #ifdef USE_CRITICAL_SECTIONS void initMutex (Mutex* pMut) @@ -159,7 +180,8 @@ getThreadLocalVar (ThreadLocalKey *key) // r is allowed to be NULL - it can mean that either there was an // error or the stored value is in fact NULL. if (GetLastError() != NO_ERROR) { - barf("getThreadLocalVar: key not found"); + sysErrorBelch("getThreadLocalVar"); + stg_exit(EXIT_FAILURE); } #endif return r; @@ -171,7 +193,19 @@ setThreadLocalVar (ThreadLocalKey *key, void *value) BOOL b; b = TlsSetValue(*key, value); if (!b) { - barf("setThreadLocalVar: %d", GetLastError()); + sysErrorBelch("setThreadLocalVar"); + stg_exit(EXIT_FAILURE); + } +} + +void +freeThreadLocalKey (ThreadLocalKey *key) +{ + BOOL r; + r = TlsFree(*key); + if (r == 0) { + DWORD dw = GetLastError(); + barf("freeThreadLocalKey failed: %lu", dw); } } @@ -198,6 +232,43 @@ forkOS_createThread ( HsStablePtr entry ) (unsigned*)&pId) == 0); } +nat +getNumberOfProcessors (void) +{ + static nat nproc = 0; + + if (nproc == 0) { + SYSTEM_INFO si; + GetSystemInfo(&si); + nproc = si.dwNumberOfProcessors; + } + + return nproc; +} + +void +setThreadAffinity (nat n, nat m) // cap N of M +{ + HANDLE hThread; + DWORD_PTR mask, r; // 64-bit win is required to handle more than 32 procs + nat nproc, i; + + hThread = GetCurrentThread(); + + nproc = getNumberOfProcessors(); + + mask = 0; + for (i = n; i < nproc; i+=m) { + mask |= 1 << i; + } + + r = SetThreadAffinityMask(hThread, mask); + if (r == 0) { + sysErrorBelch("SetThreadAffinity"); + stg_exit(EXIT_FAILURE); + } +} + #else /* !defined(THREADED_RTS) */ int