blob: b7463c0ca67763691210b5425c7582ea3e7a39f8 [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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000059/* Before FreeBSD 5.4, system scope threads was very limited resource
60 in default setting. So the process scope is preferred to get
61 enough number of threads to work. */
62#ifdef __FreeBSD__
63#include <osreldate.h>
64#if __FreeBSD_version >= 500000 && __FreeBSD_version < 504101
65#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
66#endif
67#endif
68
Martin v. Löwisb0233812002-12-11 13:12:30 +000069#if !defined(pthread_attr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000070# define pthread_attr_default ((pthread_attr_t *)NULL)
Martin v. Löwisb0233812002-12-11 13:12:30 +000071#endif
72#if !defined(pthread_mutexattr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000073# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
Martin v. Löwisb0233812002-12-11 13:12:30 +000074#endif
75#if !defined(pthread_condattr_default)
Guido van Rossumd6353e21997-05-13 17:51:13 +000076# define pthread_condattr_default ((pthread_condattr_t *)NULL)
Guido van Rossum1a623111996-08-08 18:53:41 +000077#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +000078
Guido van Rossumd6353e21997-05-13 17:51:13 +000079
Martin v. Löwiscc898662002-03-17 09:53:51 +000080/* Whether or not to use semaphores directly rather than emulating them with
81 * mutexes and condition variables:
82 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000083#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
84 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000085# define USE_SEMAPHORES
86#else
87# undef USE_SEMAPHORES
88#endif
89
90
Guido van Rossum80230992001-10-12 21:49:17 +000091/* On platforms that don't use standard POSIX threads pthread_sigmask()
92 * isn't present. DEC threads uses sigprocmask() instead as do most
93 * other UNIX International compliant systems that don't have the full
94 * pthread implementation.
95 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000096#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000097# define SET_THREAD_SIGMASK pthread_sigmask
98#else
99# define SET_THREAD_SIGMASK sigprocmask
100#endif
101
102
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000103/* We assume all modern POSIX systems have gettimeofday() */
104#ifdef GETTIMEOFDAY_NO_TZ
105#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
106#else
107#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
108#endif
109
110#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
111do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 struct timeval tv; \
113 GETTIMEOFDAY(&tv); \
114 tv.tv_usec += microseconds % 1000000; \
115 tv.tv_sec += microseconds / 1000000; \
116 tv.tv_sec += tv.tv_usec / 1000000; \
117 tv.tv_usec %= 1000000; \
118 ts.tv_sec = tv.tv_sec; \
119 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000120} while(0)
121
122
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000123/* A pthread mutex isn't sufficient to model the Python lock type
124 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
125 * following are undefined:
126 * -> a thread tries to lock a mutex it already has locked
127 * -> a thread tries to unlock a mutex locked by a different thread
128 * pthread mutexes are designed for serializing threads over short pieces
129 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000130 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000131 *
132 * The pthread_lock struct implements a Python lock as a "locked?" bit
133 * and a <condition, mutex> pair. In general, if the bit can be acquired
134 * instantly, it is, else the pair is used to block the thread until the
135 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000136 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000137
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000138typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 char locked; /* 0=unlocked, 1=locked */
140 /* a <cond, mutex> pair to handle an acquire of a locked lock */
141 pthread_cond_t lock_released;
142 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000143} pthread_lock;
144
Guido van Rossum9e46e561998-10-07 16:39:47 +0000145#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100146#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
147 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000148
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000149/*
150 * Initialization.
151 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000152static void
153PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000154{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000155#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200156 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000158#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000159}
160
161/*
162 * Thread support.
163 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000164
165
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200166unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000167PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 pthread_t th;
170 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000171#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000173#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000174#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000176#endif
177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 dprintf(("PyThread_start_new_thread called\n"));
179 if (!initialized)
180 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000181
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000182#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200184 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000185#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000186#if defined(THREAD_STACK_SIZE)
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600187 PyThreadState *tstate = PyThreadState_GET();
188 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
189 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 if (tss != 0) {
191 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
192 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200193 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 }
195 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000196#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000197#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000199#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000202#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000204#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000206#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 (void* (*)(void *))func,
208 (void *)arg
209 );
Guido van Rossum80230992001-10-12 21:49:17 +0000210
Fred Drake03459a52001-11-09 16:00:41 +0000211#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000213#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 if (status != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200215 return PYTHREAD_INVALID_THREAD_ID;
Martin v. Löwis910ae622003-04-19 07:44:52 +0000216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000218
Guido van Rossum3c288632001-10-16 21:13:49 +0000219#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200220 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000221#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200222 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000223#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000224}
225
Trent Mick635f6fb2000-08-23 21:33:05 +0000226/* XXX This implementation is considered (to quote Tim Peters) "inherently
227 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000228 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200229 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100230 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000231*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200232unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000233PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 volatile pthread_t threadid;
236 if (!initialized)
237 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200239 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000240}
241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000243PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200246 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200248 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000249}
250
Martin v. Löwiscc898662002-03-17 09:53:51 +0000251#ifdef USE_SEMAPHORES
252
253/*
254 * Lock support.
255 */
256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000258PyThread_allocate_lock(void)
259{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 sem_t *lock;
261 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 dprintf(("PyThread_allocate_lock called\n"));
264 if (!initialized)
265 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000266
Victor Stinner80aa5652013-07-07 17:17:59 +0200267 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 if (lock) {
270 status = sem_init(lock,0,1);
271 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200274 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 lock = NULL;
276 }
277 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
280 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000281}
282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000284PyThread_free_lock(PyThread_type_lock lock)
285{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 sem_t *thelock = (sem_t *)lock;
287 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000288
Christian Heimes56379c02012-12-02 08:37:00 +0100289 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 if (!thelock)
293 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 status = sem_destroy(thelock);
296 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000297
Victor Stinner80aa5652013-07-07 17:17:59 +0200298 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000299}
300
301/*
302 * As of February 2002, Cygwin thread implementations mistakenly report error
303 * codes in the return value of the sem_ calls (like the pthread_ functions).
304 * Correct implementations return -1 and put the code in errno. This supports
305 * either.
306 */
307static int
308fix_status(int status)
309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000311}
312
Antoine Pitrou810023d2010-12-15 22:59:16 +0000313PyLockStatus
314PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
315 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000316{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000317 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 sem_t *thelock = (sem_t *)lock;
319 int status, error = 0;
320 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700321 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000322
Christian Heimes56379c02012-12-02 08:37:00 +0100323 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000324 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
325 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000326
Victor Stinner850a18e2017-10-24 16:53:32 -0700327 if (microseconds > PY_TIMEOUT_MAX) {
328 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
329 }
330
331 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700333
334 if (!intr_flag) {
335 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
336 check done above */
337 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
338 deadline = _PyTime_GetMonotonicClock() + timeout;
339 }
340 }
341
342 while (1) {
343 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700345 }
346 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700348 }
349 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700351 }
352
Antoine Pitrou810023d2010-12-15 22:59:16 +0000353 /* Retry if interrupted by a signal, unless the caller wants to be
354 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700355 if (intr_flag || status != EINTR) {
356 break;
357 }
358
359 if (microseconds > 0) {
360 /* wait interrupted by a signal (EINTR): recompute the timeout */
361 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
362 if (dt < 0) {
363 status = ETIMEDOUT;
364 break;
365 }
366 else if (dt > 0) {
367 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
368 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
369 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
370 check done above */
371 Py_UNREACHABLE();
372 }
373 /* no need to update microseconds value, the code only care
374 if (microseconds > 0 or (microseconds == 0). */
375 }
376 else {
377 microseconds = 0;
378 }
379 }
380 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000381
Antoine Pitrou810023d2010-12-15 22:59:16 +0000382 /* Don't check the status if we're stopping because of an interrupt. */
383 if (!(intr_flag && status == EINTR)) {
384 if (microseconds > 0) {
385 if (status != ETIMEDOUT)
386 CHECK_STATUS("sem_timedwait");
387 }
388 else if (microseconds == 0) {
389 if (status != EAGAIN)
390 CHECK_STATUS("sem_trywait");
391 }
392 else {
393 CHECK_STATUS("sem_wait");
394 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000396
Antoine Pitrou810023d2010-12-15 22:59:16 +0000397 if (status == 0) {
398 success = PY_LOCK_ACQUIRED;
399 } else if (intr_flag && status == EINTR) {
400 success = PY_LOCK_INTR;
401 } else {
402 success = PY_LOCK_FAILURE;
403 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404
Antoine Pitrou810023d2010-12-15 22:59:16 +0000405 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
406 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000408}
409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000411PyThread_release_lock(PyThread_type_lock lock)
412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 sem_t *thelock = (sem_t *)lock;
414 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000415
Christian Heimes56379c02012-12-02 08:37:00 +0100416 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000418
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 status = sem_post(thelock);
420 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000421}
422
423#else /* USE_SEMAPHORES */
424
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000425/*
426 * Lock support.
427 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000429PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 pthread_lock *lock;
432 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 dprintf(("PyThread_allocate_lock called\n"));
435 if (!initialized)
436 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000437
Victor Stinner80aa5652013-07-07 17:17:59 +0200438 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 if (lock) {
440 memset((void *)lock, '\0', sizeof(pthread_lock));
441 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 status = pthread_mutex_init(&lock->mut,
444 pthread_mutexattr_default);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100445 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 /* Mark the pthread mutex underlying a Python mutex as
447 pure happens-before. We can't simply mark the
448 Python-level mutex as a mutex because it can be
449 acquired and released in different threads, which
450 will cause errors. */
451 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 status = pthread_cond_init(&lock->lock_released,
454 pthread_condattr_default);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100455 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000456
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200458 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 lock = 0;
460 }
461 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
464 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000465}
466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000468PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 pthread_lock *thelock = (pthread_lock *)lock;
471 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000472
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200473 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000475
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000476 /* some pthread-like implementations tie the mutex to the cond
477 * and must have the cond destroyed first.
478 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100480 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000481
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000482 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100483 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000484
Victor Stinner80aa5652013-07-07 17:17:59 +0200485 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000486}
487
Antoine Pitrou810023d2010-12-15 22:59:16 +0000488PyLockStatus
489PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
490 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000491{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200492 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 pthread_lock *thelock = (pthread_lock *)lock;
494 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000495
Antoine Pitrou810023d2010-12-15 22:59:16 +0000496 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
497 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000498
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200499 if (microseconds == 0) {
500 status = pthread_mutex_trylock( &thelock->mut );
501 if (status != EBUSY)
502 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
503 }
504 else {
505 status = pthread_mutex_lock( &thelock->mut );
506 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
507 }
508 if (status == 0) {
509 if (thelock->locked == 0) {
510 success = PY_LOCK_ACQUIRED;
511 }
512 else if (microseconds != 0) {
513 struct timespec ts;
514 if (microseconds > 0)
515 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
516 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000517
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200518 /* mut must be locked by me -- part of the condition
519 * protocol */
520 while (success == PY_LOCK_FAILURE) {
521 if (microseconds > 0) {
522 status = pthread_cond_timedwait(
523 &thelock->lock_released,
524 &thelock->mut, &ts);
525 if (status == ETIMEDOUT)
526 break;
527 CHECK_STATUS_PTHREAD("pthread_cond_timed_wait");
528 }
529 else {
530 status = pthread_cond_wait(
531 &thelock->lock_released,
532 &thelock->mut);
533 CHECK_STATUS_PTHREAD("pthread_cond_wait");
534 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000535
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200536 if (intr_flag && status == 0 && thelock->locked) {
537 /* We were woken up, but didn't get the lock. We probably received
538 * a signal. Return PY_LOCK_INTR to allow the caller to handle
539 * it and retry. */
540 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200542 }
543 else if (status == 0 && !thelock->locked) {
544 success = PY_LOCK_ACQUIRED;
545 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000546 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200548 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
549 status = pthread_mutex_unlock( &thelock->mut );
550 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000552
Antoine Pitrou810023d2010-12-15 22:59:16 +0000553 if (error) success = PY_LOCK_FAILURE;
554 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
555 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000557}
558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000560PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 pthread_lock *thelock = (pthread_lock *)lock;
563 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000564
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200565 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100569 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 /* wake up someone (anyone, if any) waiting on the lock */
574 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100575 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000576
577 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100578 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000579}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000580
581#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000582
Antoine Pitrou810023d2010-12-15 22:59:16 +0000583int
584PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
585{
586 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
587}
588
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000589/* set the thread stack size.
590 * Return 0 if size is valid, -1 if size is invalid,
591 * -2 if setting stack size is not supported.
592 */
593static int
594_pythread_pthread_set_stacksize(size_t size)
595{
596#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 pthread_attr_t attrs;
598 size_t tss_min;
599 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000600#endif
601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 /* set to default */
603 if (size == 0) {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600604 PyThreadState_GET()->interp->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 return 0;
606 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000607
608#if defined(THREAD_STACK_SIZE)
609#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
611 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000612#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000614#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 if (size >= tss_min) {
616 /* validate stack size by setting thread attribute */
617 if (pthread_attr_init(&attrs) == 0) {
618 rc = pthread_attr_setstacksize(&attrs, size);
619 pthread_attr_destroy(&attrs);
620 if (rc == 0) {
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600621 PyThreadState_GET()->interp->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 return 0;
623 }
624 }
625 }
626 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000627#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000629#endif
630}
631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000633
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000634
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900635/* Thread Local Storage (TLS) API
636
637 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
638*/
639
640/* Issue #25658: On platforms where native TLS key is defined in a way that
641 cannot be safely cast to int, PyThread_create_key returns immediately a
642 failure status and other TLS functions all are no-ops. This indicates
643 clearly that the old API is not supported on platforms where it cannot be
644 used reliably, and that no effort will be made to add such support.
645
646 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
647 removing this API.
648*/
649
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000650int
651PyThread_create_key(void)
652{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900653#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000654 pthread_key_t key;
655 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200656 if (fail)
657 return -1;
658 if (key > INT_MAX) {
659 /* Issue #22206: handle integer overflow */
660 pthread_key_delete(key);
661 errno = ENOMEM;
662 return -1;
663 }
664 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900665#else
666 return -1; /* never return valid key value. */
667#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000668}
669
670void
671PyThread_delete_key(int key)
672{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900673#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000674 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900675#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000676}
677
678void
679PyThread_delete_key_value(int key)
680{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900681#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000682 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900683#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000684}
685
686int
687PyThread_set_key_value(int key, void *value)
688{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900689#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
690 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000691 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900692#else
693 return -1;
694#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000695}
696
697void *
698PyThread_get_key_value(int key)
699{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900700#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000701 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900702#else
703 return NULL;
704#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000705}
706
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900707
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000708void
709PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900710{
711}
712
713
714/* Thread Specific Storage (TSS) API
715
716 Platform-specific components of TSS API implementation.
717*/
718
719int
720PyThread_tss_create(Py_tss_t *key)
721{
722 assert(key != NULL);
723 /* If the key has been created, function is silently skipped. */
724 if (key->_is_initialized) {
725 return 0;
726 }
727
728 int fail = pthread_key_create(&(key->_key), NULL);
729 if (fail) {
730 return -1;
731 }
732 key->_is_initialized = 1;
733 return 0;
734}
735
736void
737PyThread_tss_delete(Py_tss_t *key)
738{
739 assert(key != NULL);
740 /* If the key has not been created, function is silently skipped. */
741 if (!key->_is_initialized) {
742 return;
743 }
744
745 pthread_key_delete(key->_key);
746 /* pthread has not provided the defined invalid value for the key. */
747 key->_is_initialized = 0;
748}
749
750int
751PyThread_tss_set(Py_tss_t *key, void *value)
752{
753 assert(key != NULL);
754 int fail = pthread_setspecific(key->_key, value);
755 return fail ? -1 : 0;
756}
757
758void *
759PyThread_tss_get(Py_tss_t *key)
760{
761 assert(key != NULL);
762 return pthread_getspecific(key->_key);
763}