blob: a45d842ffe73d2417e38b3f0b04d4265d32220ab [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) && \
95 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000096# define USE_SEMAPHORES
97#else
98# undef USE_SEMAPHORES
99#endif
100
101
Guido van Rossum80230992001-10-12 21:49:17 +0000102/* On platforms that don't use standard POSIX threads pthread_sigmask()
103 * isn't present. DEC threads uses sigprocmask() instead as do most
104 * other UNIX International compliant systems that don't have the full
105 * pthread implementation.
106 */
Jason Tishlerfac083d2003-07-22 15:20:49 +0000107#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +0000108# define SET_THREAD_SIGMASK pthread_sigmask
109#else
110# define SET_THREAD_SIGMASK sigprocmask
111#endif
112
113
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000114#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
115do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 struct timeval tv; \
Benjamin Petersonf1c19032019-09-10 11:37:59 +0100117 gettimeofday(&tv, NULL); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 tv.tv_usec += microseconds % 1000000; \
119 tv.tv_sec += microseconds / 1000000; \
120 tv.tv_sec += tv.tv_usec / 1000000; \
121 tv.tv_usec %= 1000000; \
122 ts.tv_sec = tv.tv_sec; \
123 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000124} while(0)
125
126
Inada Naoki001fee12019-02-20 10:00:09 +0900127/*
128 * pthread_cond support
129 */
130
131#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
132// monotonic is supported statically. It doesn't mean it works on runtime.
133#define CONDATTR_MONOTONIC
134#endif
135
136// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
137static pthread_condattr_t *condattr_monotonic = NULL;
138
139static void
Benjamin Petersonea62a4b2020-07-15 06:12:05 -0700140init_condattr(void)
Inada Naoki001fee12019-02-20 10:00:09 +0900141{
142#ifdef CONDATTR_MONOTONIC
143 static pthread_condattr_t ca;
144 pthread_condattr_init(&ca);
145 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
146 condattr_monotonic = &ca; // Use monotonic clock
147 }
148#endif
149}
150
151int
152_PyThread_cond_init(PyCOND_T *cond)
153{
154 return pthread_cond_init(cond, condattr_monotonic);
155}
156
157void
158_PyThread_cond_after(long long us, struct timespec *abs)
159{
160#ifdef CONDATTR_MONOTONIC
161 if (condattr_monotonic) {
162 clock_gettime(CLOCK_MONOTONIC, abs);
163 abs->tv_sec += us / 1000000;
164 abs->tv_nsec += (us % 1000000) * 1000;
165 abs->tv_sec += abs->tv_nsec / 1000000000;
166 abs->tv_nsec %= 1000000000;
167 return;
168 }
169#endif
170
171 struct timespec ts;
172 MICROSECONDS_TO_TIMESPEC(us, ts);
173 *abs = ts;
174}
175
176
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000177/* A pthread mutex isn't sufficient to model the Python lock type
178 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
179 * following are undefined:
180 * -> a thread tries to lock a mutex it already has locked
181 * -> a thread tries to unlock a mutex locked by a different thread
182 * pthread mutexes are designed for serializing threads over short pieces
183 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000184 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000185 *
186 * The pthread_lock struct implements a Python lock as a "locked?" bit
187 * and a <condition, mutex> pair. In general, if the bit can be acquired
188 * instantly, it is, else the pair is used to block the thread until the
189 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000190 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000191
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000192typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 char locked; /* 0=unlocked, 1=locked */
194 /* a <cond, mutex> pair to handle an acquire of a locked lock */
195 pthread_cond_t lock_released;
196 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000197} pthread_lock;
198
Guido van Rossum9e46e561998-10-07 16:39:47 +0000199#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100200#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
201 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000202
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000203/*
204 * Initialization.
205 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000206static void
207PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000208{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000209#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200210 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000212#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900213 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000214}
215
216/*
217 * Thread support.
218 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000219
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530220/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
221 "void func(void *)" to "void* func(void *)": always return NULL.
222
223 PyThread_start_new_thread() uses "void func(void *)" type, whereas
224 pthread_create() requires a void* return value. */
225typedef struct {
226 void (*func) (void *);
227 void *arg;
228} pythread_callback;
229
230static void *
231pythread_wrapper(void *arg)
232{
233 /* copy func and func_arg and free the temporary structure */
234 pythread_callback *callback = arg;
235 void (*func)(void *) = callback->func;
236 void *func_arg = callback->arg;
237 PyMem_RawFree(arg);
238
239 func(func_arg);
240 return NULL;
241}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000242
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200243unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000244PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 pthread_t th;
247 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000248#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000250#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000251#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000253#endif
254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 dprintf(("PyThread_start_new_thread called\n"));
256 if (!initialized)
257 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000258
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000259#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200261 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000262#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000263#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100264 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600265 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
266 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 if (tss != 0) {
268 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
269 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200270 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 }
272 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000273#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000274#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000276#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000277
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530278 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
279
280 if (callback == NULL) {
281 return PYTHREAD_INVALID_THREAD_ID;
282 }
283
284 callback->func = func;
285 callback->arg = arg;
286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000288#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000290#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000292#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530293 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000294
Fred Drake03459a52001-11-09 16:00:41 +0000295#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000297#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530298
299 if (status != 0) {
300 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200301 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530302 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000305
Guido van Rossum3c288632001-10-16 21:13:49 +0000306#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200307 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000308#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200309 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000310#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000311}
312
Trent Mick635f6fb2000-08-23 21:33:05 +0000313/* XXX This implementation is considered (to quote Tim Peters) "inherently
314 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000315 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200316 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100317 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000318*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200319unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000320PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 volatile pthread_t threadid;
323 if (!initialized)
324 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200326 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000327}
328
Jake Teslerb121f632019-05-22 08:43:17 -0700329#ifdef PY_HAVE_THREAD_NATIVE_ID
330unsigned long
331PyThread_get_thread_native_id(void)
332{
333 if (!initialized)
334 PyThread_init_thread();
335#ifdef __APPLE__
336 uint64_t native_id;
337 (void) pthread_threadid_np(NULL, &native_id);
338#elif defined(__linux__)
339 pid_t native_id;
340 native_id = syscall(SYS_gettid);
341#elif defined(__FreeBSD__)
342 int native_id;
343 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100344#elif defined(__OpenBSD__)
345 pid_t native_id;
346 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200347#elif defined(_AIX)
348 tid_t native_id;
349 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000350#elif defined(__NetBSD__)
351 lwpid_t native_id;
352 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700353#endif
354 return (unsigned long) native_id;
355}
356#endif
357
Victor Stinnerc664b342019-05-04 11:48:05 -0400358void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000359PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000360{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200362 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200364 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000365}
366
Martin v. Löwiscc898662002-03-17 09:53:51 +0000367#ifdef USE_SEMAPHORES
368
369/*
370 * Lock support.
371 */
372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000374PyThread_allocate_lock(void)
375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 sem_t *lock;
377 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000378
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 dprintf(("PyThread_allocate_lock called\n"));
380 if (!initialized)
381 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000382
Victor Stinner80aa5652013-07-07 17:17:59 +0200383 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 if (lock) {
386 status = sem_init(lock,0,1);
387 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200390 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 lock = NULL;
392 }
393 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000394
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600395 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000397}
398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000400PyThread_free_lock(PyThread_type_lock lock)
401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 sem_t *thelock = (sem_t *)lock;
403 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000404
Christian Heimes56379c02012-12-02 08:37:00 +0100405 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (!thelock)
409 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000410
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 status = sem_destroy(thelock);
412 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000413
Victor Stinner80aa5652013-07-07 17:17:59 +0200414 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000415}
416
417/*
418 * As of February 2002, Cygwin thread implementations mistakenly report error
419 * codes in the return value of the sem_ calls (like the pthread_ functions).
420 * Correct implementations return -1 and put the code in errno. This supports
421 * either.
422 */
423static int
424fix_status(int status)
425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000427}
428
Antoine Pitrou810023d2010-12-15 22:59:16 +0000429PyLockStatus
430PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
431 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000432{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000433 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 sem_t *thelock = (sem_t *)lock;
435 int status, error = 0;
436 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700437 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000438
Christian Heimes56379c02012-12-02 08:37:00 +0100439 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000440 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
441 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000442
Victor Stinner850a18e2017-10-24 16:53:32 -0700443 if (microseconds > PY_TIMEOUT_MAX) {
444 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
445 }
446
447 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700449
450 if (!intr_flag) {
451 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
452 check done above */
453 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
454 deadline = _PyTime_GetMonotonicClock() + timeout;
455 }
456 }
457
458 while (1) {
459 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700461 }
462 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700464 }
465 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700467 }
468
Antoine Pitrou810023d2010-12-15 22:59:16 +0000469 /* Retry if interrupted by a signal, unless the caller wants to be
470 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700471 if (intr_flag || status != EINTR) {
472 break;
473 }
474
475 if (microseconds > 0) {
476 /* wait interrupted by a signal (EINTR): recompute the timeout */
477 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
478 if (dt < 0) {
479 status = ETIMEDOUT;
480 break;
481 }
482 else if (dt > 0) {
483 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
484 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
485 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
486 check done above */
487 Py_UNREACHABLE();
488 }
489 /* no need to update microseconds value, the code only care
490 if (microseconds > 0 or (microseconds == 0). */
491 }
492 else {
493 microseconds = 0;
494 }
495 }
496 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000497
Antoine Pitrou810023d2010-12-15 22:59:16 +0000498 /* Don't check the status if we're stopping because of an interrupt. */
499 if (!(intr_flag && status == EINTR)) {
500 if (microseconds > 0) {
501 if (status != ETIMEDOUT)
502 CHECK_STATUS("sem_timedwait");
503 }
504 else if (microseconds == 0) {
505 if (status != EAGAIN)
506 CHECK_STATUS("sem_trywait");
507 }
508 else {
509 CHECK_STATUS("sem_wait");
510 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000512
Antoine Pitrou810023d2010-12-15 22:59:16 +0000513 if (status == 0) {
514 success = PY_LOCK_ACQUIRED;
515 } else if (intr_flag && status == EINTR) {
516 success = PY_LOCK_INTR;
517 } else {
518 success = PY_LOCK_FAILURE;
519 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520
Antoine Pitrou810023d2010-12-15 22:59:16 +0000521 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
522 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000524}
525
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000527PyThread_release_lock(PyThread_type_lock lock)
528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 sem_t *thelock = (sem_t *)lock;
530 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000531
Christian Heimes56379c02012-12-02 08:37:00 +0100532 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000534
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 status = sem_post(thelock);
536 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000537}
538
539#else /* USE_SEMAPHORES */
540
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000541/*
542 * Lock support.
543 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000545PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000546{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 pthread_lock *lock;
548 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000549
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 dprintf(("PyThread_allocate_lock called\n"));
551 if (!initialized)
552 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000553
Andy Lester7668a8b2020-03-24 23:26:44 -0500554 lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 if (lock) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000557
Inada Naoki001fee12019-02-20 10:00:09 +0900558 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100559 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 /* Mark the pthread mutex underlying a Python mutex as
561 pure happens-before. We can't simply mark the
562 Python-level mutex as a mutex because it can be
563 acquired and released in different threads, which
564 will cause errors. */
565 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000566
Inada Naoki001fee12019-02-20 10:00:09 +0900567 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100568 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200571 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 lock = 0;
573 }
574 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000575
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600576 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000578}
579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000581PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 pthread_lock *thelock = (pthread_lock *)lock;
584 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000585
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200586 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000588
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000589 /* some pthread-like implementations tie the mutex to the cond
590 * and must have the cond destroyed first.
591 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100593 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000594
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000595 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100596 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000597
Victor Stinner80aa5652013-07-07 17:17:59 +0200598 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000599}
600
Antoine Pitrou810023d2010-12-15 22:59:16 +0000601PyLockStatus
602PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
603 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000604{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200605 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 pthread_lock *thelock = (pthread_lock *)lock;
607 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000608
Antoine Pitrou810023d2010-12-15 22:59:16 +0000609 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
610 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000611
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200612 if (microseconds == 0) {
613 status = pthread_mutex_trylock( &thelock->mut );
614 if (status != EBUSY)
615 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
616 }
617 else {
618 status = pthread_mutex_lock( &thelock->mut );
619 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
620 }
621 if (status == 0) {
622 if (thelock->locked == 0) {
623 success = PY_LOCK_ACQUIRED;
624 }
625 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900626 struct timespec abs;
627 if (microseconds > 0) {
628 _PyThread_cond_after(microseconds, &abs);
629 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200630 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000631
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200632 /* mut must be locked by me -- part of the condition
633 * protocol */
634 while (success == PY_LOCK_FAILURE) {
635 if (microseconds > 0) {
636 status = pthread_cond_timedwait(
637 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900638 &thelock->mut, &abs);
639 if (status == 1) {
640 break;
641 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200642 if (status == ETIMEDOUT)
643 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900644 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200645 }
646 else {
647 status = pthread_cond_wait(
648 &thelock->lock_released,
649 &thelock->mut);
650 CHECK_STATUS_PTHREAD("pthread_cond_wait");
651 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000652
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200653 if (intr_flag && status == 0 && thelock->locked) {
654 /* We were woken up, but didn't get the lock. We probably received
655 * a signal. Return PY_LOCK_INTR to allow the caller to handle
656 * it and retry. */
657 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200659 }
660 else if (status == 0 && !thelock->locked) {
661 success = PY_LOCK_ACQUIRED;
662 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000663 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200665 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
666 status = pthread_mutex_unlock( &thelock->mut );
667 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000669
Antoine Pitrou810023d2010-12-15 22:59:16 +0000670 if (error) success = PY_LOCK_FAILURE;
671 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
672 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000674}
675
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000677PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000678{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 pthread_lock *thelock = (pthread_lock *)lock;
680 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000681
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200682 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000684
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100686 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 /* wake up someone (anyone, if any) waiting on the lock */
691 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100692 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000693
694 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100695 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000696}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000697
698#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000699
Antoine Pitrou810023d2010-12-15 22:59:16 +0000700int
Victor Stinner87255be2020-04-07 23:11:49 +0200701_PyThread_at_fork_reinit(PyThread_type_lock *lock)
702{
703 PyThread_type_lock new_lock = PyThread_allocate_lock();
704 if (new_lock == NULL) {
705 return -1;
706 }
707
708 /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
709 fork() can be called in the middle of an operation on the lock done by
710 another thread. So don't call PyThread_free_lock(*lock).
711
712 Leak memory on purpose. Don't release the memory either since the
713 address of a mutex is relevant. Putting two mutexes at the same address
714 can lead to problems. */
715
716 *lock = new_lock;
717 return 0;
718}
719
720int
Antoine Pitrou810023d2010-12-15 22:59:16 +0000721PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
722{
723 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
724}
725
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000726/* set the thread stack size.
727 * Return 0 if size is valid, -1 if size is invalid,
728 * -2 if setting stack size is not supported.
729 */
730static int
731_pythread_pthread_set_stacksize(size_t size)
732{
733#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 pthread_attr_t attrs;
735 size_t tss_min;
736 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000737#endif
738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 /* set to default */
740 if (size == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200741 _PyInterpreterState_GET()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 return 0;
743 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000744
745#if defined(THREAD_STACK_SIZE)
746#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
748 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000749#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000751#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 if (size >= tss_min) {
753 /* validate stack size by setting thread attribute */
754 if (pthread_attr_init(&attrs) == 0) {
755 rc = pthread_attr_setstacksize(&attrs, size);
756 pthread_attr_destroy(&attrs);
757 if (rc == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200758 _PyInterpreterState_GET()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 return 0;
760 }
761 }
762 }
763 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000764#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000766#endif
767}
768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000770
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000771
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900772/* Thread Local Storage (TLS) API
773
774 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
775*/
776
777/* Issue #25658: On platforms where native TLS key is defined in a way that
778 cannot be safely cast to int, PyThread_create_key returns immediately a
779 failure status and other TLS functions all are no-ops. This indicates
780 clearly that the old API is not supported on platforms where it cannot be
781 used reliably, and that no effort will be made to add such support.
782
783 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
784 removing this API.
785*/
786
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000787int
788PyThread_create_key(void)
789{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900790#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000791 pthread_key_t key;
792 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200793 if (fail)
794 return -1;
795 if (key > INT_MAX) {
796 /* Issue #22206: handle integer overflow */
797 pthread_key_delete(key);
798 errno = ENOMEM;
799 return -1;
800 }
801 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900802#else
803 return -1; /* never return valid key value. */
804#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000805}
806
807void
808PyThread_delete_key(int key)
809{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900810#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000811 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900812#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000813}
814
815void
816PyThread_delete_key_value(int key)
817{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900818#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000819 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900820#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000821}
822
823int
824PyThread_set_key_value(int key, void *value)
825{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900826#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
827 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000828 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900829#else
830 return -1;
831#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000832}
833
834void *
835PyThread_get_key_value(int key)
836{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900837#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000838 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900839#else
840 return NULL;
841#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000842}
843
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900844
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000845void
846PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900847{
848}
849
850
851/* Thread Specific Storage (TSS) API
852
853 Platform-specific components of TSS API implementation.
854*/
855
856int
857PyThread_tss_create(Py_tss_t *key)
858{
859 assert(key != NULL);
860 /* If the key has been created, function is silently skipped. */
861 if (key->_is_initialized) {
862 return 0;
863 }
864
865 int fail = pthread_key_create(&(key->_key), NULL);
866 if (fail) {
867 return -1;
868 }
869 key->_is_initialized = 1;
870 return 0;
871}
872
873void
874PyThread_tss_delete(Py_tss_t *key)
875{
876 assert(key != NULL);
877 /* If the key has not been created, function is silently skipped. */
878 if (!key->_is_initialized) {
879 return;
880 }
881
882 pthread_key_delete(key->_key);
883 /* pthread has not provided the defined invalid value for the key. */
884 key->_is_initialized = 0;
885}
886
887int
888PyThread_tss_set(Py_tss_t *key, void *value)
889{
890 assert(key != NULL);
891 int fail = pthread_setspecific(key->_key, value);
892 return fail ? -1 : 0;
893}
894
895void *
896PyThread_tss_get(Py_tss_t *key)
897{
898 assert(key != NULL);
899 return pthread_getspecific(key->_key);
900}