2 /* Posix threads interface */
6 #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
7 #define destructor xxdestructor
10 #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
15 /* The POSIX spec says that implementations supporting the sem_*
16 family of functions must indicate this by defining
18 #ifdef _POSIX_SEMAPHORES
19 #include <semaphore.h>
24 /* try to determine what version of the Pthread Standard is installed.
25 * this is important, since all sorts of parameter types changed from
26 * draft to draft and there are several (incompatible) drafts in
27 * common use. these macros are a start, at least.
28 * 12 May 1997 -- david arnold <davida@pobox.com>
31 #if defined(__ultrix) && defined(__mips) && defined(_DECTHREADS_)
32 /* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
33 # define PY_PTHREAD_D4
34 # error Systems with PY_PTHREAD_D4 are unsupported. See README.
36 #elif defined(__osf__) && defined (__alpha)
37 /* _DECTHREADS_ is defined in cma.h which is included by pthread.h */
38 # if !defined(_PTHREAD_ENV_ALPHA) || defined(_PTHREAD_USE_D4) || defined(PTHREAD_USE_D4)
39 # define PY_PTHREAD_D4
40 # error Systems with PY_PTHREAD_D4 are unsupported. See README.
42 # define PY_PTHREAD_STD
46 /* SCHED_BG_NP is defined if using AIX DCE pthreads
47 * but it is unsupported by AIX 4 pthreads. Default
48 * attributes for AIX 4 pthreads equal to NULL. For
49 * AIX DCE pthreads they should be left unchanged.
51 # if !defined(SCHED_BG_NP)
52 # define PY_PTHREAD_STD
54 # define PY_PTHREAD_D7
55 # error Systems with PY_PTHREAD_D7 are unsupported. See README.
59 # define PY_PTHREAD_D6
60 # error Systems with PY_PTHREAD_D6 are unsupported. See README.
62 #elif defined(__hpux) && defined(_DECTHREADS_)
63 # define PY_PTHREAD_D4
64 # error Systems with PY_PTHREAD_D4 are unsupported. See README.
66 #else /* Default case */
67 # define PY_PTHREAD_STD
72 /* The Macintosh GUSI I/O library sets the stackspace to
73 ** 20KB, much too low. We up it to 64K.
75 #define THREAD_STACK_SIZE 0x10000
79 /* set default attribute object for different versions */
81 #if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D7)
82 #if !defined(pthread_attr_default)
83 # define pthread_attr_default pthread_attr_default
85 #if !defined(pthread_mutexattr_default)
86 # define pthread_mutexattr_default pthread_mutexattr_default
88 #if !defined(pthread_condattr_default)
89 # define pthread_condattr_default pthread_condattr_default
91 #elif defined(PY_PTHREAD_STD) || defined(PY_PTHREAD_D6)
92 #if !defined(pthread_attr_default)
93 # define pthread_attr_default ((pthread_attr_t *)NULL)
95 #if !defined(pthread_mutexattr_default)
96 # define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
98 #if !defined(pthread_condattr_default)
99 # define pthread_condattr_default ((pthread_condattr_t *)NULL)
104 /* Whether or not to use semaphores directly rather than emulating them with
105 * mutexes and condition variables:
107 #if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)
108 # define USE_SEMAPHORES
110 # undef USE_SEMAPHORES
114 /* On platforms that don't use standard POSIX threads pthread_sigmask()
115 * isn't present. DEC threads uses sigprocmask() instead as do most
116 * other UNIX International compliant systems that don't have the full
117 * pthread implementation.
119 #ifdef HAVE_PTHREAD_SIGMASK
120 # define SET_THREAD_SIGMASK pthread_sigmask
122 # define SET_THREAD_SIGMASK sigprocmask
126 /* A pthread mutex isn't sufficient to model the Python lock type
127 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
128 * following are undefined:
129 * -> a thread tries to lock a mutex it already has locked
130 * -> a thread tries to unlock a mutex locked by a different thread
131 * pthread mutexes are designed for serializing threads over short pieces
132 * of code anyway, so wouldn't be an appropriate implementation of
133 * Python's locks regardless.
135 * The pthread_lock struct implements a Python lock as a "locked?" bit
136 * and a <condition, mutex> pair. In general, if the bit can be acquired
137 * instantly, it is, else the pair is used to block the thread until the
138 * bit is cleared. 9 May 1994 tim@ksr.com
142 char locked
; /* 0=unlocked, 1=locked */
143 /* a <cond, mutex> pair to handle an acquire of a locked lock */
144 pthread_cond_t lock_released
;
148 #define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
161 PyThread__init_thread(void)
163 /* DO AN INIT BY STARTING THE THREAD */
164 static int dummy
= 0;
166 pthread_create(&thread1
, NULL
, (void *) _noop
, &dummy
);
167 pthread_join(thread1
, NULL
);
170 #else /* !_HAVE_BSDI */
173 PyThread__init_thread(void)
175 #if defined(_AIX) && defined(__GNUC__)
180 #endif /* !_HAVE_BSDI */
188 PyThread_start_new_thread(void (*func
)(void *), void *arg
)
192 sigset_t oldmask
, newmask
;
193 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
194 pthread_attr_t attrs
;
196 dprintf(("PyThread_start_new_thread called\n"));
198 PyThread_init_thread();
200 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
201 pthread_attr_init(&attrs
);
203 #ifdef THREAD_STACK_SIZE
204 pthread_attr_setstacksize(&attrs
, THREAD_STACK_SIZE
);
206 #ifdef PTHREAD_SYSTEM_SCHED_SUPPORTED
207 pthread_attr_setscope(&attrs
, PTHREAD_SCOPE_SYSTEM
);
210 /* Mask all signals in the current thread before creating the new
211 * thread. This causes the new thread to start with all signals
214 sigfillset(&newmask
);
215 SET_THREAD_SIGMASK(SIG_BLOCK
, &newmask
, &oldmask
);
217 status
= pthread_create(&th
,
218 #if defined(PY_PTHREAD_D4)
219 pthread_attr_default
,
220 (pthread_startroutine_t
)func
,
222 #elif defined(PY_PTHREAD_D6)
223 pthread_attr_default
,
224 (void* (*)(void *))func
,
226 #elif defined(PY_PTHREAD_D7)
227 pthread_attr_default
,
230 #elif defined(PY_PTHREAD_STD)
231 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
234 (pthread_attr_t
*)NULL
,
236 (void* (*)(void *))func
,
241 /* Restore signal mask for original thread */
242 SET_THREAD_SIGMASK(SIG_SETMASK
, &oldmask
, NULL
);
244 #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
245 pthread_attr_destroy(&attrs
);
250 #if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D6) || defined(PY_PTHREAD_D7)
252 #elif defined(PY_PTHREAD_STD)
256 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
259 return (long) *(long *) &th
;
263 /* XXX This implementation is considered (to quote Tim Peters) "inherently
265 - It does not guanrantee the promise that a non-zero integer is returned.
266 - The cast to long is inherently unsafe.
267 - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
268 latter return statement (for Alpha OSF/1) are any longer necessary.
271 PyThread_get_thread_ident(void)
273 volatile pthread_t threadid
;
275 PyThread_init_thread();
276 /* Jump through some hoops for Alpha OSF/1 */
277 threadid
= pthread_self();
278 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
279 return (long) threadid
;
281 return (long) *(long *) &threadid
;
286 do_PyThread_exit_thread(int no_cleanup
)
288 dprintf(("PyThread_exit_thread called\n"));
298 PyThread_exit_thread(void)
300 do_PyThread_exit_thread(0);
304 PyThread__exit_thread(void)
306 do_PyThread_exit_thread(1);
311 do_PyThread_exit_prog(int status
, int no_cleanup
)
313 dprintf(("PyThread_exit_prog(%d) called\n", status
));
322 PyThread_exit_prog(int status
)
324 do_PyThread_exit_prog(status
, 0);
328 PyThread__exit_prog(int status
)
330 do_PyThread_exit_prog(status
, 1);
332 #endif /* NO_EXIT_PROG */
334 #ifdef USE_SEMAPHORES
341 PyThread_allocate_lock(void)
344 int status
, error
= 0;
346 dprintf(("PyThread_allocate_lock called\n"));
348 PyThread_init_thread();
350 lock
= (sem_t
*)malloc(sizeof(sem_t
));
353 status
= sem_init(lock
,0,1);
354 CHECK_STATUS("sem_init");
362 dprintf(("PyThread_allocate_lock() -> %p\n", lock
));
363 return (PyThread_type_lock
)lock
;
367 PyThread_free_lock(PyThread_type_lock lock
)
369 sem_t
*thelock
= (sem_t
*)lock
;
370 int status
, error
= 0;
372 dprintf(("PyThread_free_lock(%p) called\n", lock
));
377 status
= sem_destroy(thelock
);
378 CHECK_STATUS("sem_destroy");
380 free((void *)thelock
);
384 * As of February 2002, Cygwin thread implementations mistakenly report error
385 * codes in the return value of the sem_ calls (like the pthread_ functions).
386 * Correct implementations return -1 and put the code in errno. This supports
390 fix_status(int status
)
392 return (status
== -1) ? errno
: status
;
396 PyThread_acquire_lock(PyThread_type_lock lock
, int waitflag
)
399 sem_t
*thelock
= (sem_t
*)lock
;
400 int status
, error
= 0;
402 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock
, waitflag
));
406 status
= fix_status(sem_wait(thelock
));
408 status
= fix_status(sem_trywait(thelock
));
409 } while (status
== EINTR
); /* Retry if interrupted by a signal */
412 CHECK_STATUS("sem_wait");
413 } else if (status
!= EAGAIN
) {
414 CHECK_STATUS("sem_trywait");
417 success
= (status
== 0) ? 1 : 0;
419 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock
, waitflag
, success
));
424 PyThread_release_lock(PyThread_type_lock lock
)
426 sem_t
*thelock
= (sem_t
*)lock
;
427 int status
, error
= 0;
429 dprintf(("PyThread_release_lock(%p) called\n", lock
));
431 status
= sem_post(thelock
);
432 CHECK_STATUS("sem_post");
435 #else /* USE_SEMAPHORES */
441 PyThread_allocate_lock(void)
444 int status
, error
= 0;
446 dprintf(("PyThread_allocate_lock called\n"));
448 PyThread_init_thread();
450 lock
= (pthread_lock
*) malloc(sizeof(pthread_lock
));
451 memset((void *)lock
, '\0', sizeof(pthread_lock
));
455 status
= pthread_mutex_init(&lock
->mut
,
456 pthread_mutexattr_default
);
457 CHECK_STATUS("pthread_mutex_init");
459 status
= pthread_cond_init(&lock
->lock_released
,
460 pthread_condattr_default
);
461 CHECK_STATUS("pthread_cond_init");
469 dprintf(("PyThread_allocate_lock() -> %p\n", lock
));
470 return (PyThread_type_lock
) lock
;
474 PyThread_free_lock(PyThread_type_lock lock
)
476 pthread_lock
*thelock
= (pthread_lock
*)lock
;
477 int status
, error
= 0;
479 dprintf(("PyThread_free_lock(%p) called\n", lock
));
481 status
= pthread_mutex_destroy( &thelock
->mut
);
482 CHECK_STATUS("pthread_mutex_destroy");
484 status
= pthread_cond_destroy( &thelock
->lock_released
);
485 CHECK_STATUS("pthread_cond_destroy");
487 free((void *)thelock
);
491 PyThread_acquire_lock(PyThread_type_lock lock
, int waitflag
)
494 pthread_lock
*thelock
= (pthread_lock
*)lock
;
495 int status
, error
= 0;
497 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock
, waitflag
));
499 status
= pthread_mutex_lock( &thelock
->mut
);
500 CHECK_STATUS("pthread_mutex_lock[1]");
501 success
= thelock
->locked
== 0;
503 if ( !success
&& waitflag
) {
504 /* continue trying until we get the lock */
506 /* mut must be locked by me -- part of the condition
508 while ( thelock
->locked
) {
509 status
= pthread_cond_wait(&thelock
->lock_released
,
511 CHECK_STATUS("pthread_cond_wait");
515 if (success
) thelock
->locked
= 1;
516 status
= pthread_mutex_unlock( &thelock
->mut
);
517 CHECK_STATUS("pthread_mutex_unlock[1]");
519 if (error
) success
= 0;
520 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock
, waitflag
, success
));
525 PyThread_release_lock(PyThread_type_lock lock
)
527 pthread_lock
*thelock
= (pthread_lock
*)lock
;
528 int status
, error
= 0;
530 dprintf(("PyThread_release_lock(%p) called\n", lock
));
532 status
= pthread_mutex_lock( &thelock
->mut
);
533 CHECK_STATUS("pthread_mutex_lock[3]");
537 status
= pthread_mutex_unlock( &thelock
->mut
);
538 CHECK_STATUS("pthread_mutex_unlock[3]");
540 /* wake up someone (anyone, if any) waiting on the lock */
541 status
= pthread_cond_signal( &thelock
->lock_released
);
542 CHECK_STATUS("pthread_cond_signal");
545 #endif /* USE_SEMAPHORES */