blob: cf4e854d829cb5faa08e5849b1930f8c2dd8ade1 [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
Ned Deily7ca97d52012-03-13 11:18:18 -070035/* The default stack size for new threads on OSX and BSD is small enough that
36 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
37 * exceptions.
38 *
39 * The default stack sizes below are the empirically determined minimal stack
40 * sizes where a simple recursive function doesn't cause a hard crash.
41 */
42#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
43#undef THREAD_STACK_SIZE
Ronald Oussoren1a057ba2019-08-01 07:43:07 +020044/* Note: This matches the value of -Wl,-stack_size in configure.ac */
45#define THREAD_STACK_SIZE 0x1000000
Ned Deily7ca97d52012-03-13 11:18:18 -070046#endif
47#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070048#undef THREAD_STACK_SIZE
49#define THREAD_STACK_SIZE 0x400000
50#endif
Michael Felt9670ce72019-08-03 08:12:26 +020051#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
52#undef THREAD_STACK_SIZE
53#define THREAD_STACK_SIZE 0x200000
54#endif
xdegaye00ada2c2019-12-08 08:40:14 +010055/* bpo-38852: test_threading.test_recursion_limit() checks that 1000 recursive
56 Python calls (default recursion limit) doesn't crash, but raise a regular
57 RecursionError exception. In debug mode, Python function calls allocates
58 more memory on the stack, so use a stack of 8 MiB. */
59#if defined(__ANDROID__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
60# ifdef Py_DEBUG
61# undef THREAD_STACK_SIZE
62# define THREAD_STACK_SIZE 0x800000
63# endif
64#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080066#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000067#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
68#ifdef THREAD_STACK_SIZE
69#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
70#endif
71#endif
72
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000073/* The POSIX spec says that implementations supporting the sem_*
74 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000076#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000078 we need to add 0 to make it work there as well. */
79#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000080#define HAVE_BROKEN_POSIX_SEMAPHORES
81#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000082#include <semaphore.h>
83#include <errno.h>
84#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000085#endif
Guido van Rossum66020991996-06-11 18:32:18 +000086
Guido van Rossumd6353e21997-05-13 17:51:13 +000087
Martin v. Löwiscc898662002-03-17 09:53:51 +000088/* Whether or not to use semaphores directly rather than emulating them with
89 * mutexes and condition variables:
90 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000091#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
92 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000093# define USE_SEMAPHORES
94#else
95# undef USE_SEMAPHORES
96#endif
97
98
Guido van Rossum80230992001-10-12 21:49:17 +000099/* On platforms that don't use standard POSIX threads pthread_sigmask()
100 * isn't present. DEC threads uses sigprocmask() instead as do most
101 * other UNIX International compliant systems that don't have the full
102 * pthread implementation.
103 */
Jason Tishlerfac083d2003-07-22 15:20:49 +0000104#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +0000105# define SET_THREAD_SIGMASK pthread_sigmask
106#else
107# define SET_THREAD_SIGMASK sigprocmask
108#endif
109
110
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000111#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
112do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 struct timeval tv; \
Benjamin Petersonf1c19032019-09-10 11:37:59 +0100114 gettimeofday(&tv, NULL); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 tv.tv_usec += microseconds % 1000000; \
116 tv.tv_sec += microseconds / 1000000; \
117 tv.tv_sec += tv.tv_usec / 1000000; \
118 tv.tv_usec %= 1000000; \
119 ts.tv_sec = tv.tv_sec; \
120 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000121} while(0)
122
123
Inada Naoki001fee12019-02-20 10:00:09 +0900124/*
125 * pthread_cond support
126 */
127
128#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
129// monotonic is supported statically. It doesn't mean it works on runtime.
130#define CONDATTR_MONOTONIC
131#endif
132
133// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
134static pthread_condattr_t *condattr_monotonic = NULL;
135
136static void
137init_condattr()
138{
139#ifdef CONDATTR_MONOTONIC
140 static pthread_condattr_t ca;
141 pthread_condattr_init(&ca);
142 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
143 condattr_monotonic = &ca; // Use monotonic clock
144 }
145#endif
146}
147
148int
149_PyThread_cond_init(PyCOND_T *cond)
150{
151 return pthread_cond_init(cond, condattr_monotonic);
152}
153
154void
155_PyThread_cond_after(long long us, struct timespec *abs)
156{
157#ifdef CONDATTR_MONOTONIC
158 if (condattr_monotonic) {
159 clock_gettime(CLOCK_MONOTONIC, abs);
160 abs->tv_sec += us / 1000000;
161 abs->tv_nsec += (us % 1000000) * 1000;
162 abs->tv_sec += abs->tv_nsec / 1000000000;
163 abs->tv_nsec %= 1000000000;
164 return;
165 }
166#endif
167
168 struct timespec ts;
169 MICROSECONDS_TO_TIMESPEC(us, ts);
170 *abs = ts;
171}
172
173
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000174/* A pthread mutex isn't sufficient to model the Python lock type
175 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
176 * following are undefined:
177 * -> a thread tries to lock a mutex it already has locked
178 * -> a thread tries to unlock a mutex locked by a different thread
179 * pthread mutexes are designed for serializing threads over short pieces
180 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000181 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000182 *
183 * The pthread_lock struct implements a Python lock as a "locked?" bit
184 * and a <condition, mutex> pair. In general, if the bit can be acquired
185 * instantly, it is, else the pair is used to block the thread until the
186 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000187 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000188
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000189typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 char locked; /* 0=unlocked, 1=locked */
191 /* a <cond, mutex> pair to handle an acquire of a locked lock */
192 pthread_cond_t lock_released;
193 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000194} pthread_lock;
195
Guido van Rossum9e46e561998-10-07 16:39:47 +0000196#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100197#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
198 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000199
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000200/*
201 * Initialization.
202 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000203static void
204PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000205{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000206#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200207 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000209#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900210 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000211}
212
213/*
214 * Thread support.
215 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000216
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530217/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
218 "void func(void *)" to "void* func(void *)": always return NULL.
219
220 PyThread_start_new_thread() uses "void func(void *)" type, whereas
221 pthread_create() requires a void* return value. */
222typedef struct {
223 void (*func) (void *);
224 void *arg;
225} pythread_callback;
226
227static void *
228pythread_wrapper(void *arg)
229{
230 /* copy func and func_arg and free the temporary structure */
231 pythread_callback *callback = arg;
232 void (*func)(void *) = callback->func;
233 void *func_arg = callback->arg;
234 PyMem_RawFree(arg);
235
236 func(func_arg);
237 return NULL;
238}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000239
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200240unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000241PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 pthread_t th;
244 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000245#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000247#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000248#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000250#endif
251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 dprintf(("PyThread_start_new_thread called\n"));
253 if (!initialized)
254 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000255
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000256#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200258 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000259#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100261 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600262 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
263 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 if (tss != 0) {
265 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
266 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200267 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 }
269 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000270#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000271#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000273#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000274
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530275 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
276
277 if (callback == NULL) {
278 return PYTHREAD_INVALID_THREAD_ID;
279 }
280
281 callback->func = func;
282 callback->arg = arg;
283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000285#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000287#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000289#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530290 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000291
Fred Drake03459a52001-11-09 16:00:41 +0000292#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000294#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530295
296 if (status != 0) {
297 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200298 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530299 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000302
Guido van Rossum3c288632001-10-16 21:13:49 +0000303#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200304 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000305#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200306 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000307#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000308}
309
Trent Mick635f6fb2000-08-23 21:33:05 +0000310/* XXX This implementation is considered (to quote Tim Peters) "inherently
311 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000312 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200313 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100314 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000315*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200316unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000317PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 volatile pthread_t threadid;
320 if (!initialized)
321 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200323 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000324}
325
Jake Teslerb121f632019-05-22 08:43:17 -0700326#ifdef PY_HAVE_THREAD_NATIVE_ID
327unsigned long
328PyThread_get_thread_native_id(void)
329{
330 if (!initialized)
331 PyThread_init_thread();
332#ifdef __APPLE__
333 uint64_t native_id;
334 (void) pthread_threadid_np(NULL, &native_id);
335#elif defined(__linux__)
336 pid_t native_id;
337 native_id = syscall(SYS_gettid);
338#elif defined(__FreeBSD__)
339 int native_id;
340 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100341#elif defined(__OpenBSD__)
342 pid_t native_id;
343 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200344#elif defined(_AIX)
345 tid_t native_id;
346 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000347#elif defined(__NetBSD__)
348 lwpid_t native_id;
349 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700350#endif
351 return (unsigned long) native_id;
352}
353#endif
354
Victor Stinnerc664b342019-05-04 11:48:05 -0400355void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000356PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200359 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200361 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000362}
363
Martin v. Löwiscc898662002-03-17 09:53:51 +0000364#ifdef USE_SEMAPHORES
365
366/*
367 * Lock support.
368 */
369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000371PyThread_allocate_lock(void)
372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 sem_t *lock;
374 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 dprintf(("PyThread_allocate_lock called\n"));
377 if (!initialized)
378 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000379
Victor Stinner80aa5652013-07-07 17:17:59 +0200380 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (lock) {
383 status = sem_init(lock,0,1);
384 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200387 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 lock = NULL;
389 }
390 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000391
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600392 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000394}
395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000397PyThread_free_lock(PyThread_type_lock lock)
398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 sem_t *thelock = (sem_t *)lock;
400 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000401
Christian Heimes56379c02012-12-02 08:37:00 +0100402 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 if (!thelock)
406 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 status = sem_destroy(thelock);
409 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000410
Victor Stinner80aa5652013-07-07 17:17:59 +0200411 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000412}
413
414/*
415 * As of February 2002, Cygwin thread implementations mistakenly report error
416 * codes in the return value of the sem_ calls (like the pthread_ functions).
417 * Correct implementations return -1 and put the code in errno. This supports
418 * either.
419 */
420static int
421fix_status(int status)
422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000424}
425
Antoine Pitrou810023d2010-12-15 22:59:16 +0000426PyLockStatus
427PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
428 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000429{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000430 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 sem_t *thelock = (sem_t *)lock;
432 int status, error = 0;
433 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700434 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000435
Christian Heimes56379c02012-12-02 08:37:00 +0100436 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000437 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
438 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000439
Victor Stinner850a18e2017-10-24 16:53:32 -0700440 if (microseconds > PY_TIMEOUT_MAX) {
441 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
442 }
443
444 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700446
447 if (!intr_flag) {
448 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
449 check done above */
450 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
451 deadline = _PyTime_GetMonotonicClock() + timeout;
452 }
453 }
454
455 while (1) {
456 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700458 }
459 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700461 }
462 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700464 }
465
Antoine Pitrou810023d2010-12-15 22:59:16 +0000466 /* Retry if interrupted by a signal, unless the caller wants to be
467 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700468 if (intr_flag || status != EINTR) {
469 break;
470 }
471
472 if (microseconds > 0) {
473 /* wait interrupted by a signal (EINTR): recompute the timeout */
474 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
475 if (dt < 0) {
476 status = ETIMEDOUT;
477 break;
478 }
479 else if (dt > 0) {
480 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
481 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
482 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
483 check done above */
484 Py_UNREACHABLE();
485 }
486 /* no need to update microseconds value, the code only care
487 if (microseconds > 0 or (microseconds == 0). */
488 }
489 else {
490 microseconds = 0;
491 }
492 }
493 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000494
Antoine Pitrou810023d2010-12-15 22:59:16 +0000495 /* Don't check the status if we're stopping because of an interrupt. */
496 if (!(intr_flag && status == EINTR)) {
497 if (microseconds > 0) {
498 if (status != ETIMEDOUT)
499 CHECK_STATUS("sem_timedwait");
500 }
501 else if (microseconds == 0) {
502 if (status != EAGAIN)
503 CHECK_STATUS("sem_trywait");
504 }
505 else {
506 CHECK_STATUS("sem_wait");
507 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000509
Antoine Pitrou810023d2010-12-15 22:59:16 +0000510 if (status == 0) {
511 success = PY_LOCK_ACQUIRED;
512 } else if (intr_flag && status == EINTR) {
513 success = PY_LOCK_INTR;
514 } else {
515 success = PY_LOCK_FAILURE;
516 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517
Antoine Pitrou810023d2010-12-15 22:59:16 +0000518 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
519 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000521}
522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000524PyThread_release_lock(PyThread_type_lock lock)
525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 sem_t *thelock = (sem_t *)lock;
527 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000528
Christian Heimes56379c02012-12-02 08:37:00 +0100529 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 status = sem_post(thelock);
533 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000534}
535
536#else /* USE_SEMAPHORES */
537
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000538/*
539 * Lock support.
540 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000542PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 pthread_lock *lock;
545 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 dprintf(("PyThread_allocate_lock called\n"));
548 if (!initialized)
549 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000550
Andy Lester7668a8b2020-03-24 23:26:44 -0500551 lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 if (lock) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000553 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000554
Inada Naoki001fee12019-02-20 10:00:09 +0900555 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100556 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 /* Mark the pthread mutex underlying a Python mutex as
558 pure happens-before. We can't simply mark the
559 Python-level mutex as a mutex because it can be
560 acquired and released in different threads, which
561 will cause errors. */
562 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000563
Inada Naoki001fee12019-02-20 10:00:09 +0900564 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100565 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200568 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 lock = 0;
570 }
571 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000572
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600573 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000575}
576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000578PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000579{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 pthread_lock *thelock = (pthread_lock *)lock;
581 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000582
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200583 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000585
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000586 /* some pthread-like implementations tie the mutex to the cond
587 * and must have the cond destroyed first.
588 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100590 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000591
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000592 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100593 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000594
Victor Stinner80aa5652013-07-07 17:17:59 +0200595 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000596}
597
Antoine Pitrou810023d2010-12-15 22:59:16 +0000598PyLockStatus
599PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
600 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000601{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200602 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 pthread_lock *thelock = (pthread_lock *)lock;
604 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000605
Antoine Pitrou810023d2010-12-15 22:59:16 +0000606 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
607 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000608
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200609 if (microseconds == 0) {
610 status = pthread_mutex_trylock( &thelock->mut );
611 if (status != EBUSY)
612 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
613 }
614 else {
615 status = pthread_mutex_lock( &thelock->mut );
616 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
617 }
618 if (status == 0) {
619 if (thelock->locked == 0) {
620 success = PY_LOCK_ACQUIRED;
621 }
622 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900623 struct timespec abs;
624 if (microseconds > 0) {
625 _PyThread_cond_after(microseconds, &abs);
626 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200627 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000628
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200629 /* mut must be locked by me -- part of the condition
630 * protocol */
631 while (success == PY_LOCK_FAILURE) {
632 if (microseconds > 0) {
633 status = pthread_cond_timedwait(
634 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900635 &thelock->mut, &abs);
636 if (status == 1) {
637 break;
638 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200639 if (status == ETIMEDOUT)
640 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900641 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200642 }
643 else {
644 status = pthread_cond_wait(
645 &thelock->lock_released,
646 &thelock->mut);
647 CHECK_STATUS_PTHREAD("pthread_cond_wait");
648 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000649
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200650 if (intr_flag && status == 0 && thelock->locked) {
651 /* We were woken up, but didn't get the lock. We probably received
652 * a signal. Return PY_LOCK_INTR to allow the caller to handle
653 * it and retry. */
654 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200656 }
657 else if (status == 0 && !thelock->locked) {
658 success = PY_LOCK_ACQUIRED;
659 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000660 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200662 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
663 status = pthread_mutex_unlock( &thelock->mut );
664 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000666
Antoine Pitrou810023d2010-12-15 22:59:16 +0000667 if (error) success = PY_LOCK_FAILURE;
668 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
669 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000671}
672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000674PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000675{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 pthread_lock *thelock = (pthread_lock *)lock;
677 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000678
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200679 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100683 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 /* wake up someone (anyone, if any) waiting on the lock */
688 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100689 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000690
691 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100692 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000693}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000694
695#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000696
Antoine Pitrou810023d2010-12-15 22:59:16 +0000697int
Victor Stinner87255be2020-04-07 23:11:49 +0200698_PyThread_at_fork_reinit(PyThread_type_lock *lock)
699{
700 PyThread_type_lock new_lock = PyThread_allocate_lock();
701 if (new_lock == NULL) {
702 return -1;
703 }
704
705 /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
706 fork() can be called in the middle of an operation on the lock done by
707 another thread. So don't call PyThread_free_lock(*lock).
708
709 Leak memory on purpose. Don't release the memory either since the
710 address of a mutex is relevant. Putting two mutexes at the same address
711 can lead to problems. */
712
713 *lock = new_lock;
714 return 0;
715}
716
717int
Antoine Pitrou810023d2010-12-15 22:59:16 +0000718PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
719{
720 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
721}
722
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000723/* set the thread stack size.
724 * Return 0 if size is valid, -1 if size is invalid,
725 * -2 if setting stack size is not supported.
726 */
727static int
728_pythread_pthread_set_stacksize(size_t size)
729{
730#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 pthread_attr_t attrs;
732 size_t tss_min;
733 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000734#endif
735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 /* set to default */
737 if (size == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200738 _PyInterpreterState_GET()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 return 0;
740 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000741
742#if defined(THREAD_STACK_SIZE)
743#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
745 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000746#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000748#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 if (size >= tss_min) {
750 /* validate stack size by setting thread attribute */
751 if (pthread_attr_init(&attrs) == 0) {
752 rc = pthread_attr_setstacksize(&attrs, size);
753 pthread_attr_destroy(&attrs);
754 if (rc == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200755 _PyInterpreterState_GET()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 return 0;
757 }
758 }
759 }
760 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000761#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000763#endif
764}
765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000767
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000768
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900769/* Thread Local Storage (TLS) API
770
771 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
772*/
773
774/* Issue #25658: On platforms where native TLS key is defined in a way that
775 cannot be safely cast to int, PyThread_create_key returns immediately a
776 failure status and other TLS functions all are no-ops. This indicates
777 clearly that the old API is not supported on platforms where it cannot be
778 used reliably, and that no effort will be made to add such support.
779
780 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
781 removing this API.
782*/
783
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000784int
785PyThread_create_key(void)
786{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900787#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000788 pthread_key_t key;
789 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200790 if (fail)
791 return -1;
792 if (key > INT_MAX) {
793 /* Issue #22206: handle integer overflow */
794 pthread_key_delete(key);
795 errno = ENOMEM;
796 return -1;
797 }
798 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900799#else
800 return -1; /* never return valid key value. */
801#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000802}
803
804void
805PyThread_delete_key(int key)
806{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900807#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000808 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900809#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000810}
811
812void
813PyThread_delete_key_value(int key)
814{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900815#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000816 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900817#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000818}
819
820int
821PyThread_set_key_value(int key, void *value)
822{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900823#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
824 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000825 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900826#else
827 return -1;
828#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000829}
830
831void *
832PyThread_get_key_value(int key)
833{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900834#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000835 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900836#else
837 return NULL;
838#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000839}
840
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900841
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000842void
843PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900844{
845}
846
847
848/* Thread Specific Storage (TSS) API
849
850 Platform-specific components of TSS API implementation.
851*/
852
853int
854PyThread_tss_create(Py_tss_t *key)
855{
856 assert(key != NULL);
857 /* If the key has been created, function is silently skipped. */
858 if (key->_is_initialized) {
859 return 0;
860 }
861
862 int fail = pthread_key_create(&(key->_key), NULL);
863 if (fail) {
864 return -1;
865 }
866 key->_is_initialized = 1;
867 return 0;
868}
869
870void
871PyThread_tss_delete(Py_tss_t *key)
872{
873 assert(key != NULL);
874 /* If the key has not been created, function is silently skipped. */
875 if (!key->_is_initialized) {
876 return;
877 }
878
879 pthread_key_delete(key->_key);
880 /* pthread has not provided the defined invalid value for the key. */
881 key->_is_initialized = 0;
882}
883
884int
885PyThread_tss_set(Py_tss_t *key, void *value)
886{
887 assert(key != NULL);
888 int fail = pthread_setspecific(key->_key, value);
889 return fail ? -1 : 0;
890}
891
892void *
893PyThread_tss_get(Py_tss_t *key)
894{
895 assert(key != NULL);
896 return pthread_getspecific(key->_key);
897}