blob: 64100f4f4fa76360b8ef9502404a49b8442f8dc0 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000029
30******************************************************************/
31
Guido van Rossum66020991996-06-11 18:32:18 +000032/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000033
Guido van Rossum66020991996-06-11 18:32:18 +000034#include <stdlib.h>
35#include <pthread.h>
36
Guido van Rossum1a623111996-08-08 18:53:41 +000037
Guido van Rossumd6353e21997-05-13 17:51:13 +000038/* try to determine what version of the Pthread Standard is installed.
39 * this is important, since all sorts of parameter types changed from
40 * draft to draft and there are several (incompatible) drafts in
41 * common use. these macros are a start, at least.
42 * 12 May 1997 -- david arnold <davida@pobox.com>
43 */
44
45#if defined(__ultrix) && defined(__mips) && defined(_DECTHREADS_)
46/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
47# define PY_PTHREAD_D4
48
49#elif defined(__osf__) && defined (__alpha)
50/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
51# if !defined(_PTHREAD_ENV_ALPHA) || defined(_PTHREAD_USE_D4) || defined(PTHREAD_USE_D4)
52# define PY_PTHREAD_D4
53# else
54# define PY_PTHREAD_STD
55# endif
56
57#elif defined(_AIX)
Guido van Rossum1a623111996-08-08 18:53:41 +000058/* SCHED_BG_NP is defined if using AIX DCE pthreads
59 * but it is unsupported by AIX 4 pthreads. Default
60 * attributes for AIX 4 pthreads equal to NULL. For
61 * AIX DCE pthreads they should be left unchanged.
62 */
Guido van Rossumd6353e21997-05-13 17:51:13 +000063# if !defined(SCHED_BG_NP)
64# define PY_PTHREAD_STD
65# else
66# define PY_PTHREAD_D7
67# endif
68
Guido van Rossum64f91051997-05-22 20:41:59 +000069#elif defined(__DGUX)
70# define PY_PTHREAD_D6
Guido van Rossum46ff1901997-06-02 22:25:45 +000071
Guido van Rossum532246e1998-05-14 21:01:27 +000072#elif defined(__hpux) && defined(_DECTHREADS_)
Guido van Rossum89df70b1998-05-07 13:28:23 +000073# define PY_PTHREAD_D4
74
Guido van Rossum46ff1901997-06-02 22:25:45 +000075#else /* Default case */
76# define PY_PTHREAD_STD
77
Guido van Rossum1a623111996-08-08 18:53:41 +000078#endif
79
Guido van Rossumd6353e21997-05-13 17:51:13 +000080
81/* set default attribute object for different versions */
82
83#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D7)
84# define pthread_attr_default pthread_attr_default
85# define pthread_mutexattr_default pthread_mutexattr_default
86# define pthread_condattr_default pthread_condattr_default
Guido van Rossum64f91051997-05-22 20:41:59 +000087#elif defined(PY_PTHREAD_STD) || defined(PY_PTHREAD_D6)
Guido van Rossumd6353e21997-05-13 17:51:13 +000088# define pthread_attr_default ((pthread_attr_t *)NULL)
89# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
90# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000091#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000092
Guido van Rossumd6353e21997-05-13 17:51:13 +000093
Guido van Rossumb98b1b31994-05-11 08:42:04 +000094/* A pthread mutex isn't sufficient to model the Python lock type
95 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
96 * following are undefined:
97 * -> a thread tries to lock a mutex it already has locked
98 * -> a thread tries to unlock a mutex locked by a different thread
99 * pthread mutexes are designed for serializing threads over short pieces
100 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000101 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000102 *
103 * The pthread_lock struct implements a Python lock as a "locked?" bit
104 * and a <condition, mutex> pair. In general, if the bit can be acquired
105 * instantly, it is, else the pair is used to block the thread until the
106 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000107 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000108
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000109typedef struct {
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000110 char locked; /* 0=unlocked, 1=locked */
111 /* a <cond, mutex> pair to handle an acquire of a locked lock */
112 pthread_cond_t lock_released;
113 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000114} pthread_lock;
115
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000116#define CHECK_STATUS(name) if (status < 0) { perror(name); error=1; }
117
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000118/*
119 * Initialization.
120 */
121static void _init_thread _P0()
122{
123}
124
125/*
126 * Thread support.
127 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000128
129
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000130int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
131{
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000132 pthread_t th;
Guido van Rossume944da81994-05-23 12:43:41 +0000133 int success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000134 dprintf(("start_new_thread called\n"));
135 if (!initialized)
136 init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000137
138 success = pthread_create(&th,
139#if defined(PY_PTHREAD_D4)
140 pthread_attr_default,
141 (pthread_startroutine_t)func,
142 (pthread_addr_t)arg
Guido van Rossum64f91051997-05-22 20:41:59 +0000143#elif defined(PY_PTHREAD_D6)
144 pthread_attr_default,
145 (void* (*)_P((void *)))func,
146 arg
Guido van Rossumd6353e21997-05-13 17:51:13 +0000147#elif defined(PY_PTHREAD_D7)
148 pthread_attr_default,
149 func,
150 arg
151#elif defined(PY_PTHREAD_STD)
152 (pthread_attr_t*)NULL,
153 (void* (*)_P((void *)))func,
154 (void *)arg
155#endif
156 );
157
158 if (success >= 0) {
Guido van Rossum64f91051997-05-22 20:41:59 +0000159#if defined(PY_THREAD_D4) || defined(PY_PTHREAD_D6) || defined(PY_PTHREAD_D7)
Guido van Rossumd6353e21997-05-13 17:51:13 +0000160 pthread_detach(&th);
161#elif defined(PY_PTHREAD_STD)
Guido van Rossumf4806c21997-04-30 19:59:22 +0000162 pthread_detach(th);
Guido van Rossumd6353e21997-05-13 17:51:13 +0000163#endif
164 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000165 return success < 0 ? 0 : 1;
166}
167
Guido van Rossume944da81994-05-23 12:43:41 +0000168long get_thread_ident _P0()
169{
Guido van Rossum44ee4791998-08-27 19:21:53 +0000170 volatile pthread_t threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000171 if (!initialized)
172 init_thread();
Guido van Rossum2565bff1995-01-09 17:50:47 +0000173 /* Jump through some hoops for Alpha OSF/1 */
174 threadid = pthread_self();
175 return (long) *(long *) &threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000176}
177
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000178static void do_exit_thread _P1(no_cleanup, int no_cleanup)
179{
180 dprintf(("exit_thread called\n"));
Guido van Rossum730806d1998-04-10 22:27:42 +0000181 if (!initialized) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000182 if (no_cleanup)
183 _exit(0);
184 else
185 exit(0);
Guido van Rossum730806d1998-04-10 22:27:42 +0000186 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000187}
188
189void exit_thread _P0()
190{
191 do_exit_thread(0);
192}
193
194void _exit_thread _P0()
195{
196 do_exit_thread(1);
197}
198
199#ifndef NO_EXIT_PROG
200static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
201{
202 dprintf(("exit_prog(%d) called\n", status));
203 if (!initialized)
204 if (no_cleanup)
205 _exit(status);
206 else
207 exit(status);
208}
209
210void exit_prog _P1(status, int status)
211{
212 do_exit_prog(status, 0);
213}
214
215void _exit_prog _P1(status, int status)
216{
217 do_exit_prog(status, 1);
218}
219#endif /* NO_EXIT_PROG */
220
221/*
222 * Lock support.
223 */
224type_lock allocate_lock _P0()
225{
226 pthread_lock *lock;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000227 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000228
229 dprintf(("allocate_lock called\n"));
230 if (!initialized)
231 init_thread();
232
233 lock = (pthread_lock *) malloc(sizeof(pthread_lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000234 if (lock) {
235 lock->locked = 0;
236
237 status = pthread_mutex_init(&lock->mut,
238 pthread_mutexattr_default);
239 CHECK_STATUS("pthread_mutex_init");
240
241 status = pthread_cond_init(&lock->lock_released,
242 pthread_condattr_default);
243 CHECK_STATUS("pthread_cond_init");
244
245 if (error) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000246 free((void *)lock);
247 lock = 0;
248 }
249 }
250
251 dprintf(("allocate_lock() -> %lx\n", (long)lock));
252 return (type_lock) lock;
253}
254
255void free_lock _P1(lock, type_lock lock)
256{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000257 pthread_lock *thelock = (pthread_lock *)lock;
258 int status, error = 0;
259
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000260 dprintf(("free_lock(%lx) called\n", (long)lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000261
262 status = pthread_mutex_destroy( &thelock->mut );
263 CHECK_STATUS("pthread_mutex_destroy");
264
265 status = pthread_cond_destroy( &thelock->lock_released );
266 CHECK_STATUS("pthread_cond_destroy");
267
268 free((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000269}
270
271int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
272{
273 int success;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000274 pthread_lock *thelock = (pthread_lock *)lock;
275 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000276
277 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000278
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000279 status = pthread_mutex_lock( &thelock->mut );
280 CHECK_STATUS("pthread_mutex_lock[1]");
281 success = thelock->locked == 0;
282 if (success) thelock->locked = 1;
283 status = pthread_mutex_unlock( &thelock->mut );
284 CHECK_STATUS("pthread_mutex_unlock[1]");
285
286 if ( !success && waitflag ) {
287 /* continue trying until we get the lock */
288
289 /* mut must be locked by me -- part of the condition
290 * protocol */
291 status = pthread_mutex_lock( &thelock->mut );
292 CHECK_STATUS("pthread_mutex_lock[2]");
293 while ( thelock->locked ) {
294 status = pthread_cond_wait(&thelock->lock_released,
295 &thelock->mut);
296 CHECK_STATUS("pthread_cond_wait");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000297 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000298 thelock->locked = 1;
299 status = pthread_mutex_unlock( &thelock->mut );
300 CHECK_STATUS("pthread_mutex_unlock[2]");
301 success = 1;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000302 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000303 if (error) success = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000304 dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
305 return success;
306}
307
308void release_lock _P1(lock, type_lock lock)
309{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000310 pthread_lock *thelock = (pthread_lock *)lock;
311 int status, error = 0;
312
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000313 dprintf(("release_lock(%lx) called\n", (long)lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000314
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000315 status = pthread_mutex_lock( &thelock->mut );
316 CHECK_STATUS("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000317
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000318 thelock->locked = 0;
319
320 status = pthread_mutex_unlock( &thelock->mut );
321 CHECK_STATUS("pthread_mutex_unlock[3]");
322
323 /* wake up someone (anyone, if any) waiting on the lock */
324 status = pthread_cond_signal( &thelock->lock_released );
325 CHECK_STATUS("pthread_cond_signal");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000326}
327
328/*
329 * Semaphore support.
330 */
Guido van Rossum7af81301997-01-17 21:06:41 +0000331
332struct semaphore {
333 pthread_mutex_t mutex;
334 pthread_cond_t cond;
335 int value;
336};
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000337
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000338type_sema allocate_sema _P1(value, int value)
339{
Guido van Rossum7af81301997-01-17 21:06:41 +0000340 struct semaphore *sema;
341 int status, error = 0;
342
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000343 dprintf(("allocate_sema called\n"));
344 if (!initialized)
345 init_thread();
346
Guido van Rossum7af81301997-01-17 21:06:41 +0000347 sema = (struct semaphore *) malloc(sizeof(struct semaphore));
348 if (sema != NULL) {
349 sema->value = value;
350 status = pthread_mutex_init(&sema->mutex,
351 pthread_mutexattr_default);
352 CHECK_STATUS("pthread_mutex_init");
353 status = pthread_cond_init(&sema->cond,
354 pthread_condattr_default);
355 CHECK_STATUS("pthread_cond_init");
356 if (error) {
357 free((void *) sema);
358 sema = NULL;
359 }
360 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000361 dprintf(("allocate_sema() -> %lx\n", (long) sema));
362 return (type_sema) sema;
363}
364
365void free_sema _P1(sema, type_sema sema)
366{
Guido van Rossum7af81301997-01-17 21:06:41 +0000367 int status, error = 0;
368 struct semaphore *thesema = (struct semaphore *) sema;
369
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000370 dprintf(("free_sema(%lx) called\n", (long) sema));
Guido van Rossum7af81301997-01-17 21:06:41 +0000371 status = pthread_cond_destroy(&thesema->cond);
372 CHECK_STATUS("pthread_cond_destroy");
373 status = pthread_mutex_destroy(&thesema->mutex);
374 CHECK_STATUS("pthread_mutex_destroy");
375 free((void *) thesema);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000376}
377
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000378int down_sema _P2(sema, type_sema sema, waitflag, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000379{
Guido van Rossum7af81301997-01-17 21:06:41 +0000380 int status, error = 0, success;
381 struct semaphore *thesema = (struct semaphore *) sema;
382
Guido van Rossumcf1474b1996-10-08 14:17:53 +0000383 dprintf(("down_sema(%lx, %d) called\n", (long) sema, waitflag));
Guido van Rossum7af81301997-01-17 21:06:41 +0000384 status = pthread_mutex_lock(&thesema->mutex);
385 CHECK_STATUS("pthread_mutex_lock");
386 if (waitflag) {
387 while (!error && thesema->value <= 0) {
388 status = pthread_cond_wait(&thesema->cond,
389 &thesema->mutex);
390 CHECK_STATUS("pthread_cond_wait");
391 }
392 }
393 if (error)
394 success = 0;
395 else if (thesema->value > 0) {
396 thesema->value--;
397 success = 1;
398 }
399 else
400 success = 0;
401 status = pthread_mutex_unlock(&thesema->mutex);
402 CHECK_STATUS("pthread_mutex_unlock");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000403 dprintf(("down_sema(%lx) return\n", (long) sema));
Guido van Rossum7af81301997-01-17 21:06:41 +0000404 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000405}
406
407void up_sema _P1(sema, type_sema sema)
408{
Guido van Rossum7af81301997-01-17 21:06:41 +0000409 int status, error = 0;
410 struct semaphore *thesema = (struct semaphore *) sema;
411
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000412 dprintf(("up_sema(%lx)\n", (long) sema));
Guido van Rossum7af81301997-01-17 21:06:41 +0000413 status = pthread_mutex_lock(&thesema->mutex);
414 CHECK_STATUS("pthread_mutex_lock");
415 thesema->value++;
416 status = pthread_cond_signal(&thesema->cond);
417 CHECK_STATUS("pthread_cond_signal");
418 status = pthread_mutex_unlock(&thesema->mutex);
419 CHECK_STATUS("pthread_mutex_unlock");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000420}