Fix building with GHC 6.8
[ghc-hetmet.git] / includes / OSThreads.h
index 9043144..d4dbc36 100644 (file)
 
 # if defined(HAVE_PTHREAD_H) && !defined(WANT_NATIVE_WIN32_THREADS)
 
+#if CMINUSMINUS
+
+#define ACQUIRE_LOCK(mutex) foreign "C" pthread_mutex_lock(mutex)
+#define RELEASE_LOCK(mutex) foreign "C" pthread_mutex_unlock(mutex)
+#define ASSERT_LOCK_HELD(mutex) /* nothing */
+
+#else
+
 #include <pthread.h>
+#include <errno.h>
 
 typedef pthread_cond_t  Condition;
 typedef pthread_mutex_t Mutex;
@@ -26,53 +35,53 @@ typedef pthread_key_t   ThreadLocalKey;
 #define INIT_COND_VAR       PTHREAD_COND_INITIALIZER
 
 #ifdef LOCK_DEBUG
+#define LOCK_DEBUG_BELCH(what, mutex) \
+  debugBelch("%s(0x%p) %s %d\n", what, mutex, __FILE__, __LINE__)
+#else
+#define LOCK_DEBUG_BELCH(what, mutex) /* nothing */
+#endif
 
+/* Always check the result of lock and unlock. */
 #define ACQUIRE_LOCK(mutex) \
-  debugBelch("ACQUIRE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \
-  pthread_mutex_lock(mutex)
-#define RELEASE_LOCK(mutex) \
-  debugBelch("RELEASE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \
-  pthread_mutex_unlock(mutex)
-#define ASSERT_LOCK_HELD(mutex) /* nothing */
-
-#elif defined(DEBUG) && defined(linux_HOST_OS)
-#include <errno.h>
-/* 
- * On Linux, we can use extensions to determine whether we already
- * hold a lock or not, which is useful for debugging.
- */
-#define ACQUIRE_LOCK(mutex) \
+  LOCK_DEBUG_BELCH("ACQUIRE_LOCK", mutex); \
   if (pthread_mutex_lock(mutex) == EDEADLK) { \
     barf("multiple ACQUIRE_LOCK: %s %d", __FILE__,__LINE__); \
   }
+
 #define RELEASE_LOCK(mutex) \
+  LOCK_DEBUG_BELCH("RELEASE_LOCK", mutex); \
   if (pthread_mutex_unlock(mutex) != 0) { \
     barf("RELEASE_LOCK: I do not own this lock: %s %d", __FILE__,__LINE__); \
   }
 
+// Note: this assertion calls pthread_mutex_lock() on a mutex that
+// is already held by the calling thread.  The mutex should therefore
+// have been created with PTHREAD_MUTEX_ERRORCHECK, otherwise this
+// assertion will hang.  We always initialise mutexes with
+// PTHREAD_MUTEX_ERRORCHECK when DEBUG is on (see rts/posix/OSThreads.h).
 #define ASSERT_LOCK_HELD(mutex) ASSERT(pthread_mutex_lock(mutex) == EDEADLK)
 
-#define ASSERT_LOCK_NOTHELD(mutex)             \
-  if (pthread_mutex_lock(mutex) != EDEADLK) {  \
-     pthread_mutex_unlock(mutex);              \
-  } else {                                     \
-    ASSERT(0);                                 \
-  }
+#endif // CMINUSMINUS
 
+# elif defined(HAVE_WINDOWS_H)
 
-#else
+#if CMINUSMINUS
+
+/* We jump through a hoop here to get a CCall EnterCriticalSection
+   and LeaveCriticalSection, as that's what C-- wants. */
 
-#define ACQUIRE_LOCK(mutex) pthread_mutex_lock(mutex)
-#define RELEASE_LOCK(mutex) pthread_mutex_unlock(mutex)
+#define ACQUIRE_LOCK(mutex) foreign "stdcall" EnterCriticalSection(mutex)
+#define RELEASE_LOCK(mutex) foreign "stdcall" LeaveCriticalSection(mutex)
 #define ASSERT_LOCK_HELD(mutex) /* nothing */
 
-#endif
+#else
 
-# elif defined(HAVE_WINDOWS_H)
 #include <windows.h>
 
 typedef HANDLE Condition;
 typedef DWORD OSThreadId;
+// don't be tempted to use HANDLE as the OSThreadId: there can be 
+// many HANDLES to a given thread, so comparison would not work.
 typedef DWORD ThreadLocalKey;
 
 #define OSThreadProcAttr __stdcall
@@ -131,10 +140,14 @@ typedef HANDLE Mutex;
 #define ASSERT_LOCK_HELD(mutex) /* nothing */
 #endif
 
+#endif // CMINUSMINUS
+
 # else
 #  error "Threads not supported"
 # endif
 
+
+#ifndef CMINUSMINUS
 //
 // General thread operations
 //
@@ -146,6 +159,7 @@ typedef void OSThreadProcAttr OSThreadProc(void *);
 
 extern int  createOSThread        ( OSThreadId* tid, 
                                    OSThreadProc *startProc, void *param);
+extern rtsBool osThreadIsAlive    ( OSThreadId id );
 
 //
 // Condition Variables
@@ -161,6 +175,7 @@ extern rtsBool waitCondition      ( Condition* pCond,
 // Mutexes
 //
 extern void initMutex             ( Mutex* pMut );
+extern void closeMutex            ( Mutex* pMut );
 
 //
 // Thread-local storage
@@ -168,6 +183,9 @@ extern void initMutex             ( Mutex* pMut );
 void  newThreadLocalKey (ThreadLocalKey *key);
 void *getThreadLocalVar (ThreadLocalKey *key);
 void  setThreadLocalVar (ThreadLocalKey *key, void *value);
+void  freeThreadLocalKey (ThreadLocalKey *key);
+
+#endif // !CMINUSMINUS
 
 #else