1 /* ---------------------------------------------------------------------------
3 * (c) The GHC Team, 2001
5 * Accessing OS threads functionality in a (mostly) OS-independent
8 * --------------------------------------------------------------------------*/
10 #ifndef __OSTHREADS_H__
11 #define __OSTHREADS_H__
13 #if defined(THREADED_RTS) /* to the end */
15 # if defined(HAVE_PTHREAD_H) && !defined(WANT_NATIVE_WIN32_THREADS)
19 typedef pthread_cond_t Condition;
20 typedef pthread_mutex_t Mutex;
21 typedef pthread_t OSThreadId;
22 typedef pthread_key_t ThreadLocalKey;
24 #define OSThreadProcAttr /* nothing */
26 #define INIT_MUTEX_VAR PTHREAD_MUTEX_INITIALIZER
27 #define INIT_COND_VAR PTHREAD_COND_INITIALIZER
31 #define ACQUIRE_LOCK(mutex) \
32 debugBelch("ACQUIRE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \
33 pthread_mutex_lock(mutex)
34 #define RELEASE_LOCK(mutex) \
35 debugBelch("RELEASE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \
36 pthread_mutex_unlock(mutex)
37 #define ASSERT_LOCK_HELD(mutex) /* nothing */
39 #elif defined(DEBUG) && defined(linux_HOST_OS)
42 * On Linux, we can use extensions to determine whether we already
43 * hold a lock or not, which is useful for debugging.
45 #define ACQUIRE_LOCK(mutex) \
46 if (pthread_mutex_lock(mutex) == EDEADLK) { \
47 barf("multiple ACQUIRE_LOCK: %s %d", __FILE__,__LINE__); \
49 #define RELEASE_LOCK(mutex) \
50 if (pthread_mutex_unlock(mutex) != 0) { \
51 barf("RELEASE_LOCK: I do not own this lock: %s %d", __FILE__,__LINE__); \
54 #define ASSERT_LOCK_HELD(mutex) ASSERT(pthread_mutex_lock(mutex) == EDEADLK)
56 #define ASSERT_LOCK_NOTHELD(mutex) \
57 if (pthread_mutex_lock(mutex) != EDEADLK) { \
58 pthread_mutex_unlock(mutex); \
66 #define ACQUIRE_LOCK(mutex) pthread_mutex_lock(mutex)
67 #define RELEASE_LOCK(mutex) pthread_mutex_unlock(mutex)
68 #define ASSERT_LOCK_HELD(mutex) /* nothing */
72 # elif defined(HAVE_WINDOWS_H)
75 typedef HANDLE Condition;
77 typedef DWORD OSThreadId;
78 typedef DWORD ThreadLocalKey;
80 #define OSThreadProcAttr __stdcall
82 #define INIT_MUTEX_VAR 0
83 #define INIT_COND_VAR 0
85 // casting to (Mutex *) here required due to use in .cmm files where
86 // the argument has (void *) type.
87 #define ACQUIRE_LOCK(mutex) \
88 if (WaitForSingleObject(*((Mutex *)mutex),INFINITE) == WAIT_FAILED) { \
89 barf("WaitForSingleObject: %d", GetLastError()); \
92 #define RELEASE_LOCK(mutex) \
93 if (ReleaseMutex(*((Mutex *)mutex)) == 0) { \
94 barf("ReleaseMutex: %d", GetLastError()); \
97 #define ASSERT_LOCK_HELD(mutex) /* nothing */
100 # error "Threads not supported"
104 // General thread operations
106 extern OSThreadId osThreadId ( void );
107 extern void shutdownThread ( void );
108 extern void yieldThread ( void );
110 typedef void OSThreadProcAttr OSThreadProc(void *);
112 extern int createOSThread ( OSThreadId* tid,
113 OSThreadProc *startProc, void *param);
116 // Condition Variables
118 extern void initCondition ( Condition* pCond );
119 extern void closeCondition ( Condition* pCond );
120 extern rtsBool broadcastCondition ( Condition* pCond );
121 extern rtsBool signalCondition ( Condition* pCond );
122 extern rtsBool waitCondition ( Condition* pCond,
128 extern void initMutex ( Mutex* pMut );
131 // Thread-local storage
133 void newThreadLocalKey (ThreadLocalKey *key);
134 void *getThreadLocalVar (ThreadLocalKey *key);
135 void setThreadLocalVar (ThreadLocalKey *key, void *value);
139 #define ACQUIRE_LOCK(l)
140 #define RELEASE_LOCK(l)
141 #define ASSERT_LOCK_HELD(l)
143 #endif /* defined(RTS_SUPPORTS_THREADS) */
145 #endif /* __OSTHREADS_H__ */