blob: b9a340530cfe986cbf35d4676ca9b5cd83bb6a1a [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() */
Michael Feltd0eeb932019-06-14 00:34:46 +020021#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
Ronald Oussoren1a057ba2019-08-01 07:43:07 +020043/* 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
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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080055#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
57#ifdef THREAD_STACK_SIZE
58#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
59#endif
60#endif
61
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000062/* The POSIX spec says that implementations supporting the sem_*
63 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000065#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000067 we need to add 0 to make it work there as well. */
68#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000069#define HAVE_BROKEN_POSIX_SEMAPHORES
70#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000071#include <semaphore.h>
72#include <errno.h>
73#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000074#endif
Guido van Rossum66020991996-06-11 18:32:18 +000075
Guido van Rossumd6353e21997-05-13 17:51:13 +000076
Martin v. Löwiscc898662002-03-17 09:53:51 +000077/* Whether or not to use semaphores directly rather than emulating them with
78 * mutexes and condition variables:
79 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000080#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
81 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000082# define USE_SEMAPHORES
83#else
84# undef USE_SEMAPHORES
85#endif
86
87
Guido van Rossum80230992001-10-12 21:49:17 +000088/* On platforms that don't use standard POSIX threads pthread_sigmask()
89 * isn't present. DEC threads uses sigprocmask() instead as do most
90 * other UNIX International compliant systems that don't have the full
91 * pthread implementation.
92 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000093#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000094# define SET_THREAD_SIGMASK pthread_sigmask
95#else
96# define SET_THREAD_SIGMASK sigprocmask
97#endif
98
99
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000100#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
101do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 struct timeval tv; \
Benjamin Petersonf1c19032019-09-10 11:37:59 +0100103 gettimeofday(&tv, NULL); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 tv.tv_usec += microseconds % 1000000; \
105 tv.tv_sec += microseconds / 1000000; \
106 tv.tv_sec += tv.tv_usec / 1000000; \
107 tv.tv_usec %= 1000000; \
108 ts.tv_sec = tv.tv_sec; \
109 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000110} while(0)
111
112
Inada Naoki001fee12019-02-20 10:00:09 +0900113/*
114 * pthread_cond support
115 */
116
117#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
118// monotonic is supported statically. It doesn't mean it works on runtime.
119#define CONDATTR_MONOTONIC
120#endif
121
122// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
123static pthread_condattr_t *condattr_monotonic = NULL;
124
125static void
126init_condattr()
127{
128#ifdef CONDATTR_MONOTONIC
129 static pthread_condattr_t ca;
130 pthread_condattr_init(&ca);
131 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
132 condattr_monotonic = &ca; // Use monotonic clock
133 }
134#endif
135}
136
137int
138_PyThread_cond_init(PyCOND_T *cond)
139{
140 return pthread_cond_init(cond, condattr_monotonic);
141}
142
143void
144_PyThread_cond_after(long long us, struct timespec *abs)
145{
146#ifdef CONDATTR_MONOTONIC
147 if (condattr_monotonic) {
148 clock_gettime(CLOCK_MONOTONIC, abs);
149 abs->tv_sec += us / 1000000;
150 abs->tv_nsec += (us % 1000000) * 1000;
151 abs->tv_sec += abs->tv_nsec / 1000000000;
152 abs->tv_nsec %= 1000000000;
153 return;
154 }
155#endif
156
157 struct timespec ts;
158 MICROSECONDS_TO_TIMESPEC(us, ts);
159 *abs = ts;
160}
161
162
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000163/* A pthread mutex isn't sufficient to model the Python lock type
164 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
165 * following are undefined:
166 * -> a thread tries to lock a mutex it already has locked
167 * -> a thread tries to unlock a mutex locked by a different thread
168 * pthread mutexes are designed for serializing threads over short pieces
169 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000170 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000171 *
172 * The pthread_lock struct implements a Python lock as a "locked?" bit
173 * and a <condition, mutex> pair. In general, if the bit can be acquired
174 * instantly, it is, else the pair is used to block the thread until the
175 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000176 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000177
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000178typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 char locked; /* 0=unlocked, 1=locked */
180 /* a <cond, mutex> pair to handle an acquire of a locked lock */
181 pthread_cond_t lock_released;
182 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000183} pthread_lock;
184
Guido van Rossum9e46e561998-10-07 16:39:47 +0000185#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100186#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
187 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000188
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000189/*
190 * Initialization.
191 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000192static void
193PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000194{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000195#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200196 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000198#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900199 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000200}
201
202/*
203 * Thread support.
204 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000205
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530206/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
207 "void func(void *)" to "void* func(void *)": always return NULL.
208
209 PyThread_start_new_thread() uses "void func(void *)" type, whereas
210 pthread_create() requires a void* return value. */
211typedef struct {
212 void (*func) (void *);
213 void *arg;
214} pythread_callback;
215
216static void *
217pythread_wrapper(void *arg)
218{
219 /* copy func and func_arg and free the temporary structure */
220 pythread_callback *callback = arg;
221 void (*func)(void *) = callback->func;
222 void *func_arg = callback->arg;
223 PyMem_RawFree(arg);
224
225 func(func_arg);
226 return NULL;
227}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000228
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200229unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000230PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 pthread_t th;
233 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000234#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000236#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000237#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000239#endif
240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 dprintf(("PyThread_start_new_thread called\n"));
242 if (!initialized)
243 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000244
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000245#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200247 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000248#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000249#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100250 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600251 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
252 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 if (tss != 0) {
254 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
255 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200256 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 }
258 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000259#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000262#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000263
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530264 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
265
266 if (callback == NULL) {
267 return PYTHREAD_INVALID_THREAD_ID;
268 }
269
270 callback->func = func;
271 callback->arg = arg;
272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000274#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000276#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000278#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530279 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000280
Fred Drake03459a52001-11-09 16:00:41 +0000281#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000283#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530284
285 if (status != 0) {
286 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200287 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530288 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000291
Guido van Rossum3c288632001-10-16 21:13:49 +0000292#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200293 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000294#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200295 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000296#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000297}
298
Trent Mick635f6fb2000-08-23 21:33:05 +0000299/* XXX This implementation is considered (to quote Tim Peters) "inherently
300 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000301 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200302 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100303 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000304*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200305unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000306PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 volatile pthread_t threadid;
309 if (!initialized)
310 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200312 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000313}
314
Jake Teslerb121f632019-05-22 08:43:17 -0700315#ifdef PY_HAVE_THREAD_NATIVE_ID
316unsigned long
317PyThread_get_thread_native_id(void)
318{
319 if (!initialized)
320 PyThread_init_thread();
321#ifdef __APPLE__
322 uint64_t native_id;
323 (void) pthread_threadid_np(NULL, &native_id);
324#elif defined(__linux__)
325 pid_t native_id;
326 native_id = syscall(SYS_gettid);
327#elif defined(__FreeBSD__)
328 int native_id;
329 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100330#elif defined(__OpenBSD__)
331 pid_t native_id;
332 native_id = getthrid();
Michael Feltd0eeb932019-06-14 00:34:46 +0200333#elif defined(_AIX)
334 tid_t native_id;
335 native_id = thread_self();
David Carlier52870222019-06-12 15:37:56 +0000336#elif defined(__NetBSD__)
337 lwpid_t native_id;
338 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700339#endif
340 return (unsigned long) native_id;
341}
342#endif
343
Victor Stinnerc664b342019-05-04 11:48:05 -0400344void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000345PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000346{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200348 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200350 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000351}
352
Martin v. Löwiscc898662002-03-17 09:53:51 +0000353#ifdef USE_SEMAPHORES
354
355/*
356 * Lock support.
357 */
358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000360PyThread_allocate_lock(void)
361{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 sem_t *lock;
363 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 dprintf(("PyThread_allocate_lock called\n"));
366 if (!initialized)
367 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000368
Victor Stinner80aa5652013-07-07 17:17:59 +0200369 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 if (lock) {
372 status = sem_init(lock,0,1);
373 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200376 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 lock = NULL;
378 }
379 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000380
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600381 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000383}
384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000386PyThread_free_lock(PyThread_type_lock lock)
387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 sem_t *thelock = (sem_t *)lock;
389 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000390
Christian Heimes56379c02012-12-02 08:37:00 +0100391 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 if (!thelock)
395 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 status = sem_destroy(thelock);
398 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000399
Victor Stinner80aa5652013-07-07 17:17:59 +0200400 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000401}
402
403/*
404 * As of February 2002, Cygwin thread implementations mistakenly report error
405 * codes in the return value of the sem_ calls (like the pthread_ functions).
406 * Correct implementations return -1 and put the code in errno. This supports
407 * either.
408 */
409static int
410fix_status(int status)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000413}
414
Antoine Pitrou810023d2010-12-15 22:59:16 +0000415PyLockStatus
416PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
417 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000418{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000419 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 sem_t *thelock = (sem_t *)lock;
421 int status, error = 0;
422 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700423 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000424
Christian Heimes56379c02012-12-02 08:37:00 +0100425 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000426 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
427 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000428
Victor Stinner850a18e2017-10-24 16:53:32 -0700429 if (microseconds > PY_TIMEOUT_MAX) {
430 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
431 }
432
433 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700435
436 if (!intr_flag) {
437 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
438 check done above */
439 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
440 deadline = _PyTime_GetMonotonicClock() + timeout;
441 }
442 }
443
444 while (1) {
445 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700447 }
448 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700450 }
451 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700453 }
454
Antoine Pitrou810023d2010-12-15 22:59:16 +0000455 /* Retry if interrupted by a signal, unless the caller wants to be
456 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700457 if (intr_flag || status != EINTR) {
458 break;
459 }
460
461 if (microseconds > 0) {
462 /* wait interrupted by a signal (EINTR): recompute the timeout */
463 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
464 if (dt < 0) {
465 status = ETIMEDOUT;
466 break;
467 }
468 else if (dt > 0) {
469 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
470 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
471 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
472 check done above */
473 Py_UNREACHABLE();
474 }
475 /* no need to update microseconds value, the code only care
476 if (microseconds > 0 or (microseconds == 0). */
477 }
478 else {
479 microseconds = 0;
480 }
481 }
482 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000483
Antoine Pitrou810023d2010-12-15 22:59:16 +0000484 /* Don't check the status if we're stopping because of an interrupt. */
485 if (!(intr_flag && status == EINTR)) {
486 if (microseconds > 0) {
487 if (status != ETIMEDOUT)
488 CHECK_STATUS("sem_timedwait");
489 }
490 else if (microseconds == 0) {
491 if (status != EAGAIN)
492 CHECK_STATUS("sem_trywait");
493 }
494 else {
495 CHECK_STATUS("sem_wait");
496 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000498
Antoine Pitrou810023d2010-12-15 22:59:16 +0000499 if (status == 0) {
500 success = PY_LOCK_ACQUIRED;
501 } else if (intr_flag && status == EINTR) {
502 success = PY_LOCK_INTR;
503 } else {
504 success = PY_LOCK_FAILURE;
505 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506
Antoine Pitrou810023d2010-12-15 22:59:16 +0000507 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
508 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000510}
511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000513PyThread_release_lock(PyThread_type_lock lock)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 sem_t *thelock = (sem_t *)lock;
516 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000517
Christian Heimes56379c02012-12-02 08:37:00 +0100518 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 status = sem_post(thelock);
522 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000523}
524
525#else /* USE_SEMAPHORES */
526
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000527/*
528 * Lock support.
529 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000531PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000532{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 pthread_lock *lock;
534 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 dprintf(("PyThread_allocate_lock called\n"));
537 if (!initialized)
538 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000539
Victor Stinner80aa5652013-07-07 17:17:59 +0200540 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 if (lock) {
542 memset((void *)lock, '\0', sizeof(pthread_lock));
543 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000544
Inada Naoki001fee12019-02-20 10:00:09 +0900545 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100546 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 /* Mark the pthread mutex underlying a Python mutex as
548 pure happens-before. We can't simply mark the
549 Python-level mutex as a mutex because it can be
550 acquired and released in different threads, which
551 will cause errors. */
552 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000553
Inada Naoki001fee12019-02-20 10:00:09 +0900554 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100555 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200558 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 lock = 0;
560 }
561 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000562
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600563 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000565}
566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000568PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000569{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 pthread_lock *thelock = (pthread_lock *)lock;
571 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000572
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200573 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000575
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000576 /* some pthread-like implementations tie the mutex to the cond
577 * and must have the cond destroyed first.
578 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100580 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000581
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000582 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100583 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000584
Victor Stinner80aa5652013-07-07 17:17:59 +0200585 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000586}
587
Antoine Pitrou810023d2010-12-15 22:59:16 +0000588PyLockStatus
589PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
590 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000591{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200592 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 pthread_lock *thelock = (pthread_lock *)lock;
594 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000595
Antoine Pitrou810023d2010-12-15 22:59:16 +0000596 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
597 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000598
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200599 if (microseconds == 0) {
600 status = pthread_mutex_trylock( &thelock->mut );
601 if (status != EBUSY)
602 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
603 }
604 else {
605 status = pthread_mutex_lock( &thelock->mut );
606 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
607 }
608 if (status == 0) {
609 if (thelock->locked == 0) {
610 success = PY_LOCK_ACQUIRED;
611 }
612 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900613 struct timespec abs;
614 if (microseconds > 0) {
615 _PyThread_cond_after(microseconds, &abs);
616 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200617 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000618
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200619 /* mut must be locked by me -- part of the condition
620 * protocol */
621 while (success == PY_LOCK_FAILURE) {
622 if (microseconds > 0) {
623 status = pthread_cond_timedwait(
624 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900625 &thelock->mut, &abs);
626 if (status == 1) {
627 break;
628 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200629 if (status == ETIMEDOUT)
630 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900631 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200632 }
633 else {
634 status = pthread_cond_wait(
635 &thelock->lock_released,
636 &thelock->mut);
637 CHECK_STATUS_PTHREAD("pthread_cond_wait");
638 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000639
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200640 if (intr_flag && status == 0 && thelock->locked) {
641 /* We were woken up, but didn't get the lock. We probably received
642 * a signal. Return PY_LOCK_INTR to allow the caller to handle
643 * it and retry. */
644 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200646 }
647 else if (status == 0 && !thelock->locked) {
648 success = PY_LOCK_ACQUIRED;
649 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000650 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200652 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
653 status = pthread_mutex_unlock( &thelock->mut );
654 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000656
Antoine Pitrou810023d2010-12-15 22:59:16 +0000657 if (error) success = PY_LOCK_FAILURE;
658 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
659 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000661}
662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000664PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000665{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 pthread_lock *thelock = (pthread_lock *)lock;
667 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000668
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200669 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000671
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100673 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000676
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 /* wake up someone (anyone, if any) waiting on the lock */
678 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100679 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000680
681 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100682 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000683}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000684
685#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000686
Antoine Pitrou810023d2010-12-15 22:59:16 +0000687int
688PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
689{
690 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
691}
692
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000693/* set the thread stack size.
694 * Return 0 if size is valid, -1 if size is invalid,
695 * -2 if setting stack size is not supported.
696 */
697static int
698_pythread_pthread_set_stacksize(size_t size)
699{
700#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 pthread_attr_t attrs;
702 size_t tss_min;
703 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000704#endif
705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 /* set to default */
707 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100708 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 return 0;
710 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000711
712#if defined(THREAD_STACK_SIZE)
713#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
715 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000716#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000718#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 if (size >= tss_min) {
720 /* validate stack size by setting thread attribute */
721 if (pthread_attr_init(&attrs) == 0) {
722 rc = pthread_attr_setstacksize(&attrs, size);
723 pthread_attr_destroy(&attrs);
724 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100725 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 return 0;
727 }
728 }
729 }
730 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000731#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000733#endif
734}
735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000737
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000738
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900739/* Thread Local Storage (TLS) API
740
741 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
742*/
743
744/* Issue #25658: On platforms where native TLS key is defined in a way that
745 cannot be safely cast to int, PyThread_create_key returns immediately a
746 failure status and other TLS functions all are no-ops. This indicates
747 clearly that the old API is not supported on platforms where it cannot be
748 used reliably, and that no effort will be made to add such support.
749
750 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
751 removing this API.
752*/
753
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000754int
755PyThread_create_key(void)
756{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900757#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000758 pthread_key_t key;
759 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200760 if (fail)
761 return -1;
762 if (key > INT_MAX) {
763 /* Issue #22206: handle integer overflow */
764 pthread_key_delete(key);
765 errno = ENOMEM;
766 return -1;
767 }
768 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900769#else
770 return -1; /* never return valid key value. */
771#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000772}
773
774void
775PyThread_delete_key(int key)
776{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900777#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000778 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900779#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000780}
781
782void
783PyThread_delete_key_value(int key)
784{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900785#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000786 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900787#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000788}
789
790int
791PyThread_set_key_value(int key, void *value)
792{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900793#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
794 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000795 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900796#else
797 return -1;
798#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000799}
800
801void *
802PyThread_get_key_value(int key)
803{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900804#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000805 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900806#else
807 return NULL;
808#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000809}
810
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900811
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000812void
813PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900814{
815}
816
817
818/* Thread Specific Storage (TSS) API
819
820 Platform-specific components of TSS API implementation.
821*/
822
823int
824PyThread_tss_create(Py_tss_t *key)
825{
826 assert(key != NULL);
827 /* If the key has been created, function is silently skipped. */
828 if (key->_is_initialized) {
829 return 0;
830 }
831
832 int fail = pthread_key_create(&(key->_key), NULL);
833 if (fail) {
834 return -1;
835 }
836 key->_is_initialized = 1;
837 return 0;
838}
839
840void
841PyThread_tss_delete(Py_tss_t *key)
842{
843 assert(key != NULL);
844 /* If the key has not been created, function is silently skipped. */
845 if (!key->_is_initialized) {
846 return;
847 }
848
849 pthread_key_delete(key->_key);
850 /* pthread has not provided the defined invalid value for the key. */
851 key->_is_initialized = 0;
852}
853
854int
855PyThread_tss_set(Py_tss_t *key, void *value)
856{
857 assert(key != NULL);
858 int fail = pthread_setspecific(key->_key, value);
859 return fail ? -1 : 0;
860}
861
862void *
863PyThread_tss_get(Py_tss_t *key)
864{
865 assert(key != NULL);
866 return pthread_getspecific(key->_key);
867}