blob: eeefe03760029a12a591ae9947d7bd02eef6835f [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
17/*
18 * Initialization of the C package, should not be needed.
19 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000020static void
21PyThread__init_thread(void)
Guido van Rossum62332931995-04-10 11:36:14 +000022{
23}
24
25/*
26 * Thread support.
27 */
Guido van Rossum3c288632001-10-16 21:13:49 +000028long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000029PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum62332931995-04-10 11:36:14 +000030{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000031 int aThread;
32 int success = 0;
Guido van Rossum62332931995-04-10 11:36:14 +000033
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000034 aThread = _beginthread(func,NULL,65536,arg);
Guido van Rossum62332931995-04-10 11:36:14 +000035
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000036 if (aThread == -1) {
37 success = -1;
38 fprintf(stderr, "aThread failed == %d", aThread);
39 dprintf(("_beginthread failed. return %ld\n", errno));
40 }
Guido van Rossum62332931995-04-10 11:36:14 +000041
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000042 return success;
Guido van Rossum62332931995-04-10 11:36:14 +000043}
44
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000045long
46PyThread_get_thread_ident(void)
Guido van Rossum62332931995-04-10 11:36:14 +000047{
Andrew MacIntyred9400542002-02-26 11:41:34 +000048#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000049 PPIB pib;
50 PTIB tib;
Andrew MacIntyred9400542002-02-26 11:41:34 +000051#endif
Guido van Rossum62332931995-04-10 11:36:14 +000052
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000053 if (!initialized)
54 PyThread_init_thread();
55
Andrew MacIntyred9400542002-02-26 11:41:34 +000056#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000057 return _gettid();
Andrew MacIntyred9400542002-02-26 11:41:34 +000058#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000059 DosGetInfoBlocks(&tib, &pib);
60 return tib->tib_ptib2->tib2_ultid;
Andrew MacIntyred9400542002-02-26 11:41:34 +000061#endif
Guido van Rossum62332931995-04-10 11:36:14 +000062}
63
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000064static void
65do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum62332931995-04-10 11:36:14 +000066{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000067 dprintf(("%ld: PyThread_exit_thread called\n",
68 PyThread_get_thread_ident()));
69 if (!initialized)
70 if (no_cleanup)
71 _exit(0);
72 else
73 exit(0);
74 _endthread();
Guido van Rossum62332931995-04-10 11:36:14 +000075}
76
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000077void
78PyThread_exit_thread(void)
Guido van Rossum62332931995-04-10 11:36:14 +000079{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000080 do_PyThread_exit_thread(0);
Guido van Rossum62332931995-04-10 11:36:14 +000081}
82
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000083void
84PyThread__exit_thread(void)
Guido van Rossum62332931995-04-10 11:36:14 +000085{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000086 do_PyThread_exit_thread(1);
Guido van Rossum62332931995-04-10 11:36:14 +000087}
88
89#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000090static void
91do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum62332931995-04-10 11:36:14 +000092{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +000093 dprintf(("PyThread_exit_prog(%d) called\n", status));
94 if (!initialized)
95 if (no_cleanup)
96 _exit(status);
97 else
98 exit(status);
Guido van Rossum62332931995-04-10 11:36:14 +000099}
100
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000101void
102PyThread_exit_prog(int status)
Guido van Rossum62332931995-04-10 11:36:14 +0000103{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000104 do_PyThread_exit_prog(status, 0);
Guido van Rossum62332931995-04-10 11:36:14 +0000105}
106
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000107void
108PyThread__exit_prog(int status)
Guido van Rossum62332931995-04-10 11:36:14 +0000109{
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000110 do_PyThread_exit_prog(status, 1);
Guido van Rossum62332931995-04-10 11:36:14 +0000111}
112#endif /* NO_EXIT_PROG */
113
114/*
Tim Petersa6ca4f42001-10-31 03:50:45 +0000115 * Lock support. This is implemented with an event semaphore and critical
116 * sections to make it behave more like a posix mutex than its OS/2
Andrew MacIntyred9400542002-02-26 11:41:34 +0000117 * counterparts.
Guido van Rossum62332931995-04-10 11:36:14 +0000118 */
Tim Petersa6ca4f42001-10-31 03:50:45 +0000119
120typedef struct os2_lock_t {
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000121 int is_set;
122 HEV changed;
Tim Petersa6ca4f42001-10-31 03:50:45 +0000123} *type_os2_lock;
124
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000125PyThread_type_lock
126PyThread_allocate_lock(void)
Guido van Rossum62332931995-04-10 11:36:14 +0000127{
Andrew MacIntyred9400542002-02-26 11:41:34 +0000128#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000129 _fmutex *sem = malloc(sizeof(_fmutex));
130 if (!initialized)
131 PyThread_init_thread();
132 dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
133 PyThread_get_thread_ident(),
134 (long)sem));
135 if (_fmutex_create(sem, 0)) {
136 free(sem);
137 sem = NULL;
138 }
139 return (PyThread_type_lock)sem;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000140#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000141 APIRET rc;
142 type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
Guido van Rossum62332931995-04-10 11:36:14 +0000143
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000144 dprintf(("PyThread_allocate_lock called\n"));
145 if (!initialized)
146 PyThread_init_thread();
Guido van Rossum62332931995-04-10 11:36:14 +0000147
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000148 lock->is_set = 0;
Guido van Rossum62332931995-04-10 11:36:14 +0000149
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000150 DosCreateEventSem(NULL, &lock->changed, 0, 0);
Guido van Rossum62332931995-04-10 11:36:14 +0000151
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000152 dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
153 PyThread_get_thread_ident(),
154 lock->changed));
Tim Petersa6ca4f42001-10-31 03:50:45 +0000155
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000156 return (PyThread_type_lock)lock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000157#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000158}
159
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000160void
161PyThread_free_lock(PyThread_type_lock aLock)
Guido van Rossum62332931995-04-10 11:36:14 +0000162{
Andrew MacIntyred9400542002-02-26 11:41:34 +0000163#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000164 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000165#endif
166
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000167 dprintf(("%ld: PyThread_free_lock(%p) called\n",
168 PyThread_get_thread_ident(),aLock));
Guido van Rossum62332931995-04-10 11:36:14 +0000169
Andrew MacIntyred9400542002-02-26 11:41:34 +0000170#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000171 if (aLock) {
172 _fmutex_close((_fmutex *)aLock);
173 free((_fmutex *)aLock);
174 }
Andrew MacIntyred9400542002-02-26 11:41:34 +0000175#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000176 DosCloseEventSem(lock->changed);
177 free(aLock);
Andrew MacIntyred9400542002-02-26 11:41:34 +0000178#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000179}
180
181/*
182 * Return 1 on success if the lock was acquired
183 *
Tim Petersa6ca4f42001-10-31 03:50:45 +0000184 * and 0 if the lock was not acquired.
Guido van Rossum62332931995-04-10 11:36:14 +0000185 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000186int
187PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
Guido van Rossum62332931995-04-10 11:36:14 +0000188{
Andrew MacIntyred9400542002-02-26 11:41:34 +0000189#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000190 int done = 0;
191 ULONG count;
192 PID pid = 0;
193 TID tid = 0;
194 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000195#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000196
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000197 dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
198 PyThread_get_thread_ident(),
199 aLock,
200 waitflag));
Guido van Rossum62332931995-04-10 11:36:14 +0000201
Andrew MacIntyred9400542002-02-26 11:41:34 +0000202#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000203 /* always successful if the lock doesn't exist */
204 if (aLock &&
205 _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
206 return 0;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000207#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000208 while (!done) {
209 /* if the lock is currently set, we have to wait for
210 * the state to change
211 */
212 if (lock->is_set) {
213 if (!waitflag)
214 return 0;
215 DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
216 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000217
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000218 /* enter a critical section and try to get the semaphore. If
219 * it is still locked, we will try again.
220 */
221 if (DosEnterCritSec())
222 return 0;
Tim Petersa6ca4f42001-10-31 03:50:45 +0000223
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000224 if (!lock->is_set) {
225 lock->is_set = 1;
226 DosResetEventSem(lock->changed, &count);
227 done = 1;
228 }
229
230 DosExitCritSec();
231 }
Andrew MacIntyred9400542002-02-26 11:41:34 +0000232#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000233
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000234 return 1;
Guido van Rossum62332931995-04-10 11:36:14 +0000235}
236
Tim Petersa6ca4f42001-10-31 03:50:45 +0000237void PyThread_release_lock(PyThread_type_lock aLock)
Guido van Rossum62332931995-04-10 11:36:14 +0000238{
Andrew MacIntyre69049592002-12-04 12:27:06 +0000239#if !defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000240 type_os2_lock lock = (type_os2_lock)aLock;
Andrew MacIntyred9400542002-02-26 11:41:34 +0000241#endif
242
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000243 dprintf(("%ld: PyThread_release_lock(%p) called\n",
244 PyThread_get_thread_ident(),
245 aLock));
Guido van Rossum62332931995-04-10 11:36:14 +0000246
Andrew MacIntyred9400542002-02-26 11:41:34 +0000247#if defined(PYCC_GCC)
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000248 if (aLock)
249 _fmutex_release((_fmutex *)aLock);
Andrew MacIntyred9400542002-02-26 11:41:34 +0000250#else
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000251 if (!lock->is_set) {
252 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
253 PyThread_get_thread_ident(),
254 aLock,
255 GetLastError()));
256 return;
257 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000258
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000259 if (DosEnterCritSec()) {
260 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
261 PyThread_get_thread_ident(),
262 aLock,
263 GetLastError()));
264 return;
265 }
Tim Petersa6ca4f42001-10-31 03:50:45 +0000266
Andrew MacIntyrec4c127b2002-12-04 12:29:37 +0000267 lock->is_set = 0;
268 DosPostEventSem(lock->changed);
269
270 DosExitCritSec();
Andrew MacIntyred9400542002-02-26 11:41:34 +0000271#endif
Guido van Rossum62332931995-04-10 11:36:14 +0000272}