blob: 453e942b99833f4a40b9265420ad8a0e152edeb2 [file] [log] [blame]
Guido van Rossumc3f82b61995-01-17 16:29:31 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* This code implemented by Dag.Gruneau@elsa.preseco.comm.se */
26
27#include "windows.h"
28#include "limits.h"
29
30long get_thread_ident(void);
31
32/*
33 * Change all headers to pure ANSI as no one will use K&R style on an
34 * NT
35 */
36
37/*
38 * Initialization of the C package, should not be needed.
39 */
40static void _init_thread(void)
41{
42}
43
44/*
45 * Thread support.
46 */
47int start_new_thread(void (*func)(void *), void *arg)
48{
49 HANDLE aThread;
50 DWORD aThreadId;
51
52 int success = 0; /* init not needed when SOLARIS_THREADS and */
53 /* C_THREADS implemented properly */
54 dprintf(("%ld: start_new_thread called\n", get_thread_ident()));
55 if (!initialized)
56 init_thread();
57
58 aThread = CreateThread(
59 NULL, /* No security attributes */
60 0, /* use default stack size */
61 (LPTHREAD_START_ROUTINE) func, /* thread function */
62 (LPVOID) arg, /* argument to thread function */
63 0, /* use the default creation flags */
64 &aThreadId); /* returns the thread identifier */
65
66 if (aThread != NULL) {
67 CloseHandle(aThread); /* We do not want to have any zombies hanging around */
68 success = 1;
69 dprintf(("%ld: start_new_thread succeeded: %ld\n", get_thread_ident(), aThreadId));
70 }
71
72 return success;
73}
74
75/*
76 * Return the thread Id instead of an handle. The Id is said to uniquely identify the
77 * thread in the system
78 */
79long get_thread_ident(void)
80{
81 if (!initialized)
82 init_thread();
83
84 return GetCurrentThreadId();
85}
86
87static void do_exit_thread(int no_cleanup)
88{
89 dprintf(("%ld: exit_thread called\n", get_thread_ident()));
90 if (!initialized)
91 if (no_cleanup)
92 _exit(0);
93 else
94 exit(0);
95 ExitThread(0);
96}
97
98void exit_thread(void)
99{
100 do_exit_thread(0);
101}
102
103void _exit_thread(void)
104{
105 do_exit_thread(1);
106}
107
108#ifndef NO_EXIT_PROG
109static void do_exit_prog(int status, int no_cleanup)
110{
111 dprintf(("exit_prog(%d) called\n", status));
112 if (!initialized)
113 if (no_cleanup)
114 _exit(status);
115 else
116 exit(status);
117}
118
119void exit_prog(int status)
120{
121 do_exit_prog(status, 0);
122}
123
124void _exit_prog _P1(int status)
125{
126 do_exit_prog(status, 1);
127}
128#endif /* NO_EXIT_PROG */
129
130/*
131 * Lock support. It has too be implemented as semaphores.
132 * I [Dag] tried to implement it with mutex but I could find a way to
133 * tell whether a thread already own the lock or not.
134 */
135type_lock allocate_lock(void)
136{
137 HANDLE aLock;
138
139 dprintf(("allocate_lock called\n"));
140 if (!initialized)
141 init_thread();
142
143 aLock = CreateSemaphore(NULL, /* Security attributes */
144 1, /* Initial value */
145 1, /* Maximum value */
146 NULL);
147 /* Name of semaphore */
148
149 dprintf(("%ld: allocate_lock() -> %lx\n", get_thread_ident(), (long)aLock));
150
151 return (type_lock) aLock;
152}
153
154void free_lock(type_lock aLock)
155{
156 dprintf(("%ld: free_lock(%lx) called\n", get_thread_ident(),(long)aLock));
157
158 CloseHandle((HANDLE) aLock);
159}
160
161/*
162 * Return 1 on success if the lock was acquired
163 *
164 * and 0 if the lock was not acquired. This means a 0 is returned
165 * if the lock has already been acquired by this thread!
166 */
167int acquire_lock(type_lock aLock, int waitflag)
168{
169 int success = 1;
170 DWORD waitResult;
171
172 dprintf(("%ld: acquire_lock(%lx, %d) called\n", get_thread_ident(),(long)aLock, waitflag));
173
174 waitResult = WaitForSingleObject((HANDLE) aLock, (waitflag == 1 ? INFINITE : 0));
175
176 if (waitResult != WAIT_OBJECT_0) {
177 success = 0; /* We failed */
178 }
179
180 dprintf(("%ld: acquire_lock(%lx, %d) -> %d\n", get_thread_ident(),(long)aLock, waitflag, success));
181
182 return success;
183}
184
185void release_lock(type_lock aLock)
186{
187 dprintf(("%ld: release_lock(%lx) called\n", get_thread_ident(),(long)aLock));
188
189 if (!ReleaseSemaphore(
190 (HANDLE) aLock, /* Handle of semaphore */
191 1, /* increment count by one */
192 NULL)) /* not interested in previous count */
193 {
194 dprintf(("%ld: Could not release_lock(%lx) error: %l\n", get_thread_ident(), (long)aLock, GetLastError()));
195 }
196}
197
198/*
199 * Semaphore support.
200 */
201type_sema allocate_sema(int value)
202{
203 HANDLE aSemaphore;
204
205 dprintf(("%ld: allocate_sema called\n", get_thread_ident()));
206 if (!initialized)
207 init_thread();
208
209 aSemaphore = CreateSemaphore( NULL, /* Security attributes */
210 value, /* Initial value */
211 INT_MAX, /* Maximum value */
212 NULL); /* Name of semaphore */
213
214 dprintf(("%ld: allocate_sema() -> %lx\n", get_thread_ident(), (long)aSemaphore));
215
216 return (type_sema) aSemaphore;
217}
218
219void free_sema(type_sema aSemaphore)
220{
221 dprintf(("%ld: free_sema(%lx) called\n", get_thread_ident(), (long)aSemaphore));
222
223 CloseHandle((HANDLE) aSemaphore);
224}
225
226void down_sema(type_sema aSemaphore)
227{
228 DWORD waitResult;
229
230 dprintf(("%ld: down_sema(%lx) called\n", get_thread_ident(), (long)aSemaphore));
231
232 waitResult = WaitForSingleObject( (HANDLE) aSemaphore, INFINITE);
233
234 dprintf(("%ld: down_sema(%lx) return: %l\n", get_thread_ident(),(long) aSemaphore, waitResult));
235}
236
237void up_sema(type_sema aSemaphore)
238{
239 ReleaseSemaphore(
240 (HANDLE) aSemaphore, /* Handle of semaphore */
241 1, /* increment count by one */
242 NULL); /* not interested in previous count */
243
244 dprintf(("%ld: up_sema(%lx)\n", get_thread_ident(), (long)aSemaphore));
245}