From 2846bc8a8a6a02851dd62e2c04be358902eee204 Mon Sep 17 00:00:00 2001 From: simonmar Date: Fri, 4 Nov 2005 12:02:05 +0000 Subject: [PATCH] [project @ 2005-11-04 12:02:04 by simonmar] Win32: Use CriticalSections instead of Mutexes, they are *much* faster. --- ghc/includes/OSThreads.h | 30 +++++++++++++++++++++++++----- ghc/rts/Schedule.c | 2 +- ghc/rts/Storage.c | 2 +- ghc/rts/win32/OSThreads.c | 8 ++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/ghc/includes/OSThreads.h b/ghc/includes/OSThreads.h index c136aa5..40c260b 100644 --- a/ghc/includes/OSThreads.h +++ b/ghc/includes/OSThreads.h @@ -1,6 +1,6 @@ /* --------------------------------------------------------------------------- * - * (c) The GHC Team, 2001 + * (c) The GHC Team, 2001-2005 * * Accessing OS threads functionality in a (mostly) OS-independent * manner. @@ -23,7 +23,6 @@ typedef pthread_key_t ThreadLocalKey; #define OSThreadProcAttr /* nothing */ -#define INIT_MUTEX_VAR PTHREAD_MUTEX_INITIALIZER #define INIT_COND_VAR PTHREAD_COND_INITIALIZER #ifdef LOCK_DEBUG @@ -73,15 +72,35 @@ typedef pthread_key_t ThreadLocalKey; #include typedef HANDLE Condition; -typedef HANDLE Mutex; typedef DWORD OSThreadId; typedef DWORD ThreadLocalKey; #define OSThreadProcAttr __stdcall -#define INIT_MUTEX_VAR 0 #define INIT_COND_VAR 0 +// We have a choice for implementing Mutexes on Windows. Standard +// Mutexes are kernel objects that require kernel calls to +// acquire/release, whereas CriticalSections are spin-locks that block +// in the kernel after spinning for a configurable number of times. +// CriticalSections are *much* faster, so we use those. The Mutex +// implementation is left here for posterity. +#define USE_CRITICAL_SECTIONS 1 + +#if USE_CRITICAL_SECTIONS + +typedef CRITICAL_SECTION Mutex; +#define ACQUIRE_LOCK(mutex) EnterCriticalSection(mutex) +#define RELEASE_LOCK(mutex) LeaveCriticalSection(mutex) + +// I don't know how to do this. TryEnterCriticalSection() doesn't do +// the right thing. +#define ASSERT_LOCK_HELD(mutex) /* nothing */ + +#else + +typedef HANDLE Mutex; + // casting to (Mutex *) here required due to use in .cmm files where // the argument has (void *) type. #define ACQUIRE_LOCK(mutex) \ @@ -95,6 +114,7 @@ typedef DWORD ThreadLocalKey; } #define ASSERT_LOCK_HELD(mutex) /* nothing */ +#endif # else # error "Threads not supported" @@ -140,6 +160,6 @@ void setThreadLocalVar (ThreadLocalKey *key, void *value); #define RELEASE_LOCK(l) #define ASSERT_LOCK_HELD(l) -#endif /* defined(RTS_SUPPORTS_THREADS) */ +#endif /* defined(THREADED_RTS) */ #endif /* __OSTHREADS_H__ */ diff --git a/ghc/rts/Schedule.c b/ghc/rts/Schedule.c index c2426fa..d3851eb 100644 --- a/ghc/rts/Schedule.c +++ b/ghc/rts/Schedule.c @@ -192,7 +192,7 @@ rtsBool shutting_down_scheduler = rtsFalse; * the THREADED_RTS and (inc. SMP) runtime. */ #if defined(THREADED_RTS) -Mutex sched_mutex = INIT_MUTEX_VAR; +Mutex sched_mutex; #endif #if defined(PARALLEL_HASKELL) diff --git a/ghc/rts/Storage.c b/ghc/rts/Storage.c index 57e3d70..e44348f 100644 --- a/ghc/rts/Storage.c +++ b/ghc/rts/Storage.c @@ -56,7 +56,7 @@ step *nurseries = NULL; /* array of nurseries, >1 only if SMP */ * simultaneous access by two STG threads. */ #ifdef SMP -Mutex sm_mutex = INIT_MUTEX_VAR; +Mutex sm_mutex; #endif /* diff --git a/ghc/rts/win32/OSThreads.c b/ghc/rts/win32/OSThreads.c index f48540e..c772be3 100644 --- a/ghc/rts/win32/OSThreads.c +++ b/ghc/rts/win32/OSThreads.c @@ -110,6 +110,13 @@ osThreadId() return GetCurrentThreadId(); } +#ifdef USE_CRITICAL_SECTIONS +void +initMutex (Mutex* pMut) +{ + InitializeCriticalSectionAndSpinCount(pMut,4000); +} +#else void initMutex (Mutex* pMut) { @@ -120,6 +127,7 @@ initMutex (Mutex* pMut) *pMut = h; return; } +#endif void newThreadLocalKey (ThreadLocalKey *key) -- 1.7.10.4