blob: ec7d737518b68c6a3c668399cf01bb00de2d8164 [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
pxinwrd5dcb652020-12-10 05:47:28 +080065#if defined(__VXWORKS__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
66#undef THREAD_STACK_SIZE
67#define THREAD_STACK_SIZE 0x100000
68#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080070#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
72#ifdef THREAD_STACK_SIZE
73#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
74#endif
75#endif
76
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000077/* The POSIX spec says that implementations supporting the sem_*
78 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000080#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000082 we need to add 0 to make it work there as well. */
83#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000084#define HAVE_BROKEN_POSIX_SEMAPHORES
85#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000086#include <semaphore.h>
87#include <errno.h>
88#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000089#endif
Guido van Rossum66020991996-06-11 18:32:18 +000090
Guido van Rossumd6353e21997-05-13 17:51:13 +000091
Martin v. Löwiscc898662002-03-17 09:53:51 +000092/* Whether or not to use semaphores directly rather than emulating them with
93 * mutexes and condition variables:
94 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000095#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
96 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000097# define USE_SEMAPHORES
98#else
99# undef USE_SEMAPHORES
100#endif
101
102
Guido van Rossum80230992001-10-12 21:49:17 +0000103/* On platforms that don't use standard POSIX threads pthread_sigmask()
104 * isn't present. DEC threads uses sigprocmask() instead as do most
105 * other UNIX International compliant systems that don't have the full
106 * pthread implementation.
107 */
Jason Tishlerfac083d2003-07-22 15:20:49 +0000108#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +0000109# define SET_THREAD_SIGMASK pthread_sigmask
110#else
111# define SET_THREAD_SIGMASK sigprocmask
112#endif
113
114
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000115#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
116do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 struct timeval tv; \
Benjamin Petersonf1c19032019-09-10 11:37:59 +0100118 gettimeofday(&tv, NULL); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 tv.tv_usec += microseconds % 1000000; \
120 tv.tv_sec += microseconds / 1000000; \
121 tv.tv_sec += tv.tv_usec / 1000000; \
122 tv.tv_usec %= 1000000; \
123 ts.tv_sec = tv.tv_sec; \
124 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000125} while(0)
126
127
Inada Naoki001fee12019-02-20 10:00:09 +0900128/*
129 * pthread_cond support
130 */
131
132#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
133// monotonic is supported statically. It doesn't mean it works on runtime.
134#define CONDATTR_MONOTONIC
135#endif
136
137// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
138static pthread_condattr_t *condattr_monotonic = NULL;
139
140static void
Benjamin Petersonea62a4b2020-07-15 06:12:05 -0700141init_condattr(void)
Inada Naoki001fee12019-02-20 10:00:09 +0900142{
143#ifdef CONDATTR_MONOTONIC
144 static pthread_condattr_t ca;
145 pthread_condattr_init(&ca);
146 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
147 condattr_monotonic = &ca; // Use monotonic clock
148 }
149#endif
150}
151
152int
153_PyThread_cond_init(PyCOND_T *cond)
154{
155 return pthread_cond_init(cond, condattr_monotonic);
156}
157
158void
159_PyThread_cond_after(long long us, struct timespec *abs)
160{
161#ifdef CONDATTR_MONOTONIC
162 if (condattr_monotonic) {
163 clock_gettime(CLOCK_MONOTONIC, abs);
164 abs->tv_sec += us / 1000000;
165 abs->tv_nsec += (us % 1000000) * 1000;
166 abs->tv_sec += abs->tv_nsec / 1000000000;
167 abs->tv_nsec %= 1000000000;
168 return;
169 }
170#endif
171
172 struct timespec ts;
173 MICROSECONDS_TO_TIMESPEC(us, ts);
174 *abs = ts;
175}
176
177
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000178/* A pthread mutex isn't sufficient to model the Python lock type
179 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
180 * following are undefined:
181 * -> a thread tries to lock a mutex it already has locked
182 * -> a thread tries to unlock a mutex locked by a different thread
183 * pthread mutexes are designed for serializing threads over short pieces
184 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000185 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000186 *
187 * The pthread_lock struct implements a Python lock as a "locked?" bit
188 * and a <condition, mutex> pair. In general, if the bit can be acquired
189 * instantly, it is, else the pair is used to block the thread until the
190 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000191 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000192
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000193typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 char locked; /* 0=unlocked, 1=locked */
195 /* a <cond, mutex> pair to handle an acquire of a locked lock */
196 pthread_cond_t lock_released;
197 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000198} pthread_lock;
199
Guido van Rossum9e46e561998-10-07 16:39:47 +0000200#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100201#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
202 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000203
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000204/*
205 * Initialization.
206 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000207static void
208PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000209{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000210#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200211 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000213#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900214 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000215}
216
217/*
218 * Thread support.
219 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000220
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530221/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
222 "void func(void *)" to "void* func(void *)": always return NULL.
223
224 PyThread_start_new_thread() uses "void func(void *)" type, whereas
225 pthread_create() requires a void* return value. */
226typedef struct {
227 void (*func) (void *);
228 void *arg;
229} pythread_callback;
230
231static void *
232pythread_wrapper(void *arg)
233{
234 /* copy func and func_arg and free the temporary structure */
235 pythread_callback *callback = arg;
236 void (*func)(void *) = callback->func;
237 void *func_arg = callback->arg;
238 PyMem_RawFree(arg);
239
240 func(func_arg);
241 return NULL;
242}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000243
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200244unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000245PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 pthread_t th;
248 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000249#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000251#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000252#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000254#endif
255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 dprintf(("PyThread_start_new_thread called\n"));
257 if (!initialized)
258 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000259
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000260#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200262 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000263#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100265 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600266 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
267 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 if (tss != 0) {
269 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
270 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200271 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 }
273 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000274#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000275#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000277#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000278
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530279 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
280
281 if (callback == NULL) {
282 return PYTHREAD_INVALID_THREAD_ID;
283 }
284
285 callback->func = func;
286 callback->arg = arg;
287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000289#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000291#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000293#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530294 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000295
Fred Drake03459a52001-11-09 16:00:41 +0000296#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000298#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530299
300 if (status != 0) {
301 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200302 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530303 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000306
Guido van Rossum3c288632001-10-16 21:13:49 +0000307#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200308 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000309#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200310 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000311#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000312}
313
Trent Mick635f6fb2000-08-23 21:33:05 +0000314/* XXX This implementation is considered (to quote Tim Peters) "inherently
315 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000316 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200317 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100318 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000319*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200320unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000321PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 volatile pthread_t threadid;
324 if (!initialized)
325 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200327 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000328}
329
Jake Teslerb121f632019-05-22 08:43:17 -0700330#ifdef PY_HAVE_THREAD_NATIVE_ID
331unsigned long
332PyThread_get_thread_native_id(void)
333{
334 if (!initialized)
335 PyThread_init_thread();
336#ifdef __APPLE__
337 uint64_t native_id;
338 (void) pthread_threadid_np(NULL, &native_id);
339#elif defined(__linux__)
340 pid_t native_id;
341 native_id = syscall(SYS_gettid);
342#elif defined(__FreeBSD__)
343 int native_id;
344 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100345#elif defined(__OpenBSD__)
346 pid_t native_id;
347 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200348#elif defined(_AIX)
349 tid_t native_id;
350 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000351#elif defined(__NetBSD__)
352 lwpid_t native_id;
353 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700354#endif
355 return (unsigned long) native_id;
356}
357#endif
358
Victor Stinnerc664b342019-05-04 11:48:05 -0400359void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000360PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200363 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200365 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000366}
367
Martin v. Löwiscc898662002-03-17 09:53:51 +0000368#ifdef USE_SEMAPHORES
369
370/*
371 * Lock support.
372 */
373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000375PyThread_allocate_lock(void)
376{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 sem_t *lock;
378 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 dprintf(("PyThread_allocate_lock called\n"));
381 if (!initialized)
382 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000383
Victor Stinner80aa5652013-07-07 17:17:59 +0200384 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 if (lock) {
387 status = sem_init(lock,0,1);
388 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200391 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 lock = NULL;
393 }
394 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000395
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600396 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000398}
399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000401PyThread_free_lock(PyThread_type_lock lock)
402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 sem_t *thelock = (sem_t *)lock;
404 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000405
Christian Heimes56379c02012-12-02 08:37:00 +0100406 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 if (!thelock)
410 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 status = sem_destroy(thelock);
413 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000414
Victor Stinner80aa5652013-07-07 17:17:59 +0200415 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000416}
417
418/*
419 * As of February 2002, Cygwin thread implementations mistakenly report error
420 * codes in the return value of the sem_ calls (like the pthread_ functions).
421 * Correct implementations return -1 and put the code in errno. This supports
422 * either.
423 */
424static int
425fix_status(int status)
426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000428}
429
Antoine Pitrou810023d2010-12-15 22:59:16 +0000430PyLockStatus
431PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
432 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000433{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000434 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 sem_t *thelock = (sem_t *)lock;
436 int status, error = 0;
437 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700438 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000439
Christian Heimes56379c02012-12-02 08:37:00 +0100440 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000441 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
442 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000443
Victor Stinner850a18e2017-10-24 16:53:32 -0700444 if (microseconds > PY_TIMEOUT_MAX) {
445 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
446 }
447
448 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700450
451 if (!intr_flag) {
452 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
453 check done above */
454 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
455 deadline = _PyTime_GetMonotonicClock() + timeout;
456 }
457 }
458
459 while (1) {
460 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700462 }
463 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700465 }
466 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700468 }
469
Antoine Pitrou810023d2010-12-15 22:59:16 +0000470 /* Retry if interrupted by a signal, unless the caller wants to be
471 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700472 if (intr_flag || status != EINTR) {
473 break;
474 }
475
476 if (microseconds > 0) {
477 /* wait interrupted by a signal (EINTR): recompute the timeout */
478 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
479 if (dt < 0) {
480 status = ETIMEDOUT;
481 break;
482 }
483 else if (dt > 0) {
484 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
485 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
486 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
487 check done above */
488 Py_UNREACHABLE();
489 }
490 /* no need to update microseconds value, the code only care
491 if (microseconds > 0 or (microseconds == 0). */
492 }
493 else {
494 microseconds = 0;
495 }
496 }
497 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000498
Antoine Pitrou810023d2010-12-15 22:59:16 +0000499 /* Don't check the status if we're stopping because of an interrupt. */
500 if (!(intr_flag && status == EINTR)) {
501 if (microseconds > 0) {
502 if (status != ETIMEDOUT)
503 CHECK_STATUS("sem_timedwait");
504 }
505 else if (microseconds == 0) {
506 if (status != EAGAIN)
507 CHECK_STATUS("sem_trywait");
508 }
509 else {
510 CHECK_STATUS("sem_wait");
511 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000513
Antoine Pitrou810023d2010-12-15 22:59:16 +0000514 if (status == 0) {
515 success = PY_LOCK_ACQUIRED;
516 } else if (intr_flag && status == EINTR) {
517 success = PY_LOCK_INTR;
518 } else {
519 success = PY_LOCK_FAILURE;
520 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521
Antoine Pitrou810023d2010-12-15 22:59:16 +0000522 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
523 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000525}
526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000528PyThread_release_lock(PyThread_type_lock lock)
529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 sem_t *thelock = (sem_t *)lock;
531 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000532
Christian Heimes56379c02012-12-02 08:37:00 +0100533 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 status = sem_post(thelock);
537 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000538}
539
540#else /* USE_SEMAPHORES */
541
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000542/*
543 * Lock support.
544 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000546PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 pthread_lock *lock;
549 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 dprintf(("PyThread_allocate_lock called\n"));
552 if (!initialized)
553 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000554
Andy Lester7668a8b2020-03-24 23:26:44 -0500555 lock = (pthread_lock *) PyMem_RawCalloc(1, sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 if (lock) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000558
Inada Naoki001fee12019-02-20 10:00:09 +0900559 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100560 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 /* Mark the pthread mutex underlying a Python mutex as
562 pure happens-before. We can't simply mark the
563 Python-level mutex as a mutex because it can be
564 acquired and released in different threads, which
565 will cause errors. */
566 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000567
Inada Naoki001fee12019-02-20 10:00:09 +0900568 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100569 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200572 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 lock = 0;
574 }
575 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000576
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600577 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000579}
580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000582PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000583{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 pthread_lock *thelock = (pthread_lock *)lock;
585 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000586
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200587 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000589
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000590 /* some pthread-like implementations tie the mutex to the cond
591 * and must have the cond destroyed first.
592 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100594 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000595
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000596 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100597 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000598
Victor Stinner80aa5652013-07-07 17:17:59 +0200599 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000600}
601
Antoine Pitrou810023d2010-12-15 22:59:16 +0000602PyLockStatus
603PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
604 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000605{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200606 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 pthread_lock *thelock = (pthread_lock *)lock;
608 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000609
Antoine Pitrou810023d2010-12-15 22:59:16 +0000610 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
611 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000612
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200613 if (microseconds == 0) {
614 status = pthread_mutex_trylock( &thelock->mut );
615 if (status != EBUSY)
616 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
617 }
618 else {
619 status = pthread_mutex_lock( &thelock->mut );
620 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
621 }
622 if (status == 0) {
623 if (thelock->locked == 0) {
624 success = PY_LOCK_ACQUIRED;
625 }
626 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900627 struct timespec abs;
628 if (microseconds > 0) {
629 _PyThread_cond_after(microseconds, &abs);
630 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200631 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000632
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200633 /* mut must be locked by me -- part of the condition
634 * protocol */
635 while (success == PY_LOCK_FAILURE) {
636 if (microseconds > 0) {
637 status = pthread_cond_timedwait(
638 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900639 &thelock->mut, &abs);
640 if (status == 1) {
641 break;
642 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200643 if (status == ETIMEDOUT)
644 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900645 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200646 }
647 else {
648 status = pthread_cond_wait(
649 &thelock->lock_released,
650 &thelock->mut);
651 CHECK_STATUS_PTHREAD("pthread_cond_wait");
652 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000653
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200654 if (intr_flag && status == 0 && thelock->locked) {
655 /* We were woken up, but didn't get the lock. We probably received
656 * a signal. Return PY_LOCK_INTR to allow the caller to handle
657 * it and retry. */
658 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200660 }
661 else if (status == 0 && !thelock->locked) {
662 success = PY_LOCK_ACQUIRED;
663 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000664 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200666 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
667 status = pthread_mutex_unlock( &thelock->mut );
668 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000670
Antoine Pitrou810023d2010-12-15 22:59:16 +0000671 if (error) success = PY_LOCK_FAILURE;
672 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
673 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000675}
676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000678PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000679{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 pthread_lock *thelock = (pthread_lock *)lock;
681 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000682
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200683 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100687 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 /* wake up someone (anyone, if any) waiting on the lock */
692 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100693 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000694
695 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100696 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000697}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000698
699#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000700
Antoine Pitrou810023d2010-12-15 22:59:16 +0000701int
Victor Stinner87255be2020-04-07 23:11:49 +0200702_PyThread_at_fork_reinit(PyThread_type_lock *lock)
703{
704 PyThread_type_lock new_lock = PyThread_allocate_lock();
705 if (new_lock == NULL) {
706 return -1;
707 }
708
709 /* bpo-6721, bpo-40089: The old lock can be in an inconsistent state.
710 fork() can be called in the middle of an operation on the lock done by
711 another thread. So don't call PyThread_free_lock(*lock).
712
713 Leak memory on purpose. Don't release the memory either since the
714 address of a mutex is relevant. Putting two mutexes at the same address
715 can lead to problems. */
716
717 *lock = new_lock;
718 return 0;
719}
720
721int
Antoine Pitrou810023d2010-12-15 22:59:16 +0000722PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
723{
724 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
725}
726
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000727/* set the thread stack size.
728 * Return 0 if size is valid, -1 if size is invalid,
729 * -2 if setting stack size is not supported.
730 */
731static int
732_pythread_pthread_set_stacksize(size_t size)
733{
734#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 pthread_attr_t attrs;
736 size_t tss_min;
737 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000738#endif
739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 /* set to default */
741 if (size == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200742 _PyInterpreterState_GET()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 return 0;
744 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000745
746#if defined(THREAD_STACK_SIZE)
747#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
749 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000750#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000752#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 if (size >= tss_min) {
754 /* validate stack size by setting thread attribute */
755 if (pthread_attr_init(&attrs) == 0) {
756 rc = pthread_attr_setstacksize(&attrs, size);
757 pthread_attr_destroy(&attrs);
758 if (rc == 0) {
Victor Stinner81a7be32020-04-14 15:14:01 +0200759 _PyInterpreterState_GET()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 return 0;
761 }
762 }
763 }
764 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000765#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000767#endif
768}
769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000771
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000772
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900773/* Thread Local Storage (TLS) API
774
775 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
776*/
777
778/* Issue #25658: On platforms where native TLS key is defined in a way that
779 cannot be safely cast to int, PyThread_create_key returns immediately a
780 failure status and other TLS functions all are no-ops. This indicates
781 clearly that the old API is not supported on platforms where it cannot be
782 used reliably, and that no effort will be made to add such support.
783
784 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
785 removing this API.
786*/
787
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000788int
789PyThread_create_key(void)
790{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900791#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000792 pthread_key_t key;
793 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200794 if (fail)
795 return -1;
796 if (key > INT_MAX) {
797 /* Issue #22206: handle integer overflow */
798 pthread_key_delete(key);
799 errno = ENOMEM;
800 return -1;
801 }
802 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900803#else
804 return -1; /* never return valid key value. */
805#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000806}
807
808void
809PyThread_delete_key(int key)
810{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900811#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000812 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900813#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000814}
815
816void
817PyThread_delete_key_value(int key)
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_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900821#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000822}
823
824int
825PyThread_set_key_value(int key, void *value)
826{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900827#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
828 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000829 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900830#else
831 return -1;
832#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000833}
834
835void *
836PyThread_get_key_value(int key)
837{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900838#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000839 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900840#else
841 return NULL;
842#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000843}
844
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900845
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000846void
847PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900848{
849}
850
851
852/* Thread Specific Storage (TSS) API
853
854 Platform-specific components of TSS API implementation.
855*/
856
857int
858PyThread_tss_create(Py_tss_t *key)
859{
860 assert(key != NULL);
861 /* If the key has been created, function is silently skipped. */
862 if (key->_is_initialized) {
863 return 0;
864 }
865
866 int fail = pthread_key_create(&(key->_key), NULL);
867 if (fail) {
868 return -1;
869 }
870 key->_is_initialized = 1;
871 return 0;
872}
873
874void
875PyThread_tss_delete(Py_tss_t *key)
876{
877 assert(key != NULL);
878 /* If the key has not been created, function is silently skipped. */
879 if (!key->_is_initialized) {
880 return;
881 }
882
883 pthread_key_delete(key->_key);
884 /* pthread has not provided the defined invalid value for the key. */
885 key->_is_initialized = 0;
886}
887
888int
889PyThread_tss_set(Py_tss_t *key, void *value)
890{
891 assert(key != NULL);
892 int fail = pthread_setspecific(key->_key, value);
893 return fail ? -1 : 0;
894}
895
896void *
897PyThread_tss_get(Py_tss_t *key)
898{
899 assert(key != NULL);
900 return pthread_getspecific(key->_key);
901}