blob: 697140558fdc5e7b5f3fdc432c671bed3d18f167 [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>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +00006#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +00007#define destructor xxdestructor
8#endif
Guido van Rossum66020991996-06-11 18:32:18 +00009#include <pthread.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +000010#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +000011#undef destructor
12#endif
Guido van Rossum80230992001-10-12 21:49:17 +000013#include <signal.h>
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000014
Thomas Wouters0e3f5912006-08-11 14:57:12 +000015/* The POSIX spec requires that use of pthread_attr_setstacksize
16 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
17#ifdef _POSIX_THREAD_ATTR_STACKSIZE
18#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000020#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070021
Ned Deily7ca97d52012-03-13 11:18:18 -070022/* The default stack size for new threads on OSX and BSD is small enough that
23 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
24 * exceptions.
25 *
26 * The default stack sizes below are the empirically determined minimal stack
27 * sizes where a simple recursive function doesn't cause a hard crash.
28 */
29#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
30#undef THREAD_STACK_SIZE
31#define THREAD_STACK_SIZE 0x500000
32#endif
33#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070034#undef THREAD_STACK_SIZE
35#define THREAD_STACK_SIZE 0x400000
36#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000037/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080038#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
40#ifdef THREAD_STACK_SIZE
41#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
42#endif
43#endif
44
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000045/* The POSIX spec says that implementations supporting the sem_*
46 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000048#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000050 we need to add 0 to make it work there as well. */
51#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000052#define HAVE_BROKEN_POSIX_SEMAPHORES
53#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000054#include <semaphore.h>
55#include <errno.h>
56#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000057#endif
Guido van Rossum66020991996-06-11 18:32:18 +000058
Martin v. Löwisb0233812002-12-11 13:12:30 +000059#if !defined(pthread_attr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000060# define pthread_attr_default ((pthread_attr_t *)NULL)
Martin v. Löwisb0233812002-12-11 13:12:30 +000061#endif
62#if !defined(pthread_mutexattr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000063# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
Martin v. Löwisb0233812002-12-11 13:12:30 +000064#endif
65#if !defined(pthread_condattr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000066# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000067#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000068
Guido van Rossumd6353e21997-05-13 17:51:13 +000069
Martin v. Löwiscc898662002-03-17 09:53:51 +000070/* Whether or not to use semaphores directly rather than emulating them with
71 * mutexes and condition variables:
72 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000073#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
74 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000075# define USE_SEMAPHORES
76#else
77# undef USE_SEMAPHORES
78#endif
79
80
Guido van Rossum80230992001-10-12 21:49:17 +000081/* On platforms that don't use standard POSIX threads pthread_sigmask()
82 * isn't present. DEC threads uses sigprocmask() instead as do most
83 * other UNIX International compliant systems that don't have the full
84 * pthread implementation.
85 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000086#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000087# define SET_THREAD_SIGMASK pthread_sigmask
88#else
89# define SET_THREAD_SIGMASK sigprocmask
90#endif
91
92
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000093/* We assume all modern POSIX systems have gettimeofday() */
94#ifdef GETTIMEOFDAY_NO_TZ
95#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
96#else
97#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
98#endif
99
100#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
101do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 struct timeval tv; \
103 GETTIMEOFDAY(&tv); \
104 tv.tv_usec += microseconds % 1000000; \
105 tv.tv_sec += microseconds / 1000000; \
106 tv.tv_sec += tv.tv_usec / 1000000; \
107 tv.tv_usec %= 1000000; \
108 ts.tv_sec = tv.tv_sec; \
109 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000110} while(0)
111
112
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000113/* A pthread mutex isn't sufficient to model the Python lock type
114 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
115 * following are undefined:
116 * -> a thread tries to lock a mutex it already has locked
117 * -> a thread tries to unlock a mutex locked by a different thread
118 * pthread mutexes are designed for serializing threads over short pieces
119 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000120 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000121 *
122 * The pthread_lock struct implements a Python lock as a "locked?" bit
123 * and a <condition, mutex> pair. In general, if the bit can be acquired
124 * instantly, it is, else the pair is used to block the thread until the
125 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000126 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000127
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000128typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 char locked; /* 0=unlocked, 1=locked */
130 /* a <cond, mutex> pair to handle an acquire of a locked lock */
131 pthread_cond_t lock_released;
132 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000133} pthread_lock;
134
Guido van Rossum9e46e561998-10-07 16:39:47 +0000135#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100136#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
137 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000138
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000139/*
140 * Initialization.
141 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000142static void
143PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000144{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000145#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200146 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000148#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000149}
150
151/*
152 * Thread support.
153 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000154
155
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200156unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000157PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 pthread_t th;
160 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000161#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000163#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000164#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000166#endif
167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 dprintf(("PyThread_start_new_thread called\n"));
169 if (!initialized)
170 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000171
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000172#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200174 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000175#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000176#if defined(THREAD_STACK_SIZE)
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600177 PyThreadState *tstate = PyThreadState_GET();
178 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
179 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 if (tss != 0) {
181 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
182 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200183 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 }
185 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000186#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000187#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000189#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000192#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000194#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000196#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 (void* (*)(void *))func,
198 (void *)arg
199 );
Guido van Rossum80230992001-10-12 21:49:17 +0000200
Fred Drake03459a52001-11-09 16:00:41 +0000201#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000203#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 if (status != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200205 return PYTHREAD_INVALID_THREAD_ID;
Martin v. Löwis910ae622003-04-19 07:44:52 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000208
Guido van Rossum3c288632001-10-16 21:13:49 +0000209#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200210 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000211#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200212 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000213#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000214}
215
Trent Mick635f6fb2000-08-23 21:33:05 +0000216/* XXX This implementation is considered (to quote Tim Peters) "inherently
217 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000218 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200219 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100220 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000221*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200222unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000223PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000224{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 volatile pthread_t threadid;
226 if (!initialized)
227 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200229 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000230}
231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000233PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200236 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200238 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000239}
240
Martin v. Löwiscc898662002-03-17 09:53:51 +0000241#ifdef USE_SEMAPHORES
242
243/*
244 * Lock support.
245 */
246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000248PyThread_allocate_lock(void)
249{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 sem_t *lock;
251 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 dprintf(("PyThread_allocate_lock called\n"));
254 if (!initialized)
255 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000256
Victor Stinner80aa5652013-07-07 17:17:59 +0200257 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 if (lock) {
260 status = sem_init(lock,0,1);
261 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200264 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 lock = NULL;
266 }
267 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
270 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000271}
272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000274PyThread_free_lock(PyThread_type_lock lock)
275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 sem_t *thelock = (sem_t *)lock;
277 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000278
Christian Heimes56379c02012-12-02 08:37:00 +0100279 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 if (!thelock)
283 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 status = sem_destroy(thelock);
286 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000287
Victor Stinner80aa5652013-07-07 17:17:59 +0200288 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000289}
290
291/*
292 * As of February 2002, Cygwin thread implementations mistakenly report error
293 * codes in the return value of the sem_ calls (like the pthread_ functions).
294 * Correct implementations return -1 and put the code in errno. This supports
295 * either.
296 */
297static int
298fix_status(int status)
299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000301}
302
Antoine Pitrou810023d2010-12-15 22:59:16 +0000303PyLockStatus
304PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
305 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000306{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000307 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 sem_t *thelock = (sem_t *)lock;
309 int status, error = 0;
310 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700311 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000312
Christian Heimes56379c02012-12-02 08:37:00 +0100313 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000314 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
315 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000316
Victor Stinner850a18e2017-10-24 16:53:32 -0700317 if (microseconds > PY_TIMEOUT_MAX) {
318 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
319 }
320
321 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700323
324 if (!intr_flag) {
325 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
326 check done above */
327 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
328 deadline = _PyTime_GetMonotonicClock() + timeout;
329 }
330 }
331
332 while (1) {
333 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700335 }
336 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700338 }
339 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700341 }
342
Antoine Pitrou810023d2010-12-15 22:59:16 +0000343 /* Retry if interrupted by a signal, unless the caller wants to be
344 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700345 if (intr_flag || status != EINTR) {
346 break;
347 }
348
349 if (microseconds > 0) {
350 /* wait interrupted by a signal (EINTR): recompute the timeout */
351 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
352 if (dt < 0) {
353 status = ETIMEDOUT;
354 break;
355 }
356 else if (dt > 0) {
357 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
358 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
359 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
360 check done above */
361 Py_UNREACHABLE();
362 }
363 /* no need to update microseconds value, the code only care
364 if (microseconds > 0 or (microseconds == 0). */
365 }
366 else {
367 microseconds = 0;
368 }
369 }
370 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000371
Antoine Pitrou810023d2010-12-15 22:59:16 +0000372 /* Don't check the status if we're stopping because of an interrupt. */
373 if (!(intr_flag && status == EINTR)) {
374 if (microseconds > 0) {
375 if (status != ETIMEDOUT)
376 CHECK_STATUS("sem_timedwait");
377 }
378 else if (microseconds == 0) {
379 if (status != EAGAIN)
380 CHECK_STATUS("sem_trywait");
381 }
382 else {
383 CHECK_STATUS("sem_wait");
384 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000386
Antoine Pitrou810023d2010-12-15 22:59:16 +0000387 if (status == 0) {
388 success = PY_LOCK_ACQUIRED;
389 } else if (intr_flag && status == EINTR) {
390 success = PY_LOCK_INTR;
391 } else {
392 success = PY_LOCK_FAILURE;
393 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394
Antoine Pitrou810023d2010-12-15 22:59:16 +0000395 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
396 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000398}
399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000401PyThread_release_lock(PyThread_type_lock lock)
402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 sem_t *thelock = (sem_t *)lock;
404 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000405
Christian Heimes56379c02012-12-02 08:37:00 +0100406 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 status = sem_post(thelock);
410 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000411}
412
413#else /* USE_SEMAPHORES */
414
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000415/*
416 * Lock support.
417 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000419PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 pthread_lock *lock;
422 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 dprintf(("PyThread_allocate_lock called\n"));
425 if (!initialized)
426 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000427
Victor Stinner80aa5652013-07-07 17:17:59 +0200428 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 if (lock) {
430 memset((void *)lock, '\0', sizeof(pthread_lock));
431 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000432
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 status = pthread_mutex_init(&lock->mut,
434 pthread_mutexattr_default);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100435 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 /* Mark the pthread mutex underlying a Python mutex as
437 pure happens-before. We can't simply mark the
438 Python-level mutex as a mutex because it can be
439 acquired and released in different threads, which
440 will cause errors. */
441 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 status = pthread_cond_init(&lock->lock_released,
444 pthread_condattr_default);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100445 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200448 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 lock = 0;
450 }
451 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
454 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000455}
456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000458PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 pthread_lock *thelock = (pthread_lock *)lock;
461 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000462
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200463 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000465
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000466 /* some pthread-like implementations tie the mutex to the cond
467 * and must have the cond destroyed first.
468 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100470 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000471
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000472 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100473 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000474
Victor Stinner80aa5652013-07-07 17:17:59 +0200475 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000476}
477
Antoine Pitrou810023d2010-12-15 22:59:16 +0000478PyLockStatus
479PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
480 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000481{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200482 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 pthread_lock *thelock = (pthread_lock *)lock;
484 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000485
Antoine Pitrou810023d2010-12-15 22:59:16 +0000486 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
487 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000488
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200489 if (microseconds == 0) {
490 status = pthread_mutex_trylock( &thelock->mut );
491 if (status != EBUSY)
492 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
493 }
494 else {
495 status = pthread_mutex_lock( &thelock->mut );
496 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
497 }
498 if (status == 0) {
499 if (thelock->locked == 0) {
500 success = PY_LOCK_ACQUIRED;
501 }
502 else if (microseconds != 0) {
503 struct timespec ts;
504 if (microseconds > 0)
505 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
506 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000507
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200508 /* mut must be locked by me -- part of the condition
509 * protocol */
510 while (success == PY_LOCK_FAILURE) {
511 if (microseconds > 0) {
512 status = pthread_cond_timedwait(
513 &thelock->lock_released,
514 &thelock->mut, &ts);
515 if (status == ETIMEDOUT)
516 break;
517 CHECK_STATUS_PTHREAD("pthread_cond_timed_wait");
518 }
519 else {
520 status = pthread_cond_wait(
521 &thelock->lock_released,
522 &thelock->mut);
523 CHECK_STATUS_PTHREAD("pthread_cond_wait");
524 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000525
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200526 if (intr_flag && status == 0 && thelock->locked) {
527 /* We were woken up, but didn't get the lock. We probably received
528 * a signal. Return PY_LOCK_INTR to allow the caller to handle
529 * it and retry. */
530 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200532 }
533 else if (status == 0 && !thelock->locked) {
534 success = PY_LOCK_ACQUIRED;
535 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000536 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200538 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
539 status = pthread_mutex_unlock( &thelock->mut );
540 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000542
Antoine Pitrou810023d2010-12-15 22:59:16 +0000543 if (error) success = PY_LOCK_FAILURE;
544 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
545 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000547}
548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000550PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 pthread_lock *thelock = (pthread_lock *)lock;
553 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000554
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200555 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100559 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 /* wake up someone (anyone, if any) waiting on the lock */
564 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100565 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000566
567 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100568 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000569}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000570
571#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000572
Antoine Pitrou810023d2010-12-15 22:59:16 +0000573int
574PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
575{
576 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
577}
578
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000579/* set the thread stack size.
580 * Return 0 if size is valid, -1 if size is invalid,
581 * -2 if setting stack size is not supported.
582 */
583static int
584_pythread_pthread_set_stacksize(size_t size)
585{
586#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 pthread_attr_t attrs;
588 size_t tss_min;
589 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000590#endif
591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 /* set to default */
593 if (size == 0) {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600594 PyThreadState_GET()->interp->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 return 0;
596 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000597
598#if defined(THREAD_STACK_SIZE)
599#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
601 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000602#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000604#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 if (size >= tss_min) {
606 /* validate stack size by setting thread attribute */
607 if (pthread_attr_init(&attrs) == 0) {
608 rc = pthread_attr_setstacksize(&attrs, size);
609 pthread_attr_destroy(&attrs);
610 if (rc == 0) {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600611 PyThreadState_GET()->interp->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 return 0;
613 }
614 }
615 }
616 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000617#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000619#endif
620}
621
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000623
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000624
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900625/* Thread Local Storage (TLS) API
626
627 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
628*/
629
630/* Issue #25658: On platforms where native TLS key is defined in a way that
631 cannot be safely cast to int, PyThread_create_key returns immediately a
632 failure status and other TLS functions all are no-ops. This indicates
633 clearly that the old API is not supported on platforms where it cannot be
634 used reliably, and that no effort will be made to add such support.
635
636 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
637 removing this API.
638*/
639
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000640int
641PyThread_create_key(void)
642{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900643#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000644 pthread_key_t key;
645 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200646 if (fail)
647 return -1;
648 if (key > INT_MAX) {
649 /* Issue #22206: handle integer overflow */
650 pthread_key_delete(key);
651 errno = ENOMEM;
652 return -1;
653 }
654 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900655#else
656 return -1; /* never return valid key value. */
657#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000658}
659
660void
661PyThread_delete_key(int key)
662{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900663#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000664 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900665#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000666}
667
668void
669PyThread_delete_key_value(int key)
670{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900671#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000672 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900673#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000674}
675
676int
677PyThread_set_key_value(int key, void *value)
678{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900679#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
680 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000681 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900682#else
683 return -1;
684#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000685}
686
687void *
688PyThread_get_key_value(int key)
689{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900690#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000691 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900692#else
693 return NULL;
694#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000695}
696
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900697
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000698void
699PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900700{
701}
702
703
704/* Thread Specific Storage (TSS) API
705
706 Platform-specific components of TSS API implementation.
707*/
708
709int
710PyThread_tss_create(Py_tss_t *key)
711{
712 assert(key != NULL);
713 /* If the key has been created, function is silently skipped. */
714 if (key->_is_initialized) {
715 return 0;
716 }
717
718 int fail = pthread_key_create(&(key->_key), NULL);
719 if (fail) {
720 return -1;
721 }
722 key->_is_initialized = 1;
723 return 0;
724}
725
726void
727PyThread_tss_delete(Py_tss_t *key)
728{
729 assert(key != NULL);
730 /* If the key has not been created, function is silently skipped. */
731 if (!key->_is_initialized) {
732 return;
733 }
734
735 pthread_key_delete(key->_key);
736 /* pthread has not provided the defined invalid value for the key. */
737 key->_is_initialized = 0;
738}
739
740int
741PyThread_tss_set(Py_tss_t *key, void *value)
742{
743 assert(key != NULL);
744 int fail = pthread_setspecific(key->_key, value);
745 return fail ? -1 : 0;
746}
747
748void *
749PyThread_tss_get(Py_tss_t *key)
750{
751 assert(key != NULL);
752 return pthread_getspecific(key->_key);
753}