blob: 994e35b2cc0803cc0c02bd3b42ff686a873802c9 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001
Guido van Rossum66020991996-06-11 18:32:18 +00002/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00003
Guido van Rossum66020991996-06-11 18:32:18 +00004#include <stdlib.h>
Guido van Rossum9e46e561998-10-07 16:39:47 +00005#include <string.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +00006#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +00007#define destructor xxdestructor
8#endif
Guido van Rossum66020991996-06-11 18:32:18 +00009#include <pthread.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +000010#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +000011#undef destructor
12#endif
Guido van Rossum80230992001-10-12 21:49:17 +000013#include <signal.h>
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000014
Jake Teslerb121f632019-05-22 08:43:17 -070015#if defined(__linux__)
16# include <sys/syscall.h> /* syscall(SYS_gettid) */
17#elif defined(__FreeBSD__)
18# include <pthread_np.h> /* pthread_getthreadid_np() */
David Carlier0b9956e2019-06-03 16:43:33 +010019#elif defined(__OpenBSD__)
20# include <unistd.h> /* getthrid() */
Miss Islington (bot)886d83e2019-06-13 15:54:04 -070021#elif defined(_AIX)
22# include <sys/thread.h> /* thread_self() */
23#elif defined(__NetBSD__)
24# include <lwp.h> /* _lwp_self() */
Jake Teslerb121f632019-05-22 08:43:17 -070025#endif
26
Thomas Wouters0e3f5912006-08-11 14:57:12 +000027/* The POSIX spec requires that use of pthread_attr_setstacksize
28 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
29#ifdef _POSIX_THREAD_ATTR_STACKSIZE
30#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070033
Ned Deily7ca97d52012-03-13 11:18:18 -070034/* The default stack size for new threads on OSX and BSD is small enough that
35 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
36 * exceptions.
37 *
38 * The default stack sizes below are the empirically determined minimal stack
39 * sizes where a simple recursive function doesn't cause a hard crash.
40 */
41#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
42#undef THREAD_STACK_SIZE
Miss Islington (bot)83996412019-08-01 07:38:57 -070043/* Note: This matches the value of -Wl,-stack_size in configure.ac */
44#define THREAD_STACK_SIZE 0x1000000
Ned Deily7ca97d52012-03-13 11:18:18 -070045#endif
46#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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080051#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
53#ifdef THREAD_STACK_SIZE
54#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
55#endif
56#endif
57
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000058/* The POSIX spec says that implementations supporting the sem_*
59 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000061#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000062/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000063 we need to add 0 to make it work there as well. */
64#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000065#define HAVE_BROKEN_POSIX_SEMAPHORES
66#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000067#include <semaphore.h>
68#include <errno.h>
69#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000070#endif
Guido van Rossum66020991996-06-11 18:32:18 +000071
Guido van Rossumd6353e21997-05-13 17:51:13 +000072
Martin v. Löwiscc898662002-03-17 09:53:51 +000073/* Whether or not to use semaphores directly rather than emulating them with
74 * mutexes and condition variables:
75 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000076#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
77 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000078# define USE_SEMAPHORES
79#else
80# undef USE_SEMAPHORES
81#endif
82
83
Guido van Rossum80230992001-10-12 21:49:17 +000084/* On platforms that don't use standard POSIX threads pthread_sigmask()
85 * isn't present. DEC threads uses sigprocmask() instead as do most
86 * other UNIX International compliant systems that don't have the full
87 * pthread implementation.
88 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000089#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000090# define SET_THREAD_SIGMASK pthread_sigmask
91#else
92# define SET_THREAD_SIGMASK sigprocmask
93#endif
94
95
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000096/* We assume all modern POSIX systems have gettimeofday() */
97#ifdef GETTIMEOFDAY_NO_TZ
98#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
99#else
100#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
101#endif
102
103#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
104do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 struct timeval tv; \
106 GETTIMEOFDAY(&tv); \
107 tv.tv_usec += microseconds % 1000000; \
108 tv.tv_sec += microseconds / 1000000; \
109 tv.tv_sec += tv.tv_usec / 1000000; \
110 tv.tv_usec %= 1000000; \
111 ts.tv_sec = tv.tv_sec; \
112 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000113} while(0)
114
115
Inada Naoki001fee12019-02-20 10:00:09 +0900116/*
117 * pthread_cond support
118 */
119
120#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
121// monotonic is supported statically. It doesn't mean it works on runtime.
122#define CONDATTR_MONOTONIC
123#endif
124
125// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
126static pthread_condattr_t *condattr_monotonic = NULL;
127
128static void
129init_condattr()
130{
131#ifdef CONDATTR_MONOTONIC
132 static pthread_condattr_t ca;
133 pthread_condattr_init(&ca);
134 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
135 condattr_monotonic = &ca; // Use monotonic clock
136 }
137#endif
138}
139
140int
141_PyThread_cond_init(PyCOND_T *cond)
142{
143 return pthread_cond_init(cond, condattr_monotonic);
144}
145
146void
147_PyThread_cond_after(long long us, struct timespec *abs)
148{
149#ifdef CONDATTR_MONOTONIC
150 if (condattr_monotonic) {
151 clock_gettime(CLOCK_MONOTONIC, abs);
152 abs->tv_sec += us / 1000000;
153 abs->tv_nsec += (us % 1000000) * 1000;
154 abs->tv_sec += abs->tv_nsec / 1000000000;
155 abs->tv_nsec %= 1000000000;
156 return;
157 }
158#endif
159
160 struct timespec ts;
161 MICROSECONDS_TO_TIMESPEC(us, ts);
162 *abs = ts;
163}
164
165
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000166/* A pthread mutex isn't sufficient to model the Python lock type
167 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
168 * following are undefined:
169 * -> a thread tries to lock a mutex it already has locked
170 * -> a thread tries to unlock a mutex locked by a different thread
171 * pthread mutexes are designed for serializing threads over short pieces
172 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000173 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000174 *
175 * The pthread_lock struct implements a Python lock as a "locked?" bit
176 * and a <condition, mutex> pair. In general, if the bit can be acquired
177 * instantly, it is, else the pair is used to block the thread until the
178 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000179 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000180
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000181typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 char locked; /* 0=unlocked, 1=locked */
183 /* a <cond, mutex> pair to handle an acquire of a locked lock */
184 pthread_cond_t lock_released;
185 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000186} pthread_lock;
187
Guido van Rossum9e46e561998-10-07 16:39:47 +0000188#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100189#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
190 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000191
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000192/*
193 * Initialization.
194 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000195static void
196PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000197{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000198#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200199 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000201#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900202 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000203}
204
205/*
206 * Thread support.
207 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000208
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530209/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
210 "void func(void *)" to "void* func(void *)": always return NULL.
211
212 PyThread_start_new_thread() uses "void func(void *)" type, whereas
213 pthread_create() requires a void* return value. */
214typedef struct {
215 void (*func) (void *);
216 void *arg;
217} pythread_callback;
218
219static void *
220pythread_wrapper(void *arg)
221{
222 /* copy func and func_arg and free the temporary structure */
223 pythread_callback *callback = arg;
224 void (*func)(void *) = callback->func;
225 void *func_arg = callback->arg;
226 PyMem_RawFree(arg);
227
228 func(func_arg);
229 return NULL;
230}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000231
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200232unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000233PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 pthread_t th;
236 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000237#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000239#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000240#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000242#endif
243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 dprintf(("PyThread_start_new_thread called\n"));
245 if (!initialized)
246 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000247
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 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200250 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000251#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000252#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100253 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600254 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
255 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 if (tss != 0) {
257 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
258 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200259 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 }
261 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000262#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000265#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000266
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530267 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
268
269 if (callback == NULL) {
270 return PYTHREAD_INVALID_THREAD_ID;
271 }
272
273 callback->func = func;
274 callback->arg = arg;
275
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000277#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000279#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000281#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530282 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000283
Fred Drake03459a52001-11-09 16:00:41 +0000284#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000286#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530287
288 if (status != 0) {
289 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200290 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530291 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000294
Guido van Rossum3c288632001-10-16 21:13:49 +0000295#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200296 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000297#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200298 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000299#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000300}
301
Trent Mick635f6fb2000-08-23 21:33:05 +0000302/* XXX This implementation is considered (to quote Tim Peters) "inherently
303 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000304 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200305 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100306 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000307*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200308unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000309PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000310{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 volatile pthread_t threadid;
312 if (!initialized)
313 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200315 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000316}
317
Jake Teslerb121f632019-05-22 08:43:17 -0700318#ifdef PY_HAVE_THREAD_NATIVE_ID
319unsigned long
320PyThread_get_thread_native_id(void)
321{
322 if (!initialized)
323 PyThread_init_thread();
324#ifdef __APPLE__
325 uint64_t native_id;
326 (void) pthread_threadid_np(NULL, &native_id);
327#elif defined(__linux__)
328 pid_t native_id;
329 native_id = syscall(SYS_gettid);
330#elif defined(__FreeBSD__)
331 int native_id;
332 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100333#elif defined(__OpenBSD__)
334 pid_t native_id;
335 native_id = getthrid();
Miss Islington (bot)886d83e2019-06-13 15:54:04 -0700336#elif defined(_AIX)
337 tid_t native_id;
338 native_id = thread_self();
Miss Islington (bot)c9ca96d2019-06-12 09:03:04 -0700339#elif defined(__NetBSD__)
340 lwpid_t native_id;
341 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700342#endif
343 return (unsigned long) native_id;
344}
345#endif
346
Victor Stinnerc664b342019-05-04 11:48:05 -0400347void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000348PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200351 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200353 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000354}
355
Martin v. Löwiscc898662002-03-17 09:53:51 +0000356#ifdef USE_SEMAPHORES
357
358/*
359 * Lock support.
360 */
361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000363PyThread_allocate_lock(void)
364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 sem_t *lock;
366 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 dprintf(("PyThread_allocate_lock called\n"));
369 if (!initialized)
370 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000371
Victor Stinner80aa5652013-07-07 17:17:59 +0200372 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (lock) {
375 status = sem_init(lock,0,1);
376 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200379 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 lock = NULL;
381 }
382 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000383
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600384 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000386}
387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000389PyThread_free_lock(PyThread_type_lock lock)
390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 sem_t *thelock = (sem_t *)lock;
392 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000393
Christian Heimes56379c02012-12-02 08:37:00 +0100394 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 if (!thelock)
398 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 status = sem_destroy(thelock);
401 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000402
Victor Stinner80aa5652013-07-07 17:17:59 +0200403 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000404}
405
406/*
407 * As of February 2002, Cygwin thread implementations mistakenly report error
408 * codes in the return value of the sem_ calls (like the pthread_ functions).
409 * Correct implementations return -1 and put the code in errno. This supports
410 * either.
411 */
412static int
413fix_status(int status)
414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000416}
417
Antoine Pitrou810023d2010-12-15 22:59:16 +0000418PyLockStatus
419PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
420 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000421{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000422 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 sem_t *thelock = (sem_t *)lock;
424 int status, error = 0;
425 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700426 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000427
Christian Heimes56379c02012-12-02 08:37:00 +0100428 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000429 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
430 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000431
Victor Stinner850a18e2017-10-24 16:53:32 -0700432 if (microseconds > PY_TIMEOUT_MAX) {
433 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
434 }
435
436 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700438
439 if (!intr_flag) {
440 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
441 check done above */
442 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
443 deadline = _PyTime_GetMonotonicClock() + timeout;
444 }
445 }
446
447 while (1) {
448 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700450 }
451 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700453 }
454 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700456 }
457
Antoine Pitrou810023d2010-12-15 22:59:16 +0000458 /* Retry if interrupted by a signal, unless the caller wants to be
459 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700460 if (intr_flag || status != EINTR) {
461 break;
462 }
463
464 if (microseconds > 0) {
465 /* wait interrupted by a signal (EINTR): recompute the timeout */
466 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
467 if (dt < 0) {
468 status = ETIMEDOUT;
469 break;
470 }
471 else if (dt > 0) {
472 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
473 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
474 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
475 check done above */
476 Py_UNREACHABLE();
477 }
478 /* no need to update microseconds value, the code only care
479 if (microseconds > 0 or (microseconds == 0). */
480 }
481 else {
482 microseconds = 0;
483 }
484 }
485 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000486
Antoine Pitrou810023d2010-12-15 22:59:16 +0000487 /* Don't check the status if we're stopping because of an interrupt. */
488 if (!(intr_flag && status == EINTR)) {
489 if (microseconds > 0) {
490 if (status != ETIMEDOUT)
491 CHECK_STATUS("sem_timedwait");
492 }
493 else if (microseconds == 0) {
494 if (status != EAGAIN)
495 CHECK_STATUS("sem_trywait");
496 }
497 else {
498 CHECK_STATUS("sem_wait");
499 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000501
Antoine Pitrou810023d2010-12-15 22:59:16 +0000502 if (status == 0) {
503 success = PY_LOCK_ACQUIRED;
504 } else if (intr_flag && status == EINTR) {
505 success = PY_LOCK_INTR;
506 } else {
507 success = PY_LOCK_FAILURE;
508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509
Antoine Pitrou810023d2010-12-15 22:59:16 +0000510 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
511 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000513}
514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000516PyThread_release_lock(PyThread_type_lock lock)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 sem_t *thelock = (sem_t *)lock;
519 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000520
Christian Heimes56379c02012-12-02 08:37:00 +0100521 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 status = sem_post(thelock);
525 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000526}
527
528#else /* USE_SEMAPHORES */
529
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000530/*
531 * Lock support.
532 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000534PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 pthread_lock *lock;
537 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 dprintf(("PyThread_allocate_lock called\n"));
540 if (!initialized)
541 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000542
Victor Stinner80aa5652013-07-07 17:17:59 +0200543 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 if (lock) {
545 memset((void *)lock, '\0', sizeof(pthread_lock));
546 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000547
Inada Naoki001fee12019-02-20 10:00:09 +0900548 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100549 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 /* Mark the pthread mutex underlying a Python mutex as
551 pure happens-before. We can't simply mark the
552 Python-level mutex as a mutex because it can be
553 acquired and released in different threads, which
554 will cause errors. */
555 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000556
Inada Naoki001fee12019-02-20 10:00:09 +0900557 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100558 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200561 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 lock = 0;
563 }
564 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000565
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600566 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000568}
569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000571PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 pthread_lock *thelock = (pthread_lock *)lock;
574 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000575
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200576 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000578
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000579 /* some pthread-like implementations tie the mutex to the cond
580 * and must have the cond destroyed first.
581 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100583 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000584
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000585 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100586 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000587
Victor Stinner80aa5652013-07-07 17:17:59 +0200588 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000589}
590
Antoine Pitrou810023d2010-12-15 22:59:16 +0000591PyLockStatus
592PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
593 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000594{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200595 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 pthread_lock *thelock = (pthread_lock *)lock;
597 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000598
Antoine Pitrou810023d2010-12-15 22:59:16 +0000599 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
600 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000601
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200602 if (microseconds == 0) {
603 status = pthread_mutex_trylock( &thelock->mut );
604 if (status != EBUSY)
605 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
606 }
607 else {
608 status = pthread_mutex_lock( &thelock->mut );
609 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
610 }
611 if (status == 0) {
612 if (thelock->locked == 0) {
613 success = PY_LOCK_ACQUIRED;
614 }
615 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900616 struct timespec abs;
617 if (microseconds > 0) {
618 _PyThread_cond_after(microseconds, &abs);
619 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200620 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000621
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200622 /* mut must be locked by me -- part of the condition
623 * protocol */
624 while (success == PY_LOCK_FAILURE) {
625 if (microseconds > 0) {
626 status = pthread_cond_timedwait(
627 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900628 &thelock->mut, &abs);
629 if (status == 1) {
630 break;
631 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200632 if (status == ETIMEDOUT)
633 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900634 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200635 }
636 else {
637 status = pthread_cond_wait(
638 &thelock->lock_released,
639 &thelock->mut);
640 CHECK_STATUS_PTHREAD("pthread_cond_wait");
641 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000642
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200643 if (intr_flag && status == 0 && thelock->locked) {
644 /* We were woken up, but didn't get the lock. We probably received
645 * a signal. Return PY_LOCK_INTR to allow the caller to handle
646 * it and retry. */
647 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200649 }
650 else if (status == 0 && !thelock->locked) {
651 success = PY_LOCK_ACQUIRED;
652 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000653 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200655 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
656 status = pthread_mutex_unlock( &thelock->mut );
657 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000659
Antoine Pitrou810023d2010-12-15 22:59:16 +0000660 if (error) success = PY_LOCK_FAILURE;
661 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
662 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000664}
665
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000667PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000668{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 pthread_lock *thelock = (pthread_lock *)lock;
670 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000671
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200672 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100676 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 /* wake up someone (anyone, if any) waiting on the lock */
681 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100682 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000683
684 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100685 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000686}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000687
688#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000689
Antoine Pitrou810023d2010-12-15 22:59:16 +0000690int
691PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
692{
693 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
694}
695
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000696/* set the thread stack size.
697 * Return 0 if size is valid, -1 if size is invalid,
698 * -2 if setting stack size is not supported.
699 */
700static int
701_pythread_pthread_set_stacksize(size_t size)
702{
703#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 pthread_attr_t attrs;
705 size_t tss_min;
706 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000707#endif
708
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 /* set to default */
710 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100711 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 return 0;
713 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000714
715#if defined(THREAD_STACK_SIZE)
716#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
718 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000719#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000721#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 if (size >= tss_min) {
723 /* validate stack size by setting thread attribute */
724 if (pthread_attr_init(&attrs) == 0) {
725 rc = pthread_attr_setstacksize(&attrs, size);
726 pthread_attr_destroy(&attrs);
727 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100728 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 return 0;
730 }
731 }
732 }
733 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000734#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000736#endif
737}
738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000740
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000741
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900742/* Thread Local Storage (TLS) API
743
744 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
745*/
746
747/* Issue #25658: On platforms where native TLS key is defined in a way that
748 cannot be safely cast to int, PyThread_create_key returns immediately a
749 failure status and other TLS functions all are no-ops. This indicates
750 clearly that the old API is not supported on platforms where it cannot be
751 used reliably, and that no effort will be made to add such support.
752
753 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
754 removing this API.
755*/
756
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000757int
758PyThread_create_key(void)
759{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900760#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000761 pthread_key_t key;
762 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200763 if (fail)
764 return -1;
765 if (key > INT_MAX) {
766 /* Issue #22206: handle integer overflow */
767 pthread_key_delete(key);
768 errno = ENOMEM;
769 return -1;
770 }
771 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900772#else
773 return -1; /* never return valid key value. */
774#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000775}
776
777void
778PyThread_delete_key(int key)
779{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900780#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000781 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900782#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000783}
784
785void
786PyThread_delete_key_value(int key)
787{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900788#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000789 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900790#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000791}
792
793int
794PyThread_set_key_value(int key, void *value)
795{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900796#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
797 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000798 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900799#else
800 return -1;
801#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000802}
803
804void *
805PyThread_get_key_value(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 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900809#else
810 return NULL;
811#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000812}
813
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900814
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000815void
816PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900817{
818}
819
820
821/* Thread Specific Storage (TSS) API
822
823 Platform-specific components of TSS API implementation.
824*/
825
826int
827PyThread_tss_create(Py_tss_t *key)
828{
829 assert(key != NULL);
830 /* If the key has been created, function is silently skipped. */
831 if (key->_is_initialized) {
832 return 0;
833 }
834
835 int fail = pthread_key_create(&(key->_key), NULL);
836 if (fail) {
837 return -1;
838 }
839 key->_is_initialized = 1;
840 return 0;
841}
842
843void
844PyThread_tss_delete(Py_tss_t *key)
845{
846 assert(key != NULL);
847 /* If the key has not been created, function is silently skipped. */
848 if (!key->_is_initialized) {
849 return;
850 }
851
852 pthread_key_delete(key->_key);
853 /* pthread has not provided the defined invalid value for the key. */
854 key->_is_initialized = 0;
855}
856
857int
858PyThread_tss_set(Py_tss_t *key, void *value)
859{
860 assert(key != NULL);
861 int fail = pthread_setspecific(key->_key, value);
862 return fail ? -1 : 0;
863}
864
865void *
866PyThread_tss_get(Py_tss_t *key)
867{
868 assert(key != NULL);
869 return pthread_getspecific(key->_key);
870}