blob: 11ceecd26713f35583e10e21482c4dad46c16e8b [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
Andrew MacIntyre63f0db62006-06-04 12:59:59 +0000247void
248PyThread_release_lock(PyThread_type_lock aLock)
Guido van Rossum62332931995-04-10 11:36:14 +0000249{
Andrew MacIntyre69049592002-12-04 12:27:06 +0000250#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000251 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000252#endif
253
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000254 dprintf(("%ld: PyThread_release_lock(%p) called\n",
255 PyThread_get_thread_ident(),
256 aLock));
Guido van Rossum62332931995-04-10 11:36:14 +0000257
Andrew MacIntyred9400542002-02-26 11:41:34 +0000258#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000259 if (aLock)
260 _fmutex_release((_fmutex *)aLock);
Andrew MacIntyred9400542002-02-26 11:41:34 +0000261#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000262 if (!lock->is_set) {
263 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
264 PyThread_get_thread_ident(),
265 aLock,
266 GetLastError()));
267 return;
268 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000269
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000270 if (DosEnterCritSec()) {
271 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
272 PyThread_get_thread_ident(),
273 aLock,
274 GetLastError()));
275 return;
276 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000277
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000278 lock->is_set = 0;
279 DosPostEventSem(lock->changed);
280
281 DosExitCritSec();
Andrew MacIntyred9400542002-02-26 11:41:34 +0000282#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000283}
Andrew MacIntyre6539d2d2006-06-04 12:31:09 +0000284
285/* minimum/maximum thread stack sizes supported */
286#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
287#define THREAD_MAX_STACKSIZE 0x2000000 /* 32MB */
288
289/* set the thread stack size.
290 * Return 1 if an exception is pending, 0 otherwise.
291 */
292static int
293_pythread_os2_set_stacksize(size_t size)
294{
295 /* set to default */
296 if (size == 0) {
297 _pythread_stacksize = 0;
298 return 0;
299 }
300
301 /* valid range? */
302 if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
303 _pythread_stacksize = size;
304 return 0;
305 }
306 else {
307 char warning[128];
308 snprintf(warning,
309 128,
310 "thread stack size of %#x bytes not supported on OS/2",
311 size);
312 return PyErr_Warn(PyExc_RuntimeWarning, warning);
313 }
314}
315
316#undef THREAD_SET_STACKSIZE
317#define THREAD_SET_STACKSIZE(x) _pythread_os2_set_stacksize(x)