History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Python/thread_os2.h (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Python/thread_os2.h+307−0
@@ -0,0 +1,307 @@
1+/* 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+
10+#if defined(PYCC_GCC)
11+#include <sys/builtin.h>
12+#include <sys/fmutex.h>
13+#else
14+long PyThread_get_thread_ident(void);
15+#endif
16+
17+/* default thread stack size of 64kB */
18+#if !defined(THREAD_STACK_SIZE)
19+#define THREAD_STACK_SIZE 0x10000
20+#endif
21+
22+#define OS2_STACKSIZE(x) (x ? x : THREAD_STACK_SIZE)
23+
24+/*
25+ * Initialization of the C package, should not be needed.
26+ */
27+static void
28+PyThread__init_thread(void)
29+{
30+}
31+
32+/*
33+ * Thread support.
34+ */
35+long
36+PyThread_start_new_thread(void (*func)(void *), void *arg)
37+{
38+ int thread_id;
39+
40+ thread_id = _beginthread(func,
41+ NULL,
42+ OS2_STACKSIZE(_pythread_stacksize),
43+ arg);
44+
45+ if (thread_id == -1) {
46+ dprintf(("_beginthread failed. return %ld\n", errno));
47+ }
48+
49+ return thread_id;
50+}
51+
52+long
53+PyThread_get_thread_ident(void)
54+{
55+#if !defined(PYCC_GCC)
56+ PPIB pib;
57+ PTIB tib;
58+#endif
59+
60+ if (!initialized)
61+ PyThread_init_thread();
62+
63+#if defined(PYCC_GCC)
64+ return _gettid();
65+#else
66+ DosGetInfoBlocks(&tib, &pib);
67+ return tib->tib_ptib2->tib2_ultid;
68+#endif
69+}
70+
71+static void
72+do_PyThread_exit_thread(int no_cleanup)
73+{
74+ dprintf(("%ld: PyThread_exit_thread called\n",
75+ PyThread_get_thread_ident()));
76+ if (!initialized)
77+ if (no_cleanup)
78+ _exit(0);
79+ else
80+ exit(0);
81+ _endthread();
82+}
83+
84+void
85+PyThread_exit_thread(void)
86+{
87+ do_PyThread_exit_thread(0);
88+}
89+
90+void
91+PyThread__exit_thread(void)
92+{
93+ do_PyThread_exit_thread(1);
94+}
95+
96+#ifndef NO_EXIT_PROG
97+static void
98+do_PyThread_exit_prog(int status, int no_cleanup)
99+{
100+ dprintf(("PyThread_exit_prog(%d) called\n", status));
101+ if (!initialized)
102+ if (no_cleanup)
103+ _exit(status);
104+ else
105+ exit(status);
106+}
107+
108+void
109+PyThread_exit_prog(int status)
110+{
111+ do_PyThread_exit_prog(status, 0);
112+}
113+
114+void
115+PyThread__exit_prog(int status)
116+{
117+ do_PyThread_exit_prog(status, 1);
118+}
119+#endif /* NO_EXIT_PROG */
120+
121+/*
122+ * Lock support. This is implemented with an event semaphore and critical
123+ * sections to make it behave more like a posix mutex than its OS/2
124+ * counterparts.
125+ */
126+
127+typedef struct os2_lock_t {
128+ int is_set;
129+ HEV changed;
130+} *type_os2_lock;
131+
132+PyThread_type_lock
133+PyThread_allocate_lock(void)
134+{
135+#if defined(PYCC_GCC)
136+ _fmutex *sem = malloc(sizeof(_fmutex));
137+ if (!initialized)
138+ PyThread_init_thread();
139+ dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
140+ PyThread_get_thread_ident(),
141+ (long)sem));
142+ if (_fmutex_create(sem, 0)) {
143+ free(sem);
144+ sem = NULL;
145+ }
146+ return (PyThread_type_lock)sem;
147+#else
148+ APIRET rc;
149+ type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
150+
151+ dprintf(("PyThread_allocate_lock called\n"));
152+ if (!initialized)
153+ PyThread_init_thread();
154+
155+ lock->is_set = 0;
156+
157+ DosCreateEventSem(NULL, &lock->changed, 0, 0);
158+
159+ dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
160+ PyThread_get_thread_ident(),
161+ lock->changed));
162+
163+ return (PyThread_type_lock)lock;
164+#endif
165+}
166+
167+void
168+PyThread_free_lock(PyThread_type_lock aLock)
169+{
170+#if !defined(PYCC_GCC)
171+ type_os2_lock lock = (type_os2_lock)aLock;
172+#endif
173+
174+ dprintf(("%ld: PyThread_free_lock(%p) called\n",
175+ PyThread_get_thread_ident(),aLock));
176+
177+#if defined(PYCC_GCC)
178+ if (aLock) {
179+ _fmutex_close((_fmutex *)aLock);
180+ free((_fmutex *)aLock);
181+ }
182+#else
183+ DosCloseEventSem(lock->changed);
184+ free(aLock);
185+#endif
186+}
187+
188+/*
189+ * Return 1 on success if the lock was acquired
190+ *
191+ * and 0 if the lock was not acquired.
192+ */
193+int
194+PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
195+{
196+#if !defined(PYCC_GCC)
197+ int done = 0;
198+ ULONG count;
199+ PID pid = 0;
200+ TID tid = 0;
201+ type_os2_lock lock = (type_os2_lock)aLock;
202+#endif
203+
204+ dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
205+ PyThread_get_thread_ident(),
206+ aLock,
207+ waitflag));
208+
209+#if defined(PYCC_GCC)
210+ /* always successful if the lock doesn't exist */
211+ if (aLock &&
212+ _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
213+ return 0;
214+#else
215+ while (!done) {
216+ /* if the lock is currently set, we have to wait for
217+ * the state to change
218+ */
219+ if (lock->is_set) {
220+ if (!waitflag)
221+ return 0;
222+ DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
223+ }
224+
225+ /* enter a critical section and try to get the semaphore. If
226+ * it is still locked, we will try again.
227+ */
228+ if (DosEnterCritSec())
229+ return 0;
230+
231+ if (!lock->is_set) {
232+ lock->is_set = 1;
233+ DosResetEventSem(lock->changed, &count);
234+ done = 1;
235+ }
236+
237+ DosExitCritSec();
238+ }
239+#endif
240+
241+ return 1;
242+}
243+
244+void
245+PyThread_release_lock(PyThread_type_lock aLock)
246+{
247+#if !defined(PYCC_GCC)
248+ type_os2_lock lock = (type_os2_lock)aLock;
249+#endif
250+
251+ dprintf(("%ld: PyThread_release_lock(%p) called\n",
252+ PyThread_get_thread_ident(),
253+ aLock));
254+
255+#if defined(PYCC_GCC)
256+ if (aLock)
257+ _fmutex_release((_fmutex *)aLock);
258+#else
259+ if (!lock->is_set) {
260+ dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
261+ PyThread_get_thread_ident(),
262+ aLock,
263+ GetLastError()));
264+ return;
265+ }
266+
267+ if (DosEnterCritSec()) {
268+ dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
269+ PyThread_get_thread_ident(),
270+ aLock,
271+ GetLastError()));
272+ return;
273+ }
274+
275+ lock->is_set = 0;
276+ DosPostEventSem(lock->changed);
277+
278+ DosExitCritSec();
279+#endif
280+}
281+
282+/* minimum/maximum thread stack sizes supported */
283+#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
284+#define THREAD_MAX_STACKSIZE 0x2000000 /* 32MB */
285+
286+/* set the thread stack size.
287+ * Return 0 if size is valid, -1 otherwise.
288+ */
289+static int
290+_pythread_os2_set_stacksize(size_t size)
291+{
292+ /* set to default */
293+ if (size == 0) {
294+ _pythread_stacksize = 0;
295+ return 0;
296+ }
297+
298+ /* valid range? */
299+ if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
300+ _pythread_stacksize = size;
301+ return 0;
302+ }
303+
304+ return -1;
305+}
306+
307+#define THREAD_SET_STACKSIZE(x) _pythread_os2_set_stacksize(x)