[project @ 2002-01-31 23:04:15 by sof]
[ghc-hetmet.git] / ghc / rts / OSThreads.c
1 /* ---------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 2001
4  *
5  * Accessing OS threads functionality in a (mostly) OS-independent
6  * manner. 
7  *
8  * 
9  * --------------------------------------------------------------------------*/
10 #include "Rts.h"
11 #if defined(RTS_SUPPORTS_THREADS)
12 #include "OSThreads.h"
13 #include "RtsUtils.h"
14
15 #if defined(HAVE_PTHREAD_H) && !defined(WANT_NATIVE_WIN32_THREADS)
16 /*
17  * This (allegedly) OS threads independent layer was initially
18  * abstracted away from code that used Pthreads, so the functions
19  * provided here are mostly just wrappers to the Pthreads API.
20  *
21  */
22
23 void initCondVar( CondVar* pCond )
24 {
25   pthread_cond_init(pCond, NULL);
26   return;
27 }
28
29 void closeCondVar( CondVar* pCond )
30 {
31   pthread_cond_destroy(pCond);
32   return;
33 }
34
35 rtsBool
36 broadcastCondVar ( CondVar* pCond )
37 {
38   return (pthread_cond_broadcast(pCond) == 0);
39 }
40
41 rtsBool
42 signalCondVar ( CondVar* pCond )
43 {
44   return (pthread_cond_signal(pCond) == 0);
45 }
46
47 rtsBool
48 waitCondVar ( CondVar* pCond, MutexVar* pMut )
49 {
50   return (pthread_cond_wait(pCond,pMut) == 0);
51 }
52
53 void shutdownThread()
54 {
55   pthread_exit(NULL);
56 }
57
58 int createOSThread ( OSThreadId* pId, void *(*startProc)(void*))
59 {
60   return pthread_create(pId, NULL, startProc, NULL);
61 }
62
63 OSThreadId osThreadId()
64 {
65   return pthread_self();
66 }
67
68 void initMutexVar (MutexVar* pMut)
69 {
70   pthread_mutex_init(pMut,NULL);
71   return;
72 }
73
74 #elif defined(HAVE_WINDOWS_H)
75 #include <process.h>
76
77 /* Win32 threads and synchronisation objects */
78
79 /* A CondVar is represented by a Win32 Event object,
80  * a MutexVar by a Mutex kernel object.
81  *
82  * ToDo: go through the defn and usage of these to
83  * make sure the semantics match up with that of 
84  * the (assumed) pthreads behaviour. This is really
85  * just a first pass at getting something compilable.
86  */
87
88 void initCondVar( CondVar* pCond )
89 {
90   HANDLE h =  CreateEvent(NULL, 
91                           TRUE,  /* manual reset */
92                           TRUE,  /* initially signalled */
93                           NULL); /* unnamed => process-local. */
94   
95   if ( h == NULL ) {
96     belch("initCondVar: unable to create");
97   }
98   *pCond = h;
99   return;
100 }
101
102 void closeCondVar( CondVar* pCond )
103 {
104   if ( CloseHandle(*pCond) == 0 ) {
105     belch("closeCondVar: failed to close");
106   }
107   return;
108 }
109
110 rtsBool
111 broadcastCondVar ( CondVar* pCond )
112 {
113   PulseEvent(*pCond);
114   return rtsTrue;
115 }
116
117 rtsBool
118 signalCondVar ( CondVar* pCond )
119 {
120   SetEvent(*pCond);
121   return rtsTrue;
122 }
123
124 rtsBool
125 waitCondVar ( CondVar* pCond, MutexVar* pMut )
126 {
127   ReleaseMutex(*pMut);
128   WaitForSingleObject(*pCond, INFINITE);
129   /* Hmm..use WaitForMultipleObjects() ? */
130   WaitForSingleObject(*pMut, INFINITE);
131   return rtsTrue;
132 }
133
134 void shutdownThread()
135 {
136   _endthreadex(0);
137 }
138
139 static unsigned __stdcall startProcWrapper(void* pReal);
140 static unsigned __stdcall startProcWrapper(void* pReal)
141 {
142   ((void (*)(void*))pReal)(NULL);
143   return 0;
144 }
145
146 int createOSThread ( OSThreadId* pId, void *(*startProc)(void*))
147 {
148   
149   return _beginthreadex ( NULL,  /* default security attributes */
150                           0,
151                           startProcWrapper,
152                           (void*)startProc,
153                           0,
154                           (unsigned*)pId);
155 }
156
157 OSThreadId osThreadId()
158 {
159   return GetCurrentThreadId();
160 }
161
162 void initMutexVar (MutexVar* pMut)
163 {
164   HANDLE h = CreateMutex ( NULL,  /* default sec. attributes */
165                            FALSE, /* not owned => initially signalled */
166                            NULL
167                            );
168   *pMut = h;
169   return;
170 }
171
172 #endif /* defined(HAVE_PTHREAD_H) */
173
174 #endif /* defined(RTS_SUPPORTS_THREADS) */