summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ghc/includes/OSThreads.h30
-rw-r--r--ghc/rts/Schedule.c2
-rw-r--r--ghc/rts/Storage.c2
-rw-r--r--ghc/rts/win32/OSThreads.c8
4 files changed, 35 insertions, 7 deletions
diff --git a/ghc/includes/OSThreads.h b/ghc/includes/OSThreads.h
index c136aa5c6d..40c260bc0f 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 <windows.h>
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 c2426fa19e..d3851eb8c5 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 57e3d70683..e44348f5f4 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 f48540eea5..c772be38f4 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)