blob: 91959a09510a3cc8155eecff4c998dc5e76a79f0 [file] [log] [blame]
Guido van Rossum62332931995-04-10 11:36:14 +00001/* This code implemented by cvale@netcom.com */
2
3#define INCL_DOSPROCESS
4#define INCL_DOSSEMAPHORES
5#include "os2.h"
6#include "limits.h"
7
8#include "process.h"
9
Andrew MacIntyred9400542002-02-26 11:41:34 +000010#if defined(PYCC_GCC)
11#include <sys/builtin.h>
12#include <sys/fmutex.h>
13#else
Guido van Rossum65d5b571998-12-21 19:32:43 +000014long PyThread_get_thread_ident(void);
Andrew MacIntyred9400542002-02-26 11:41:34 +000015#endif
Guido van Rossum62332931995-04-10 11:36:14 +000016
Andrew MacIntyre6539d2d2006-06-04 12:31:09 +000017/* default thread stack size of 64kB */
Andrew MacIntyre2bea4742005-01-17 12:16:36 +000018#if !defined(THREAD_STACK_SIZE)
19#define THREAD_STACK_SIZE 0x10000
20#endif
21
Andrew MacIntyre6539d2d2006-06-04 12:31:09 +000022#define OS2_STACKSIZE(x) (x ? x : THREAD_STACK_SIZE)
23
Guido van Rossum62332931995-04-10 11:36:14 +000024/*
25 * Initialization of the C package, should not be needed.
26 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000027static void
28PyThread__init_thread(void)
Guido van Rossum62332931995-04-10 11:36:14 +000029{
30}
31
32/*
33 * Thread support.
34 */
Guido van Rossum3c288632001-10-16 21:13:49 +000035long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000036PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum62332931995-04-10 11:36:14 +000037{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000038 int aThread;
39 int success = 0;
Guido van Rossum62332931995-04-10 11:36:14 +000040
Andrew MacIntyre6539d2d2006-06-04 12:31:09 +000041 aThread = _beginthread(func,
42 NULL,
43 OS2_STACKSIZE(_pythread_stacksize),
44 arg);
Guido van Rossum62332931995-04-10 11:36:14 +000045
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000046 if (aThread == -1) {
47 success = -1;
48 fprintf(stderr, "aThread failed == %d", aThread);
49 dprintf(("_beginthread failed. return %ld\n", errno));
50 }
Guido van Rossum62332931995-04-10 11:36:14 +000051
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000052 return success;
Guido van Rossum62332931995-04-10 11:36:14 +000053}
54
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000055long
56PyThread_get_thread_ident(void)
Guido van Rossum62332931995-04-10 11:36:14 +000057{
Andrew MacIntyred9400542002-02-26 11:41:34 +000058#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000059 PPIB pib;
60 PTIB tib;
Andrew MacIntyred9400542002-02-26 11:41:34 +000061#endif
Guido van Rossum62332931995-04-10 11:36:14 +000062
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000063 if (!initialized)
64 PyThread_init_thread();
65
Andrew MacIntyred9400542002-02-26 11:41:34 +000066#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000067 return _gettid();
Andrew MacIntyred9400542002-02-26 11:41:34 +000068#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000069 DosGetInfoBlocks(&tib, &pib);
70 return tib->tib_ptib2->tib2_ultid;
Andrew MacIntyred9400542002-02-26 11:41:34 +000071#endif
Guido van Rossum62332931995-04-10 11:36:14 +000072}
73
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000074static void
75do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum62332931995-04-10 11:36:14 +000076{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000077 dprintf(("%ld: PyThread_exit_thread called\n",
78 PyThread_get_thread_ident()));
79 if (!initialized)
80 if (no_cleanup)
81 _exit(0);
82 else
83 exit(0);
84 _endthread();
Guido van Rossum62332931995-04-10 11:36:14 +000085}
86
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000087void
88PyThread_exit_thread(void)
Guido van Rossum62332931995-04-10 11:36:14 +000089{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000090 do_PyThread_exit_thread(0);
Guido van Rossum62332931995-04-10 11:36:14 +000091}
92
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000093void
94PyThread__exit_thread(void)
Guido van Rossum62332931995-04-10 11:36:14 +000095{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000096 do_PyThread_exit_thread(1);
Guido van Rossum62332931995-04-10 11:36:14 +000097}
98
99#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000100static void
101do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum62332931995-04-10 11:36:14 +0000102{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000103 dprintf(("PyThread_exit_prog(%d) called\n", status));
104 if (!initialized)
105 if (no_cleanup)
106 _exit(status);
107 else
108 exit(status);
Guido van Rossum62332931995-04-10 11:36:14 +0000109}
110
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000111void
112PyThread_exit_prog(int status)
Guido van Rossum62332931995-04-10 11:36:14 +0000113{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000114 do_PyThread_exit_prog(status, 0);
Guido van Rossum62332931995-04-10 11:36:14 +0000115}
116
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000117void
118PyThread__exit_prog(int status)
Guido van Rossum62332931995-04-10 11:36:14 +0000119{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000120 do_PyThread_exit_prog(status, 1);
Guido van Rossum62332931995-04-10 11:36:14 +0000121}
122#endif /* NO_EXIT_PROG */
123
124/*
Tim Petersa6ca4f42001-10-31 03:50:45 +0000125 * Lock support. This is implemented with an event semaphore and critical
126 * sections to make it behave more like a posix mutex than its OS/2
Andrew MacIntyred9400542002-02-26 11:41:34 +0000127 * counterparts.
Guido van Rossum62332931995-04-10 11:36:14 +0000128 */
Tim Petersa6ca4f42001-10-31 03:50:45 +0000129
130typedef struct os2_lock_t {
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000131 int is_set;
132 HEV changed;
Tim Petersa6ca4f42001-10-31 03:50:45 +0000133} *type_os2_lock;
134
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000135PyThread_type_lock
136PyThread_allocate_lock(void)
Guido van Rossum62332931995-04-10 11:36:14 +0000137{
Andrew MacIntyred9400542002-02-26 11:41:34 +0000138#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000139 _fmutex *sem = malloc(sizeof(_fmutex));
140 if (!initialized)
141 PyThread_init_thread();
142 dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
143 PyThread_get_thread_ident(),
144 (long)sem));
145 if (_fmutex_create(sem, 0)) {
146 free(sem);
147 sem = NULL;
148 }
149 return (PyThread_type_lock)sem;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000150#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000151 APIRET rc;
152 type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
Guido van Rossum62332931995-04-10 11:36:14 +0000153
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000154 dprintf(("PyThread_allocate_lock called\n"));
155 if (!initialized)
156 PyThread_init_thread();
Guido van Rossum62332931995-04-10 11:36:14 +0000157
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000158 lock->is_set = 0;
Guido van Rossum62332931995-04-10 11:36:14 +0000159
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000160 DosCreateEventSem(NULL, &lock->changed, 0, 0);
Guido van Rossum62332931995-04-10 11:36:14 +0000161
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000162 dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
163 PyThread_get_thread_ident(),
164 lock->changed));
Tim Petersa6ca4f42001-10-31 03:50:45 +0000165
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000166 return (PyThread_type_lock)lock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000167#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000168}
169
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000170void
171PyThread_free_lock(PyThread_type_lock aLock)
Guido van Rossum62332931995-04-10 11:36:14 +0000172{
Andrew MacIntyred9400542002-02-26 11:41:34 +0000173#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000174 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000175#endif
176
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000177 dprintf(("%ld: PyThread_free_lock(%p) called\n",
178 PyThread_get_thread_ident(),aLock));
Guido van Rossum62332931995-04-10 11:36:14 +0000179
Andrew MacIntyred9400542002-02-26 11:41:34 +0000180#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000181 if (aLock) {
182 _fmutex_close((_fmutex *)aLock);
183 free((_fmutex *)aLock);
184 }
Andrew MacIntyred9400542002-02-26 11:41:34 +0000185#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000186 DosCloseEventSem(lock->changed);
187 free(aLock);
Andrew MacIntyred9400542002-02-26 11:41:34 +0000188#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000189}
190
191/*
192 * Return 1 on success if the lock was acquired
193 *
Tim Petersa6ca4f42001-10-31 03:50:45 +0000194 * and 0 if the lock was not acquired.
Guido van Rossum62332931995-04-10 11:36:14 +0000195 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000196int
197PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
Guido van Rossum62332931995-04-10 11:36:14 +0000198{
Andrew MacIntyred9400542002-02-26 11:41:34 +0000199#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000200 int done = 0;
201 ULONG count;
202 PID pid = 0;
203 TID tid = 0;
204 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000205#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000206
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000207 dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
208 PyThread_get_thread_ident(),
209 aLock,
210 waitflag));
Guido van Rossum62332931995-04-10 11:36:14 +0000211
Andrew MacIntyred9400542002-02-26 11:41:34 +0000212#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000213 /* always successful if the lock doesn't exist */
214 if (aLock &&
215 _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
216 return 0;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000217#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000218 while (!done) {
219 /* if the lock is currently set, we have to wait for
220 * the state to change
221 */
222 if (lock->is_set) {
223 if (!waitflag)
224 return 0;
225 DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
226 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000227
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000228 /* enter a critical section and try to get the semaphore. If
229 * it is still locked, we will try again.
230 */
231 if (DosEnterCritSec())
232 return 0;
Tim Petersa6ca4f42001-10-31 03:50:45 +0000233
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000234 if (!lock->is_set) {
235 lock->is_set = 1;
236 DosResetEventSem(lock->changed, &count);
237 done = 1;
238 }
239
240 DosExitCritSec();
241 }
Andrew MacIntyred9400542002-02-26 11:41:34 +0000242#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000243
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000244 return 1;
Guido van Rossum62332931995-04-10 11:36:14 +0000245}
246
Tim Petersa6ca4f42001-10-31 03:50:45 +0000247void PyThread_release_lock(PyThread_type_lock aLock)
Guido van Rossum62332931995-04-10 11:36:14 +0000248{
Andrew MacIntyre69049592002-12-04 12:27:06 +0000249#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000250 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000251#endif
252
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000253 dprintf(("%ld: PyThread_release_lock(%p) called\n",
254 PyThread_get_thread_ident(),
255 aLock));
Guido van Rossum62332931995-04-10 11:36:14 +0000256
Andrew MacIntyred9400542002-02-26 11:41:34 +0000257#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000258 if (aLock)
259 _fmutex_release((_fmutex *)aLock);
Andrew MacIntyred9400542002-02-26 11:41:34 +0000260#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000261 if (!lock->is_set) {
262 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
263 PyThread_get_thread_ident(),
264 aLock,
265 GetLastError()));
266 return;
267 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000268
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000269 if (DosEnterCritSec()) {
270 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
271 PyThread_get_thread_ident(),
272 aLock,
273 GetLastError()));
274 return;
275 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000276
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000277 lock->is_set = 0;
278 DosPostEventSem(lock->changed);
279
280 DosExitCritSec();
Andrew MacIntyred9400542002-02-26 11:41:34 +0000281#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000282}
Andrew MacIntyre6539d2d2006-06-04 12:31:09 +0000283
284/* minimum/maximum thread stack sizes supported */
285#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
286#define THREAD_MAX_STACKSIZE 0x2000000 /* 32MB */
287
288/* set the thread stack size.
289 * Return 1 if an exception is pending, 0 otherwise.
290 */
291static int
292_pythread_os2_set_stacksize(size_t size)
293{
294 /* set to default */
295 if (size == 0) {
296 _pythread_stacksize = 0;
297 return 0;
298 }
299
300 /* valid range? */
301 if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
302 _pythread_stacksize = size;
303 return 0;
304 }
305 else {
306 char warning[128];
307 snprintf(warning,
308 128,
309 "thread stack size of %#x bytes not supported on OS/2",
310 size);
311 return PyErr_Warn(PyExc_RuntimeWarning, warning);
312 }
313}
314
315#undef THREAD_SET_STACKSIZE
316#define THREAD_SET_STACKSIZE(x) _pythread_os2_set_stacksize(x)