blob: 35b9810aa377f25dfedf505400e5cba916d0423f [file] [log] [blame]
Victor Stinner4a3fe082020-04-14 14:26:24 +02001#include "pycore_interp.h" // _PyInterpreterState.pythread_stacksize
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00002
Guido van Rossum66020991996-06-11 18:32:18 +00003/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00004
Guido van Rossum66020991996-06-11 18:32:18 +00005#include <stdlib.h>
Guido van Rossum9e46e561998-10-07 16:39:47 +00006#include <string.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +00007#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +00008#define destructor xxdestructor
9#endif
Guido van Rossum66020991996-06-11 18:32:18 +000010#include <pthread.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +000011#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +000012#undef destructor
13#endif
Guido van Rossum80230992001-10-12 21:49:17 +000014#include <signal.h>
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000015
Jake Teslerb121f632019-05-22 08:43:17 -070016#if defined(__linux__)
17# include <sys/syscall.h> /* syscall(SYS_gettid) */
18#elif defined(__FreeBSD__)
19# include <pthread_np.h> /* pthread_getthreadid_np() */
David Carlier0b9956e2019-06-03 16:43:33 +010020#elif defined(__OpenBSD__)
21# include <unistd.h> /* getthrid() */
Michael Feltd0eeb932019-06-14 00:34:46 +020022#elif defined(_AIX)
23# include <sys/thread.h> /* thread_self() */
24#elif defined(__NetBSD__)
25# include <lwp.h> /* _lwp_self() */
Jake Teslerb121f632019-05-22 08:43:17 -070026#endif
27
Thomas Wouters0e3f5912006-08-11 14:57:12 +000028/* The POSIX spec requires that use of pthread_attr_setstacksize
29 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
30#ifdef _POSIX_THREAD_ATTR_STACKSIZE
31#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000032#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000033#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070034
Łukasz Langa2563dd22021-09-15 20:34:57 +020035/* The default stack size for new threads on BSD is small enough that
Ned Deily7ca97d52012-03-13 11:18:18 -070036 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
37 * exceptions.
38 *
Łukasz Langa2563dd22021-09-15 20:34:57 +020039 * The default stack size below is the empirically determined minimal stack
Ned Deily7ca97d52012-03-13 11:18:18 -070040 * sizes where a simple recursive function doesn't cause a hard crash.
Łukasz Langa2563dd22021-09-15 20:34:57 +020041 *
42 * For macOS the value of THREAD_STACK_SIZE is determined in configure.ac
43 * as it also depends on the other configure options like chosen sanitizer
44 * runtimes.
Ned Deily7ca97d52012-03-13 11:18:18 -070045 */
Ned Deily7ca97d52012-03-13 11:18:18 -070046#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070047#undef THREAD_STACK_SIZE
48#define THREAD_STACK_SIZE 0x400000
49#endif
Michael Felt9670ce72019-08-03 08:12:26 +020050#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
51#undef THREAD_STACK_SIZE
52#define THREAD_STACK_SIZE 0x200000
53#endif
xdegaye00ada2c2019-12-08 08:40:14 +010054/* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive
55 Python calls (default recursion limit) doesn't crash, but raise a regular
56 RecursionError exception. In debug mode, Python function calls allocates
57 more memory on the stack, so use a stack of 8 MiB. */
58#if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
59# ifdef Py_DEBUG
60# undef THREAD_STACK_SIZE
61# define THREAD_STACK_SIZE 0x800000
62# endif
63#endif
pxinwrd5dcb652020-12-10 05:47:28 +080064#if defined(__VXWORKS__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
65#undef THREAD_STACK_SIZE
66#define THREAD_STACK_SIZE 0x100000
67#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080069#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
71#ifdef THREAD_STACK_SIZE
72#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
73#endif
74#endif
75
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000076/* The POSIX spec says that implementations supporting the sem_*
77 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000079#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000081 we need to add 0 to make it work there as well. */
82#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000083#define HAVE_BROKEN_POSIX_SEMAPHORES
84#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000085#include <semaphore.h>
86#include <errno.h>
87#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000088#endif
Guido van Rossum66020991996-06-11 18:32:18 +000089
Guido van Rossumd6353e21997-05-13 17:51:13 +000090
Martin v. Löwiscc898662002-03-17 09:53:51 +000091/* Whether or not to use semaphores directly rather than emulating them with
92 * mutexes and condition variables:
93 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000094#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
Victor Stinner6df8c322021-10-01 18:22:49 +020095 (defined(HAVE_SEM_TIMEDWAIT) || defined(HAVE_SEM_CLOCKWAIT)))
Martin v. Löwiscc898662002-03-17 09:53:51 +000096# define USE_SEMAPHORES
97#else
98# undef USE_SEMAPHORES
99#endif
100
Victor Stinner6df8c322021-10-01 18:22:49 +0200101#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
102// monotonic is supported statically. It doesn't mean it works on runtime.
103#define CONDATTR_MONOTONIC
104#endif
105
Martin v. Löwiscc898662002-03-17 09:53:51 +0000106
Guido van Rossum80230992001-10-12 21:49:17 +0000107/* On platforms that don't use standard POSIX threads pthread_sigmask()
108 * isn't present. DEC threads uses sigprocmask() instead as do most
109 * other UNIX International compliant systems that don't have the full
110 * pthread implementation.
111 */
Jason Tishlerfac083d2003-07-22 15:20:49 +0000112#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +0000113# define SET_THREAD_SIGMASK pthread_sigmask
114#else
115# define SET_THREAD_SIGMASK sigprocmask
116#endif
117
118
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000119#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
120do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 struct timeval tv; \
Benjamin Petersonf1c19032019-09-10 11:37:59 +0100122 gettimeofday(&tv, NULL); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 tv.tv_usec += microseconds % 1000000; \
124 tv.tv_sec += microseconds / 1000000; \
125 tv.tv_sec += tv.tv_usec / 1000000; \
126 tv.tv_usec %= 1000000; \
127 ts.tv_sec = tv.tv_sec; \
128 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000129} while(0)
130
Victor Stinner6df8c322021-10-01 18:22:49 +0200131#if defined(CONDATTR_MONOTONIC) || defined(HAVE_SEM_CLOCKWAIT)
132static void
133monotonic_abs_timeout(long long us, struct timespec *abs)
134{
135 clock_gettime(CLOCK_MONOTONIC, abs);
136 abs->tv_sec += us / 1000000;
137 abs->tv_nsec += (us % 1000000) * 1000;
138 abs->tv_sec += abs->tv_nsec / 1000000000;
139 abs->tv_nsec %= 1000000000;
140}
141#endif
142
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000143
Inada Naoki001fee12019-02-20 10:00:09 +0900144/*
145 * pthread_cond support
146 */
147
Inada Naoki001fee12019-02-20 10:00:09 +0900148// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
149static pthread_condattr_t *condattr_monotonic = NULL;
150
151static void
Benjamin Petersonea62a4b2020-07-15 06:12:05 -0700152init_condattr(void)
Inada Naoki001fee12019-02-20 10:00:09 +0900153{
154#ifdef CONDATTR_MONOTONIC
155 static pthread_condattr_t ca;
156 pthread_condattr_init(&ca);
157 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
158 condattr_monotonic = &ca; // Use monotonic clock
159 }
160#endif
161}
162
163int
164_PyThread_cond_init(PyCOND_T *cond)
165{
166 return pthread_cond_init(cond, condattr_monotonic);
167}
168
Victor Stinner6df8c322021-10-01 18:22:49 +0200169
Inada Naoki001fee12019-02-20 10:00:09 +0900170void
171_PyThread_cond_after(long long us, struct timespec *abs)
172{
173#ifdef CONDATTR_MONOTONIC
174 if (condattr_monotonic) {
Victor Stinner6df8c322021-10-01 18:22:49 +0200175 monotonic_abs_timeout(us, abs);
Inada Naoki001fee12019-02-20 10:00:09 +0900176 return;
177 }
178#endif
179
180 struct timespec ts;
181 MICROSECONDS_TO_TIMESPEC(us, ts);
182 *abs = ts;
183}
184
185
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000186/* A pthread mutex isn't sufficient to model the Python lock type
187 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
188 * following are undefined:
189 * -> a thread tries to lock a mutex it already has locked
190 * -> a thread tries to unlock a mutex locked by a different thread
191 * pthread mutexes are designed for serializing threads over short pieces
192 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000193 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000194 *
195 * The pthread_lock struct implements a Python lock as a "locked?" bit
196 * and a <condition, mutex> pair. In general, if the bit can be acquired
197 * instantly, it is, else the pair is used to block the thread until the
198 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000199 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000200
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000201typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 char locked; /* 0=unlocked, 1=locked */
203 /* a <cond, mutex> pair to handle an acquire of a locked lock */
204 pthread_cond_t lock_released;
205 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000206} pthread_lock;
207
Guido van Rossum9e46e561998-10-07 16:39:47 +0000208#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100209#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
210 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000211
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000212/*
213 * Initialization.
214 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000215static void
216PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000217{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000218#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200219 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000221#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900222 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000223}
224
225/*
226 * Thread support.
227 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000228
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530229/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
230 "void func(void *)" to "void* func(void *)": always return NULL.
231
232 PyThread_start_new_thread() uses "void func(void *)" type, whereas
233 pthread_create() requires a void* return value. */
234typedef struct {
235 void (*func) (void *);
236 void *arg;
237} pythread_callback;
238
239static void *
240pythread_wrapper(void *arg)
241{
242 /* copy func and func_arg and free the temporary structure */
243 pythread_callback *callback = arg;
244 void (*func)(void *) = callback->func;
245 void *func_arg = callback->arg;
246 PyMem_RawFree(arg);
247
248 func(func_arg);
249 return NULL;
250}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000251
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200252unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000253PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 pthread_t th;
256 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000257#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000259#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000262#endif
263
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 dprintf(("PyThread_start_new_thread called\n"));
265 if (!initialized)
266 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000267
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000268#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200270 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000271#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000272#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100273 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600274 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
275 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 if (tss != 0) {
277 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
278 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200279 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 }
281 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000282#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000283#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000285#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000286
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530287 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
288
289 if (callback == NULL) {
290 return PYTHREAD_INVALID_THREAD_ID;
291 }
292
293 callback->func = func;
294 callback->arg = arg;
295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000297#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000299#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000301#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530302 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000303
Fred Drake03459a52001-11-09 16:00:41 +0000304#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000306#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530307
308 if (status != 0) {
309 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200310 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530311 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000314
Guido van Rossum3c288632001-10-16 21:13:49 +0000315#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200316 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000317#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200318 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000319#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000320}
321
Trent Mick635f6fb2000-08-23 21:33:05 +0000322/* XXX This implementation is considered (to quote Tim Peters) "inherently
323 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000324 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200325 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100326 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000327*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200328unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000329PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 volatile pthread_t threadid;
332 if (!initialized)
333 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200335 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000336}
337
Jake Teslerb121f632019-05-22 08:43:17 -0700338#ifdef PY_HAVE_THREAD_NATIVE_ID
339unsigned long
340PyThread_get_thread_native_id(void)
341{
342 if (!initialized)
343 PyThread_init_thread();
344#ifdef __APPLE__
345 uint64_t native_id;
346 (void) pthread_threadid_np(NULL, &native_id);
347#elif defined(__linux__)
348 pid_t native_id;
349 native_id = syscall(SYS_gettid);
350#elif defined(__FreeBSD__)
351 int native_id;
352 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100353#elif defined(__OpenBSD__)
354 pid_t native_id;
355 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200356#elif defined(_AIX)
357 tid_t native_id;
358 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000359#elif defined(__NetBSD__)
360 lwpid_t native_id;
361 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700362#endif
363 return (unsigned long) native_id;
364}
365#endif
366
Victor Stinnerc664b342019-05-04 11:48:05 -0400367void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000368PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000369{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200371 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200373 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000374}
375
Martin v. Löwiscc898662002-03-17 09:53:51 +0000376#ifdef USE_SEMAPHORES
377
378/*
379 * Lock support.
380 */
381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000383PyThread_allocate_lock(void)
384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 sem_t *lock;
386 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 dprintf(("PyThread_allocate_lock called\n"));
389 if (!initialized)
390 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000391
Victor Stinner80aa5652013-07-07 17:17:59 +0200392 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 if (lock) {
395 status = sem_init(lock,0,1);
396 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200399 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 lock = NULL;
401 }
402 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000403
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600404 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000406}
407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000409PyThread_free_lock(PyThread_type_lock lock)
410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 sem_t *thelock = (sem_t *)lock;
412 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000413
Christian Heimes56379c02012-12-02 08:37:00 +0100414 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 if (!thelock)
418 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 status = sem_destroy(thelock);
421 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000422
Victor Stinner80aa5652013-07-07 17:17:59 +0200423 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000424}
425
426/*
427 * As of February 2002, Cygwin thread implementations mistakenly report error
428 * codes in the return value of the sem_ calls (like the pthread_ functions).
429 * Correct implementations return -1 and put the code in errno. This supports
430 * either.
431 */
432static int
433fix_status(int status)
434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000436}
437
Antoine Pitrou810023d2010-12-15 22:59:16 +0000438PyLockStatus
439PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
440 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000441{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000442 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 sem_t *thelock = (sem_t *)lock;
444 int status, error = 0;
445 struct timespec ts;
Victor Stinner6df8c322021-10-01 18:22:49 +0200446#ifndef HAVE_SEM_CLOCKWAIT
Victor Stinner850a18e2017-10-24 16:53:32 -0700447 _PyTime_t deadline = 0;
Victor Stinner6df8c322021-10-01 18:22:49 +0200448#endif
Martin v. Löwiscc898662002-03-17 09:53:51 +0000449
Christian Heimes56379c02012-12-02 08:37:00 +0100450 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000451 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
452 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000453
Victor Stinner850a18e2017-10-24 16:53:32 -0700454 if (microseconds > PY_TIMEOUT_MAX) {
455 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
456 }
457
458 if (microseconds > 0) {
Victor Stinner6df8c322021-10-01 18:22:49 +0200459#ifdef HAVE_SEM_CLOCKWAIT
460 monotonic_abs_timeout(microseconds, &ts);
461#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700463
464 if (!intr_flag) {
465 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
466 check done above */
467 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
468 deadline = _PyTime_GetMonotonicClock() + timeout;
469 }
Victor Stinner6df8c322021-10-01 18:22:49 +0200470#endif
Victor Stinner850a18e2017-10-24 16:53:32 -0700471 }
472
473 while (1) {
474 if (microseconds > 0) {
Victor Stinner6df8c322021-10-01 18:22:49 +0200475#ifdef HAVE_SEM_CLOCKWAIT
476 status = fix_status(sem_clockwait(thelock, CLOCK_MONOTONIC,
477 &ts));
478#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner6df8c322021-10-01 18:22:49 +0200480#endif
Victor Stinner850a18e2017-10-24 16:53:32 -0700481 }
482 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700484 }
485 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700487 }
488
Antoine Pitrou810023d2010-12-15 22:59:16 +0000489 /* Retry if interrupted by a signal, unless the caller wants to be
490 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700491 if (intr_flag || status != EINTR) {
492 break;
493 }
494
Victor Stinner6df8c322021-10-01 18:22:49 +0200495 // sem_clockwait() uses an absolute timeout, there is no need
496 // to recompute the relative timeout.
497#ifndef HAVE_SEM_CLOCKWAIT
Victor Stinner850a18e2017-10-24 16:53:32 -0700498 if (microseconds > 0) {
499 /* wait interrupted by a signal (EINTR): recompute the timeout */
500 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
501 if (dt < 0) {
502 status = ETIMEDOUT;
503 break;
504 }
505 else if (dt > 0) {
506 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
507 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
508 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
509 check done above */
510 Py_UNREACHABLE();
511 }
512 /* no need to update microseconds value, the code only care
513 if (microseconds > 0 or (microseconds == 0). */
514 }
515 else {
516 microseconds = 0;
517 }
518 }
Victor Stinner6df8c322021-10-01 18:22:49 +0200519#endif
Victor Stinner850a18e2017-10-24 16:53:32 -0700520 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000521
Antoine Pitrou810023d2010-12-15 22:59:16 +0000522 /* Don't check the status if we're stopping because of an interrupt. */
523 if (!(intr_flag && status == EINTR)) {
524 if (microseconds > 0) {
Victor Stinner6df8c322021-10-01 18:22:49 +0200525 if (status != ETIMEDOUT) {
526#ifdef HAVE_SEM_CLOCKWAIT
527 CHECK_STATUS("sem_clockwait");
528#else
Antoine Pitrou810023d2010-12-15 22:59:16 +0000529 CHECK_STATUS("sem_timedwait");
Victor Stinner6df8c322021-10-01 18:22:49 +0200530#endif
531 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000532 }
533 else if (microseconds == 0) {
534 if (status != EAGAIN)
535 CHECK_STATUS("sem_trywait");
536 }
537 else {
538 CHECK_STATUS("sem_wait");
539 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000541
Antoine Pitrou810023d2010-12-15 22:59:16 +0000542 if (status == 0) {
543 success = PY_LOCK_ACQUIRED;
544 } else if (intr_flag && status == EINTR) {
545 success = PY_LOCK_INTR;
546 } else {
547 success = PY_LOCK_FAILURE;
548 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549
Antoine Pitrou810023d2010-12-15 22:59:16 +0000550 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
551 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000553}
554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000556PyThread_release_lock(PyThread_type_lock lock)
557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 sem_t *thelock = (sem_t *)lock;
559 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000560
Christian Heimes56379c02012-12-02 08:37:00 +0100561 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 status = sem_post(thelock);
565 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000566}
567
568#else /* USE_SEMAPHORES */
569
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000570/*
571 * Lock support.
572 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000574PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 pthread_lock *lock;
577 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 dprintf(("PyThread_allocate_lock called\n"));
580 if (!initialized)
581 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000582
Andy Lester7668a8b2020-03-24 23:26:44 -0500583 lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 if (lock) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000586
Inada Naoki001fee12019-02-20 10:00:09 +0900587 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100588 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 /* Mark the pthread mutex underlying a Python mutex as
590 pure happens-before. We can't simply mark the
591 Python-level mutex as a mutex because it can be
592 acquired and released in different threads, which
593 will cause errors. */
594 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000595
Inada Naoki001fee12019-02-20 10:00:09 +0900596 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100597 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000598
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200600 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 lock = 0;
602 }
603 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000604
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600605 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000607}
608
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000610PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 pthread_lock *thelock = (pthread_lock *)lock;
613 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000614
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200615 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000617
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000618 /* some pthread-like implementations tie the mutex to the cond
619 * and must have the cond destroyed first.
620 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100622 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000623
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000624 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100625 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000626
Victor Stinner80aa5652013-07-07 17:17:59 +0200627 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000628}
629
Antoine Pitrou810023d2010-12-15 22:59:16 +0000630PyLockStatus
631PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
632 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000633{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200634 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 pthread_lock *thelock = (pthread_lock *)lock;
636 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000637
Antoine Pitrou810023d2010-12-15 22:59:16 +0000638 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
639 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000640
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200641 if (microseconds == 0) {
642 status = pthread_mutex_trylock( &thelock->mut );
643 if (status != EBUSY)
644 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
645 }
646 else {
647 status = pthread_mutex_lock( &thelock->mut );
648 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
649 }
650 if (status == 0) {
651 if (thelock->locked == 0) {
652 success = PY_LOCK_ACQUIRED;
653 }
654 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900655 struct timespec abs;
656 if (microseconds > 0) {
657 _PyThread_cond_after(microseconds, &abs);
658 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200659 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000660
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200661 /* mut must be locked by me -- part of the condition
662 * protocol */
663 while (success == PY_LOCK_FAILURE) {
664 if (microseconds > 0) {
665 status = pthread_cond_timedwait(
666 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900667 &thelock->mut, &abs);
668 if (status == 1) {
669 break;
670 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200671 if (status == ETIMEDOUT)
672 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900673 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200674 }
675 else {
676 status = pthread_cond_wait(
677 &thelock->lock_released,
678 &thelock->mut);
679 CHECK_STATUS_PTHREAD("pthread_cond_wait");
680 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000681
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200682 if (intr_flag && status == 0 && thelock->locked) {
683 /* We were woken up, but didn't get the lock. We probably received
684 * a signal. Return PY_LOCK_INTR to allow the caller to handle
685 * it and retry. */
686 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200688 }
689 else if (status == 0 && !thelock->locked) {
690 success = PY_LOCK_ACQUIRED;
691 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000692 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200694 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
695 status = pthread_mutex_unlock( &thelock->mut );
696 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000698
Antoine Pitrou810023d2010-12-15 22:59:16 +0000699 if (error) success = PY_LOCK_FAILURE;
700 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
701 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000703}
704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000706PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 pthread_lock *thelock = (pthread_lock *)lock;
709 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000710
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200711 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000713
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100715 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 /* wake up someone (anyone, if any) waiting on the lock */
720 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100721 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000722
723 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100724 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000725}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000726
727#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000728
Antoine Pitrou810023d2010-12-15 22:59:16 +0000729int
Victor Stinner87255be2020-04-07 23:11:49 +0200730_PyThread_at_fork_reinit(PyThread_type_lock *lock)
731{
732 PyThread_type_lock new_lock = PyThread_allocate_lock();
733 if (new_lock == NULL) {
734 return -1;
735 }
736
737 /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
738 fork() can be called in the middle of an operation on the lock done by
739 another thread. So don't call PyThread_free_lock(*lock).
740
741 Leak memory on purpose. Don't release the memory either since the
742 address of a mutex is relevant. Putting two mutexes at the same address
743 can lead to problems. */
744
745 *lock = new_lock;
746 return 0;
747}
748
749int
Antoine Pitrou810023d2010-12-15 22:59:16 +0000750PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
751{
752 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
753}
754
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000755/* set the thread stack size.
756 * Return 0 if size is valid, -1 if size is invalid,
757 * -2 if setting stack size is not supported.
758 */
759static int
760_pythread_pthread_set_stacksize(size_t size)
761{
762#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 pthread_attr_t attrs;
764 size_t tss_min;
765 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000766#endif
767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 /* set to default */
769 if (size == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200770 _PyInterpreterState_GET()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 return 0;
772 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000773
774#if defined(THREAD_STACK_SIZE)
775#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
777 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000778#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000780#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 if (size >= tss_min) {
782 /* validate stack size by setting thread attribute */
783 if (pthread_attr_init(&attrs) == 0) {
784 rc = pthread_attr_setstacksize(&attrs, size);
785 pthread_attr_destroy(&attrs);
786 if (rc == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200787 _PyInterpreterState_GET()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000788 return 0;
789 }
790 }
791 }
792 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000793#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000794 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000795#endif
796}
797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000799
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000800
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900801/* Thread Local Storage (TLS) API
802
803 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
804*/
805
806/* Issue #25658: On platforms where native TLS key is defined in a way that
807 cannot be safely cast to int, PyThread_create_key returns immediately a
808 failure status and other TLS functions all are no-ops. This indicates
809 clearly that the old API is not supported on platforms where it cannot be
810 used reliably, and that no effort will be made to add such support.
811
812 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
813 removing this API.
814*/
815
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000816int
817PyThread_create_key(void)
818{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900819#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000820 pthread_key_t key;
821 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200822 if (fail)
823 return -1;
824 if (key > INT_MAX) {
825 /* Issue #22206: handle integer overflow */
826 pthread_key_delete(key);
827 errno = ENOMEM;
828 return -1;
829 }
830 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900831#else
832 return -1; /* never return valid key value. */
833#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000834}
835
836void
837PyThread_delete_key(int key)
838{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900839#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000840 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900841#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000842}
843
844void
845PyThread_delete_key_value(int key)
846{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900847#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000848 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900849#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000850}
851
852int
853PyThread_set_key_value(int key, void *value)
854{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900855#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
856 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000857 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900858#else
859 return -1;
860#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000861}
862
863void *
864PyThread_get_key_value(int key)
865{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900866#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000867 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900868#else
869 return NULL;
870#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000871}
872
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900873
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000874void
875PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900876{
877}
878
879
880/* Thread Specific Storage (TSS) API
881
882 Platform-specific components of TSS API implementation.
883*/
884
885int
886PyThread_tss_create(Py_tss_t *key)
887{
888 assert(key != NULL);
889 /* If the key has been created, function is silently skipped. */
890 if (key->_is_initialized) {
891 return 0;
892 }
893
894 int fail = pthread_key_create(&(key->_key), NULL);
895 if (fail) {
896 return -1;
897 }
898 key->_is_initialized = 1;
899 return 0;
900}
901
902void
903PyThread_tss_delete(Py_tss_t *key)
904{
905 assert(key != NULL);
906 /* If the key has not been created, function is silently skipped. */
907 if (!key->_is_initialized) {
908 return;
909 }
910
911 pthread_key_delete(key->_key);
912 /* pthread has not provided the defined invalid value for the key. */
913 key->_is_initialized = 0;
914}
915
916int
917PyThread_tss_set(Py_tss_t *key, void *value)
918{
919 assert(key != NULL);
920 int fail = pthread_setspecific(key->_key, value);
921 return fail ? -1 : 0;
922}
923
924void *
925PyThread_tss_get(Py_tss_t *key)
926{
927 assert(key != NULL);
928 return pthread_getspecific(key->_key);
929}