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 success
= 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
);
248 #if defined(PY_PTHREAD_D4) || defined(PY_PTHREAD_D6) || defined(PY_PTHREAD_D7)
250 #elif defined(PY_PTHREAD_STD)
254 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
257 return (long) *(long *) &th
;
261 /* XXX This implementation is considered (to quote Tim Peters) "inherently
263 - It does not guanrantee the promise that a non-zero integer is returned.
264 - The cast to long is inherently unsafe.
265 - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
266 latter return statement (for Alpha OSF/1) are any longer necessary.
269 PyThread_get_thread_ident(void)
271 volatile pthread_t threadid
;
273 PyThread_init_thread();
274 /* Jump through some hoops for Alpha OSF/1 */
275 threadid
= pthread_self();
276 #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
277 return (long) threadid
;
279 return (long) *(long *) &threadid
;
284 do_PyThread_exit_thread(int no_cleanup
)
286 dprintf(("PyThread_exit_thread called\n"));
296 PyThread_exit_thread(void)
298 do_PyThread_exit_thread(0);
302 PyThread__exit_thread(void)
304 do_PyThread_exit_thread(1);
309 do_PyThread_exit_prog(int status
, int no_cleanup
)
311 dprintf(("PyThread_exit_prog(%d) called\n", status
));
320 PyThread_exit_prog(int status
)
322 do_PyThread_exit_prog(status
, 0);
326 PyThread__exit_prog(int status
)
328 do_PyThread_exit_prog(status
, 1);
330 #endif /* NO_EXIT_PROG */
332 #ifdef USE_SEMAPHORES
339 PyThread_allocate_lock(void)
342 int status
, error
= 0;
344 dprintf(("PyThread_allocate_lock called\n"));
346 PyThread_init_thread();
348 lock
= (sem_t
*)malloc(sizeof(sem_t
));
351 status
= sem_init(lock
,0,1);
352 CHECK_STATUS("sem_init");
360 dprintf(("PyThread_allocate_lock() -> %p\n", lock
));
361 return (PyThread_type_lock
)lock
;
365 PyThread_free_lock(PyThread_type_lock lock
)
367 sem_t
*thelock
= (sem_t
*)lock
;
368 int status
, error
= 0;
370 dprintf(("PyThread_free_lock(%p) called\n", lock
));
375 status
= sem_destroy(thelock
);
376 CHECK_STATUS("sem_destroy");
378 free((void *)thelock
);
382 * As of February 2002, Cygwin thread implementations mistakenly report error
383 * codes in the return value of the sem_ calls (like the pthread_ functions).
384 * Correct implementations return -1 and put the code in errno. This supports
388 fix_status(int status
)
390 return (status
== -1) ? errno
: status
;
394 PyThread_acquire_lock(PyThread_type_lock lock
, int waitflag
)
397 sem_t
*thelock
= (sem_t
*)lock
;
398 int status
, error
= 0;
400 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock
, waitflag
));
404 status
= fix_status(sem_wait(thelock
));
406 status
= fix_status(sem_trywait(thelock
));
407 } while (status
== EINTR
); /* Retry if interrupted by a signal */
410 CHECK_STATUS("sem_wait");
411 } else if (status
!= EAGAIN
) {
412 CHECK_STATUS("sem_trywait");
415 success
= (status
== 0) ? 1 : 0;
417 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock
, waitflag
, success
));
422 PyThread_release_lock(PyThread_type_lock lock
)
424 sem_t
*thelock
= (sem_t
*)lock
;
425 int status
, error
= 0;
427 dprintf(("PyThread_release_lock(%p) called\n", lock
));
429 status
= sem_post(thelock
);
430 CHECK_STATUS("sem_post");
433 #else /* USE_SEMAPHORES */
439 PyThread_allocate_lock(void)
442 int status
, error
= 0;
444 dprintf(("PyThread_allocate_lock called\n"));
446 PyThread_init_thread();
448 lock
= (pthread_lock
*) malloc(sizeof(pthread_lock
));
449 memset((void *)lock
, '\0', sizeof(pthread_lock
));
453 status
= pthread_mutex_init(&lock
->mut
,
454 pthread_mutexattr_default
);
455 CHECK_STATUS("pthread_mutex_init");
457 status
= pthread_cond_init(&lock
->lock_released
,
458 pthread_condattr_default
);
459 CHECK_STATUS("pthread_cond_init");
467 dprintf(("PyThread_allocate_lock() -> %p\n", lock
));
468 return (PyThread_type_lock
) lock
;
472 PyThread_free_lock(PyThread_type_lock lock
)
474 pthread_lock
*thelock
= (pthread_lock
*)lock
;
475 int status
, error
= 0;
477 dprintf(("PyThread_free_lock(%p) called\n", lock
));
479 status
= pthread_mutex_destroy( &thelock
->mut
);
480 CHECK_STATUS("pthread_mutex_destroy");
482 status
= pthread_cond_destroy( &thelock
->lock_released
);
483 CHECK_STATUS("pthread_cond_destroy");
485 free((void *)thelock
);
489 PyThread_acquire_lock(PyThread_type_lock lock
, int waitflag
)
492 pthread_lock
*thelock
= (pthread_lock
*)lock
;
493 int status
, error
= 0;
495 dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock
, waitflag
));
497 status
= pthread_mutex_lock( &thelock
->mut
);
498 CHECK_STATUS("pthread_mutex_lock[1]");
499 success
= thelock
->locked
== 0;
500 if (success
) thelock
->locked
= 1;
501 status
= pthread_mutex_unlock( &thelock
->mut
);
502 CHECK_STATUS("pthread_mutex_unlock[1]");
504 if ( !success
&& waitflag
) {
505 /* continue trying until we get the lock */
507 /* mut must be locked by me -- part of the condition
509 status
= pthread_mutex_lock( &thelock
->mut
);
510 CHECK_STATUS("pthread_mutex_lock[2]");
511 while ( thelock
->locked
) {
512 status
= pthread_cond_wait(&thelock
->lock_released
,
514 CHECK_STATUS("pthread_cond_wait");
517 status
= pthread_mutex_unlock( &thelock
->mut
);
518 CHECK_STATUS("pthread_mutex_unlock[2]");
521 if (error
) success
= 0;
522 dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock
, waitflag
, success
));
527 PyThread_release_lock(PyThread_type_lock lock
)
529 pthread_lock
*thelock
= (pthread_lock
*)lock
;
530 int status
, error
= 0;
532 dprintf(("PyThread_release_lock(%p) called\n", lock
));
534 status
= pthread_mutex_lock( &thelock
->mut
);
535 CHECK_STATUS("pthread_mutex_lock[3]");
539 status
= pthread_mutex_unlock( &thelock
->mut
);
540 CHECK_STATUS("pthread_mutex_unlock[3]");
542 /* wake up someone (anyone, if any) waiting on the lock */
543 status
= pthread_cond_signal( &thelock
->lock_released
);
544 CHECK_STATUS("pthread_cond_signal");
547 #endif /* USE_SEMAPHORES */