blob: 6c2bbfd3e747103abe9a79ba5ad87ed730a81fae [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001
Guido van Rossum66020991996-06-11 18:32:18 +00002/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00003
Guido van Rossum66020991996-06-11 18:32:18 +00004#include <stdlib.h>
Guido van Rossum9e46e561998-10-07 16:39:47 +00005#include <string.h>
Guido van Rossum66020991996-06-11 18:32:18 +00006#include <pthread.h>
Guido van Rossum80230992001-10-12 21:49:17 +00007#include <signal.h>
Guido van Rossum66020991996-06-11 18:32:18 +00008
Guido van Rossum1a623111996-08-08 18:53:41 +00009
Guido van Rossumd6353e21997-05-13 17:51:13 +000010/* try to determine what version of the Pthread Standard is installed.
11 * this is important, since all sorts of parameter types changed from
12 * draft to draft and there are several (incompatible) drafts in
13 * common use. these macros are a start, at least.
14 * 12 May 1997 -- david arnold <davida@pobox.com>
15 */
16
17#if defined(__ultrix) && defined(__mips) && defined(_DECTHREADS_)
18/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
19# define PY_PTHREAD_D4
20
21#elif defined(__osf__) && defined (__alpha)
22/* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
23# if !defined(_PTHREAD_ENV_ALPHA) || defined(_PTHREAD_USE_D4) || defined(PTHREAD_USE_D4)
24# define PY_PTHREAD_D4
25# else
26# define PY_PTHREAD_STD
27# endif
28
29#elif defined(_AIX)
Guido van Rossum1a623111996-08-08 18:53:41 +000030/* SCHED_BG_NP is defined if using AIX DCE pthreads
31 * but it is unsupported by AIX 4 pthreads. Default
32 * attributes for AIX 4 pthreads equal to NULL. For
33 * AIX DCE pthreads they should be left unchanged.
34 */
Guido van Rossumd6353e21997-05-13 17:51:13 +000035# if !defined(SCHED_BG_NP)
36# define PY_PTHREAD_STD
37# else
38# define PY_PTHREAD_D7
39# endif
40
Guido van Rossum64f91051997-05-22 20:41:59 +000041#elif defined(__DGUX)
42# define PY_PTHREAD_D6
Guido van Rossum46ff1901997-06-02 22:25:45 +000043
Guido van Rossum532246e1998-05-14 21:01:27 +000044#elif defined(__hpux) && defined(_DECTHREADS_)
Guido van Rossum89df70b1998-05-07 13:28:23 +000045# define PY_PTHREAD_D4
46
Guido van Rossum46ff1901997-06-02 22:25:45 +000047#else /* Default case */
48# define PY_PTHREAD_STD
49
Guido van Rossum1a623111996-08-08 18:53:41 +000050#endif
51
Jack Jansenc51395d2001-08-29 15:24:53 +000052#ifdef USE_GUSI
53/* The Macintosh GUSI I/O library sets the stackspace to
54** 20KB, much too low. We up it to 64K.
55*/
56#define THREAD_STACK_SIZE 0x10000
57#endif
58
Guido van Rossumd6353e21997-05-13 17:51:13 +000059
60/* set default attribute object for different versions */
61
62#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D7)
63# define pthread_attr_default pthread_attr_default
64# define pthread_mutexattr_default pthread_mutexattr_default
65# define pthread_condattr_default pthread_condattr_default
Guido van Rossum64f91051997-05-22 20:41:59 +000066#elif defined(PY_PTHREAD_STD) || defined(PY_PTHREAD_D6)
Guido van Rossumd6353e21997-05-13 17:51:13 +000067# define pthread_attr_default ((pthread_attr_t *)NULL)
68# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
69# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000070#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000071
Guido van Rossumd6353e21997-05-13 17:51:13 +000072
Guido van Rossum80230992001-10-12 21:49:17 +000073/* On platforms that don't use standard POSIX threads pthread_sigmask()
74 * isn't present. DEC threads uses sigprocmask() instead as do most
75 * other UNIX International compliant systems that don't have the full
76 * pthread implementation.
77 */
Martin v. Löwis69c0ff32001-10-15 14:34:42 +000078#ifdef HAVE_PTHREAD_SIGMASK
Guido van Rossum80230992001-10-12 21:49:17 +000079# define SET_THREAD_SIGMASK pthread_sigmask
80#else
81# define SET_THREAD_SIGMASK sigprocmask
82#endif
83
84
Guido van Rossumb98b1b31994-05-11 08:42:04 +000085/* A pthread mutex isn't sufficient to model the Python lock type
86 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
87 * following are undefined:
88 * -> a thread tries to lock a mutex it already has locked
89 * -> a thread tries to unlock a mutex locked by a different thread
90 * pthread mutexes are designed for serializing threads over short pieces
91 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000092 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +000093 *
94 * The pthread_lock struct implements a Python lock as a "locked?" bit
95 * and a <condition, mutex> pair. In general, if the bit can be acquired
96 * instantly, it is, else the pair is used to block the thread until the
97 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000098 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +000099
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000100typedef struct {
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000101 char locked; /* 0=unlocked, 1=locked */
102 /* a <cond, mutex> pair to handle an acquire of a locked lock */
103 pthread_cond_t lock_released;
104 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000105} pthread_lock;
106
Guido van Rossum9e46e561998-10-07 16:39:47 +0000107#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000108
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000109/*
110 * Initialization.
111 */
Guido van Rossum9e46e561998-10-07 16:39:47 +0000112
113#ifdef _HAVE_BSDI
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000114static
115void _noop(void)
Guido van Rossum9e46e561998-10-07 16:39:47 +0000116{
117}
118
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000119static void
120PyThread__init_thread(void)
Guido van Rossum9e46e561998-10-07 16:39:47 +0000121{
122 /* DO AN INIT BY STARTING THE THREAD */
123 static int dummy = 0;
124 pthread_t thread1;
125 pthread_create(&thread1, NULL, (void *) _noop, &dummy);
126 pthread_join(thread1, NULL);
127}
128
129#else /* !_HAVE_BSDI */
130
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000131static void
132PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000133{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000134#if defined(_AIX) && defined(__GNUC__)
135 pthread_init();
136#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000137}
138
Guido van Rossum9e46e561998-10-07 16:39:47 +0000139#endif /* !_HAVE_BSDI */
140
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000141/*
142 * Thread support.
143 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000144
145
Guido van Rossum3c288632001-10-16 21:13:49 +0000146long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000147PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000148{
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000149 pthread_t th;
Guido van Rossume944da81994-05-23 12:43:41 +0000150 int success;
Guido van Rossum80230992001-10-12 21:49:17 +0000151 sigset_t oldmask, newmask;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000152#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000153 pthread_attr_t attrs;
154#endif
Guido van Rossum65d5b571998-12-21 19:32:43 +0000155 dprintf(("PyThread_start_new_thread called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000156 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000157 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000158
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000159#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000160 pthread_attr_init(&attrs);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000161#endif
162#ifdef THREAD_STACK_SIZE
Jack Jansenc51395d2001-08-29 15:24:53 +0000163 pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
164#endif
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000165#ifdef PTHREAD_SYSTEM_SCHED_SUPPORTED
166 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
167#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000168
169 /* Mask all signals in the current thread before creating the new
170 * thread. This causes the new thread to start with all signals
171 * blocked.
172 */
173 sigfillset(&newmask);
174 SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask);
175
Guido van Rossumd6353e21997-05-13 17:51:13 +0000176 success = pthread_create(&th,
177#if defined(PY_PTHREAD_D4)
178 pthread_attr_default,
179 (pthread_startroutine_t)func,
180 (pthread_addr_t)arg
Guido van Rossum64f91051997-05-22 20:41:59 +0000181#elif defined(PY_PTHREAD_D6)
182 pthread_attr_default,
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000183 (void* (*)(void *))func,
Guido van Rossum64f91051997-05-22 20:41:59 +0000184 arg
Guido van Rossumd6353e21997-05-13 17:51:13 +0000185#elif defined(PY_PTHREAD_D7)
186 pthread_attr_default,
187 func,
188 arg
189#elif defined(PY_PTHREAD_STD)
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000190#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000191 &attrs,
192#else
Guido van Rossumd6353e21997-05-13 17:51:13 +0000193 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000194#endif
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000195 (void* (*)(void *))func,
Guido van Rossumd6353e21997-05-13 17:51:13 +0000196 (void *)arg
197#endif
198 );
Guido van Rossum80230992001-10-12 21:49:17 +0000199
200 /* Restore signal mask for original thread */
201 SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL);
202
Fred Drake03459a52001-11-09 16:00:41 +0000203#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Jack Jansenc51395d2001-08-29 15:24:53 +0000204 pthread_attr_destroy(&attrs);
205#endif
Guido van Rossum701f25e1999-03-15 20:27:53 +0000206 if (success == 0) {
Guido van Rossuma74d0e41998-09-04 13:38:32 +0000207#if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D6) || defined(PY_PTHREAD_D7)
Guido van Rossumd6353e21997-05-13 17:51:13 +0000208 pthread_detach(&th);
209#elif defined(PY_PTHREAD_STD)
Guido van Rossumf4806c21997-04-30 19:59:22 +0000210 pthread_detach(th);
Guido van Rossumd6353e21997-05-13 17:51:13 +0000211#endif
212 }
Guido van Rossum3c288632001-10-16 21:13:49 +0000213#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
214 return (long) th;
215#else
216 return (long) *(long *) &th;
217#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000218}
219
Trent Mick635f6fb2000-08-23 21:33:05 +0000220/* XXX This implementation is considered (to quote Tim Peters) "inherently
221 hosed" because:
222 - It does not guanrantee the promise that a non-zero integer is returned.
223 - The cast to long is inherently unsafe.
224 - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
225 latter return statement (for Alpha OSF/1) are any longer necessary.
226*/
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000227long
228PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000229{
Guido van Rossum44ee4791998-08-27 19:21:53 +0000230 volatile pthread_t threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000231 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000232 PyThread_init_thread();
Guido van Rossum2565bff1995-01-09 17:50:47 +0000233 /* Jump through some hoops for Alpha OSF/1 */
234 threadid = pthread_self();
Trent Mick635f6fb2000-08-23 21:33:05 +0000235#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
236 return (long) threadid;
237#else
Guido van Rossum2565bff1995-01-09 17:50:47 +0000238 return (long) *(long *) &threadid;
Trent Mick635f6fb2000-08-23 21:33:05 +0000239#endif
Guido van Rossume944da81994-05-23 12:43:41 +0000240}
241
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000242static void
243do_PyThread_exit_thread(int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000244{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000245 dprintf(("PyThread_exit_thread called\n"));
Guido van Rossum730806d1998-04-10 22:27:42 +0000246 if (!initialized) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000247 if (no_cleanup)
248 _exit(0);
249 else
250 exit(0);
Guido van Rossum730806d1998-04-10 22:27:42 +0000251 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000252}
253
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000254void
255PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000256{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000257 do_PyThread_exit_thread(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000258}
259
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000260void
261PyThread__exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000262{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000263 do_PyThread_exit_thread(1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000264}
265
266#ifndef NO_EXIT_PROG
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000267static void
268do_PyThread_exit_prog(int status, int no_cleanup)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000269{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000270 dprintf(("PyThread_exit_prog(%d) called\n", status));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000271 if (!initialized)
272 if (no_cleanup)
273 _exit(status);
274 else
275 exit(status);
276}
277
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000278void
279PyThread_exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000280{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000281 do_PyThread_exit_prog(status, 0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000282}
283
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000284void
285PyThread__exit_prog(int status)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000286{
Guido van Rossum65d5b571998-12-21 19:32:43 +0000287 do_PyThread_exit_prog(status, 1);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000288}
289#endif /* NO_EXIT_PROG */
290
291/*
292 * Lock support.
293 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000294PyThread_type_lock
295PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000296{
297 pthread_lock *lock;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000298 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000299
Guido van Rossum65d5b571998-12-21 19:32:43 +0000300 dprintf(("PyThread_allocate_lock called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000301 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000302 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000303
304 lock = (pthread_lock *) malloc(sizeof(pthread_lock));
Guido van Rossum9e46e561998-10-07 16:39:47 +0000305 memset((void *)lock, '\0', sizeof(pthread_lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000306 if (lock) {
307 lock->locked = 0;
308
309 status = pthread_mutex_init(&lock->mut,
310 pthread_mutexattr_default);
311 CHECK_STATUS("pthread_mutex_init");
312
313 status = pthread_cond_init(&lock->lock_released,
314 pthread_condattr_default);
315 CHECK_STATUS("pthread_cond_init");
316
317 if (error) {
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000318 free((void *)lock);
319 lock = 0;
320 }
321 }
322
Fred Drakea44d3532000-06-30 15:01:00 +0000323 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000324 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000325}
326
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000327void
328PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000329{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000330 pthread_lock *thelock = (pthread_lock *)lock;
331 int status, error = 0;
332
Fred Drakea44d3532000-06-30 15:01:00 +0000333 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000334
335 status = pthread_mutex_destroy( &thelock->mut );
336 CHECK_STATUS("pthread_mutex_destroy");
337
338 status = pthread_cond_destroy( &thelock->lock_released );
339 CHECK_STATUS("pthread_cond_destroy");
340
341 free((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000342}
343
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000344int
345PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000346{
347 int success;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000348 pthread_lock *thelock = (pthread_lock *)lock;
349 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000350
Fred Drakea44d3532000-06-30 15:01:00 +0000351 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000352
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000353 status = pthread_mutex_lock( &thelock->mut );
354 CHECK_STATUS("pthread_mutex_lock[1]");
355 success = thelock->locked == 0;
356 if (success) thelock->locked = 1;
357 status = pthread_mutex_unlock( &thelock->mut );
358 CHECK_STATUS("pthread_mutex_unlock[1]");
359
360 if ( !success && waitflag ) {
361 /* continue trying until we get the lock */
362
363 /* mut must be locked by me -- part of the condition
364 * protocol */
365 status = pthread_mutex_lock( &thelock->mut );
366 CHECK_STATUS("pthread_mutex_lock[2]");
367 while ( thelock->locked ) {
368 status = pthread_cond_wait(&thelock->lock_released,
369 &thelock->mut);
370 CHECK_STATUS("pthread_cond_wait");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000371 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000372 thelock->locked = 1;
373 status = pthread_mutex_unlock( &thelock->mut );
374 CHECK_STATUS("pthread_mutex_unlock[2]");
375 success = 1;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000376 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000377 if (error) success = 0;
Fred Drakea44d3532000-06-30 15:01:00 +0000378 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000379 return success;
380}
381
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000382void
383PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000384{
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000385 pthread_lock *thelock = (pthread_lock *)lock;
386 int status, error = 0;
387
Fred Drakea44d3532000-06-30 15:01:00 +0000388 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000389
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000390 status = pthread_mutex_lock( &thelock->mut );
391 CHECK_STATUS("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000392
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000393 thelock->locked = 0;
394
395 status = pthread_mutex_unlock( &thelock->mut );
396 CHECK_STATUS("pthread_mutex_unlock[3]");
397
398 /* wake up someone (anyone, if any) waiting on the lock */
399 status = pthread_cond_signal( &thelock->lock_released );
400 CHECK_STATUS("pthread_cond_signal");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000401}
402
403/*
404 * Semaphore support.
405 */
Guido van Rossum7af81301997-01-17 21:06:41 +0000406
407struct semaphore {
408 pthread_mutex_t mutex;
409 pthread_cond_t cond;
410 int value;
411};
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000412
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000413PyThread_type_sema
414PyThread_allocate_sema(int value)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000415{
Guido van Rossum7af81301997-01-17 21:06:41 +0000416 struct semaphore *sema;
417 int status, error = 0;
418
Guido van Rossum65d5b571998-12-21 19:32:43 +0000419 dprintf(("PyThread_allocate_sema called\n"));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000420 if (!initialized)
Guido van Rossum65d5b571998-12-21 19:32:43 +0000421 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000422
Guido van Rossum7af81301997-01-17 21:06:41 +0000423 sema = (struct semaphore *) malloc(sizeof(struct semaphore));
424 if (sema != NULL) {
425 sema->value = value;
426 status = pthread_mutex_init(&sema->mutex,
427 pthread_mutexattr_default);
428 CHECK_STATUS("pthread_mutex_init");
429 status = pthread_cond_init(&sema->cond,
430 pthread_condattr_default);
431 CHECK_STATUS("pthread_cond_init");
432 if (error) {
433 free((void *) sema);
434 sema = NULL;
435 }
436 }
Fred Drakea44d3532000-06-30 15:01:00 +0000437 dprintf(("PyThread_allocate_sema() -> %p\n", sema));
Guido van Rossum65d5b571998-12-21 19:32:43 +0000438 return (PyThread_type_sema) sema;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000439}
440
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000441void
442PyThread_free_sema(PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000443{
Guido van Rossum7af81301997-01-17 21:06:41 +0000444 int status, error = 0;
445 struct semaphore *thesema = (struct semaphore *) sema;
446
Fred Drakea44d3532000-06-30 15:01:00 +0000447 dprintf(("PyThread_free_sema(%p) called\n", sema));
Guido van Rossum7af81301997-01-17 21:06:41 +0000448 status = pthread_cond_destroy(&thesema->cond);
449 CHECK_STATUS("pthread_cond_destroy");
450 status = pthread_mutex_destroy(&thesema->mutex);
451 CHECK_STATUS("pthread_mutex_destroy");
452 free((void *) thesema);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000453}
454
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000455int
456PyThread_down_sema(PyThread_type_sema sema, int waitflag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000457{
Guido van Rossum7af81301997-01-17 21:06:41 +0000458 int status, error = 0, success;
459 struct semaphore *thesema = (struct semaphore *) sema;
460
Fred Drakea44d3532000-06-30 15:01:00 +0000461 dprintf(("PyThread_down_sema(%p, %d) called\n", sema, waitflag));
Guido van Rossum7af81301997-01-17 21:06:41 +0000462 status = pthread_mutex_lock(&thesema->mutex);
463 CHECK_STATUS("pthread_mutex_lock");
464 if (waitflag) {
465 while (!error && thesema->value <= 0) {
466 status = pthread_cond_wait(&thesema->cond,
467 &thesema->mutex);
468 CHECK_STATUS("pthread_cond_wait");
469 }
470 }
471 if (error)
472 success = 0;
473 else if (thesema->value > 0) {
474 thesema->value--;
475 success = 1;
476 }
477 else
478 success = 0;
479 status = pthread_mutex_unlock(&thesema->mutex);
480 CHECK_STATUS("pthread_mutex_unlock");
Fred Drakea44d3532000-06-30 15:01:00 +0000481 dprintf(("PyThread_down_sema(%p) return\n", sema));
Guido van Rossum7af81301997-01-17 21:06:41 +0000482 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000483}
484
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000485void
486PyThread_up_sema(PyThread_type_sema sema)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000487{
Guido van Rossum7af81301997-01-17 21:06:41 +0000488 int status, error = 0;
489 struct semaphore *thesema = (struct semaphore *) sema;
490
Fred Drakea44d3532000-06-30 15:01:00 +0000491 dprintf(("PyThread_up_sema(%p)\n", sema));
Guido van Rossum7af81301997-01-17 21:06:41 +0000492 status = pthread_mutex_lock(&thesema->mutex);
493 CHECK_STATUS("pthread_mutex_lock");
494 thesema->value++;
495 status = pthread_cond_signal(&thesema->cond);
496 CHECK_STATUS("pthread_cond_signal");
497 status = pthread_mutex_unlock(&thesema->mutex);
498 CHECK_STATUS("pthread_mutex_unlock");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000499}