blob: 87c98d3e93cb773d80083ac7c6fb4469b71779ae [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 Tesler4959c332019-05-12 10:08:24 -070015#if defined(__linux__)
16#include <sys/syscall.h>
17#elif defined(__FreeBSD__)
18#include <pthread_np.h>
19#endif
20
Thomas Wouters0e3f5912006-08-11 14:57:12 +000021/* The POSIX spec requires that use of pthread_attr_setstacksize
22 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
23#ifdef _POSIX_THREAD_ATTR_STACKSIZE
24#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000025#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000026#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070027
Ned Deily7ca97d52012-03-13 11:18:18 -070028/* The default stack size for new threads on OSX and BSD is small enough that
29 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
30 * exceptions.
31 *
32 * The default stack sizes below are the empirically determined minimal stack
33 * sizes where a simple recursive function doesn't cause a hard crash.
34 */
35#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
36#undef THREAD_STACK_SIZE
37#define THREAD_STACK_SIZE 0x500000
38#endif
39#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070040#undef THREAD_STACK_SIZE
41#define THREAD_STACK_SIZE 0x400000
42#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000043/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080044#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000045#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
46#ifdef THREAD_STACK_SIZE
47#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
48#endif
49#endif
50
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000051/* The POSIX spec says that implementations supporting the sem_*
52 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000053 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000054#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000056 we need to add 0 to make it work there as well. */
57#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000058#define HAVE_BROKEN_POSIX_SEMAPHORES
59#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000060#include <semaphore.h>
61#include <errno.h>
62#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000063#endif
Guido van Rossum66020991996-06-11 18:32:18 +000064
Guido van Rossumd6353e21997-05-13 17:51:13 +000065
Martin v. Löwiscc898662002-03-17 09:53:51 +000066/* Whether or not to use semaphores directly rather than emulating them with
67 * mutexes and condition variables:
68 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000069#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
70 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000071# define USE_SEMAPHORES
72#else
73# undef USE_SEMAPHORES
74#endif
75
76
Guido van Rossum80230992001-10-12 21:49:17 +000077/* On platforms that don't use standard POSIX threads pthread_sigmask()
78 * isn't present. DEC threads uses sigprocmask() instead as do most
79 * other UNIX International compliant systems that don't have the full
80 * pthread implementation.
81 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000082#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000083# define SET_THREAD_SIGMASK pthread_sigmask
84#else
85# define SET_THREAD_SIGMASK sigprocmask
86#endif
87
88
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000089/* We assume all modern POSIX systems have gettimeofday() */
90#ifdef GETTIMEOFDAY_NO_TZ
91#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
92#else
93#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
94#endif
95
96#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
97do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 struct timeval tv; \
99 GETTIMEOFDAY(&tv); \
100 tv.tv_usec += microseconds % 1000000; \
101 tv.tv_sec += microseconds / 1000000; \
102 tv.tv_sec += tv.tv_usec / 1000000; \
103 tv.tv_usec %= 1000000; \
104 ts.tv_sec = tv.tv_sec; \
105 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000106} while(0)
107
108
Inada Naoki001fee12019-02-20 10:00:09 +0900109/*
110 * pthread_cond support
111 */
112
113#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
114// monotonic is supported statically. It doesn't mean it works on runtime.
115#define CONDATTR_MONOTONIC
116#endif
117
118// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
119static pthread_condattr_t *condattr_monotonic = NULL;
120
121static void
122init_condattr()
123{
124#ifdef CONDATTR_MONOTONIC
125 static pthread_condattr_t ca;
126 pthread_condattr_init(&ca);
127 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
128 condattr_monotonic = &ca; // Use monotonic clock
129 }
130#endif
131}
132
133int
134_PyThread_cond_init(PyCOND_T *cond)
135{
136 return pthread_cond_init(cond, condattr_monotonic);
137}
138
139void
140_PyThread_cond_after(long long us, struct timespec *abs)
141{
142#ifdef CONDATTR_MONOTONIC
143 if (condattr_monotonic) {
144 clock_gettime(CLOCK_MONOTONIC, abs);
145 abs->tv_sec += us / 1000000;
146 abs->tv_nsec += (us % 1000000) * 1000;
147 abs->tv_sec += abs->tv_nsec / 1000000000;
148 abs->tv_nsec %= 1000000000;
149 return;
150 }
151#endif
152
153 struct timespec ts;
154 MICROSECONDS_TO_TIMESPEC(us, ts);
155 *abs = ts;
156}
157
158
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000159/* A pthread mutex isn't sufficient to model the Python lock type
160 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
161 * following are undefined:
162 * -> a thread tries to lock a mutex it already has locked
163 * -> a thread tries to unlock a mutex locked by a different thread
164 * pthread mutexes are designed for serializing threads over short pieces
165 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000166 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000167 *
168 * The pthread_lock struct implements a Python lock as a "locked?" bit
169 * and a <condition, mutex> pair. In general, if the bit can be acquired
170 * instantly, it is, else the pair is used to block the thread until the
171 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000172 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000173
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000174typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 char locked; /* 0=unlocked, 1=locked */
176 /* a <cond, mutex> pair to handle an acquire of a locked lock */
177 pthread_cond_t lock_released;
178 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000179} pthread_lock;
180
Guido van Rossum9e46e561998-10-07 16:39:47 +0000181#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100182#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
183 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000184
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000185/*
186 * Initialization.
187 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000188static void
189PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000190{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000191#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200192 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000194#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900195 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000196}
197
198/*
199 * Thread support.
200 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000201
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530202/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
203 "void func(void *)" to "void* func(void *)": always return NULL.
204
205 PyThread_start_new_thread() uses "void func(void *)" type, whereas
206 pthread_create() requires a void* return value. */
207typedef struct {
208 void (*func) (void *);
209 void *arg;
210} pythread_callback;
211
212static void *
213pythread_wrapper(void *arg)
214{
215 /* copy func and func_arg and free the temporary structure */
216 pythread_callback *callback = arg;
217 void (*func)(void *) = callback->func;
218 void *func_arg = callback->arg;
219 PyMem_RawFree(arg);
220
221 func(func_arg);
222 return NULL;
223}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000224
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200225unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000226PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000227{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 pthread_t th;
229 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000230#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000232#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000233#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000235#endif
236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 dprintf(("PyThread_start_new_thread called\n"));
238 if (!initialized)
239 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000240
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000241#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200243 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000244#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000245#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100246 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600247 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
248 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000249 if (tss != 0) {
250 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
251 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200252 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 }
254 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000255#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000258#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000259
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530260 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
261
262 if (callback == NULL) {
263 return PYTHREAD_INVALID_THREAD_ID;
264 }
265
266 callback->func = func;
267 callback->arg = arg;
268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000270#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000272#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000274#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530275 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000276
Fred Drake03459a52001-11-09 16:00:41 +0000277#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000279#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530280
281 if (status != 0) {
282 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200283 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530284 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000287
Guido van Rossum3c288632001-10-16 21:13:49 +0000288#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200289 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000290#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200291 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000292#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000293}
294
Trent Mick635f6fb2000-08-23 21:33:05 +0000295/* XXX This implementation is considered (to quote Tim Peters) "inherently
296 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000297 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200298 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100299 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000300*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200301unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000302PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 volatile pthread_t threadid;
305 if (!initialized)
306 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200308 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000309}
310
Jake Tesler4959c332019-05-12 10:08:24 -0700311unsigned long
312PyThread_get_thread_native_id(void)
313{
314 if (!initialized)
315 PyThread_init_thread();
316#ifdef __APPLE__
317 uint64_t native_id;
318 pthread_threadid_np(NULL, &native_id);
319#elif defined(__linux__)
320 pid_t native_id;
321 native_id = syscall(__NR_gettid);
322#elif defined(__FreeBSD__)
323 pid_t native_id;
324 native_id = pthread_getthreadid_np();
325#else
326 unsigned long native_id;
327 native_id = 0;
328#endif
329 return (unsigned long) native_id;
330}
331
Victor Stinnerc664b342019-05-04 11:48:05 -0400332void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000333PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200336 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200338 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000339}
340
Martin v. Löwiscc898662002-03-17 09:53:51 +0000341#ifdef USE_SEMAPHORES
342
343/*
344 * Lock support.
345 */
346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000348PyThread_allocate_lock(void)
349{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 sem_t *lock;
351 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 dprintf(("PyThread_allocate_lock called\n"));
354 if (!initialized)
355 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000356
Victor Stinner80aa5652013-07-07 17:17:59 +0200357 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 if (lock) {
360 status = sem_init(lock,0,1);
361 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200364 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 lock = NULL;
366 }
367 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000368
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600369 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000371}
372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000374PyThread_free_lock(PyThread_type_lock lock)
375{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 sem_t *thelock = (sem_t *)lock;
377 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000378
Christian Heimes56379c02012-12-02 08:37:00 +0100379 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (!thelock)
383 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 status = sem_destroy(thelock);
386 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000387
Victor Stinner80aa5652013-07-07 17:17:59 +0200388 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000389}
390
391/*
392 * As of February 2002, Cygwin thread implementations mistakenly report error
393 * codes in the return value of the sem_ calls (like the pthread_ functions).
394 * Correct implementations return -1 and put the code in errno. This supports
395 * either.
396 */
397static int
398fix_status(int status)
399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000401}
402
Antoine Pitrou810023d2010-12-15 22:59:16 +0000403PyLockStatus
404PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
405 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000406{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000407 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 sem_t *thelock = (sem_t *)lock;
409 int status, error = 0;
410 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700411 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000412
Christian Heimes56379c02012-12-02 08:37:00 +0100413 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000414 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
415 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000416
Victor Stinner850a18e2017-10-24 16:53:32 -0700417 if (microseconds > PY_TIMEOUT_MAX) {
418 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
419 }
420
421 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700423
424 if (!intr_flag) {
425 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
426 check done above */
427 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
428 deadline = _PyTime_GetMonotonicClock() + timeout;
429 }
430 }
431
432 while (1) {
433 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700435 }
436 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700438 }
439 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700441 }
442
Antoine Pitrou810023d2010-12-15 22:59:16 +0000443 /* Retry if interrupted by a signal, unless the caller wants to be
444 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700445 if (intr_flag || status != EINTR) {
446 break;
447 }
448
449 if (microseconds > 0) {
450 /* wait interrupted by a signal (EINTR): recompute the timeout */
451 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
452 if (dt < 0) {
453 status = ETIMEDOUT;
454 break;
455 }
456 else if (dt > 0) {
457 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
458 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
459 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
460 check done above */
461 Py_UNREACHABLE();
462 }
463 /* no need to update microseconds value, the code only care
464 if (microseconds > 0 or (microseconds == 0). */
465 }
466 else {
467 microseconds = 0;
468 }
469 }
470 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000471
Antoine Pitrou810023d2010-12-15 22:59:16 +0000472 /* Don't check the status if we're stopping because of an interrupt. */
473 if (!(intr_flag && status == EINTR)) {
474 if (microseconds > 0) {
475 if (status != ETIMEDOUT)
476 CHECK_STATUS("sem_timedwait");
477 }
478 else if (microseconds == 0) {
479 if (status != EAGAIN)
480 CHECK_STATUS("sem_trywait");
481 }
482 else {
483 CHECK_STATUS("sem_wait");
484 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000486
Antoine Pitrou810023d2010-12-15 22:59:16 +0000487 if (status == 0) {
488 success = PY_LOCK_ACQUIRED;
489 } else if (intr_flag && status == EINTR) {
490 success = PY_LOCK_INTR;
491 } else {
492 success = PY_LOCK_FAILURE;
493 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494
Antoine Pitrou810023d2010-12-15 22:59:16 +0000495 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
496 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000498}
499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000501PyThread_release_lock(PyThread_type_lock lock)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 sem_t *thelock = (sem_t *)lock;
504 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000505
Christian Heimes56379c02012-12-02 08:37:00 +0100506 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 status = sem_post(thelock);
510 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000511}
512
513#else /* USE_SEMAPHORES */
514
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000515/*
516 * Lock support.
517 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000519PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 pthread_lock *lock;
522 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 dprintf(("PyThread_allocate_lock called\n"));
525 if (!initialized)
526 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000527
Victor Stinner80aa5652013-07-07 17:17:59 +0200528 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 if (lock) {
530 memset((void *)lock, '\0', sizeof(pthread_lock));
531 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000532
Inada Naoki001fee12019-02-20 10:00:09 +0900533 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100534 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 /* Mark the pthread mutex underlying a Python mutex as
536 pure happens-before. We can't simply mark the
537 Python-level mutex as a mutex because it can be
538 acquired and released in different threads, which
539 will cause errors. */
540 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000541
Inada Naoki001fee12019-02-20 10:00:09 +0900542 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100543 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200546 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 lock = 0;
548 }
549 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000550
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600551 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000553}
554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000556PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000557{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 pthread_lock *thelock = (pthread_lock *)lock;
559 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000560
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200561 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000563
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000564 /* some pthread-like implementations tie the mutex to the cond
565 * and must have the cond destroyed first.
566 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100568 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000569
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000570 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100571 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000572
Victor Stinner80aa5652013-07-07 17:17:59 +0200573 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000574}
575
Antoine Pitrou810023d2010-12-15 22:59:16 +0000576PyLockStatus
577PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
578 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000579{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200580 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 pthread_lock *thelock = (pthread_lock *)lock;
582 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000583
Antoine Pitrou810023d2010-12-15 22:59:16 +0000584 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
585 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000586
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200587 if (microseconds == 0) {
588 status = pthread_mutex_trylock( &thelock->mut );
589 if (status != EBUSY)
590 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
591 }
592 else {
593 status = pthread_mutex_lock( &thelock->mut );
594 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
595 }
596 if (status == 0) {
597 if (thelock->locked == 0) {
598 success = PY_LOCK_ACQUIRED;
599 }
600 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900601 struct timespec abs;
602 if (microseconds > 0) {
603 _PyThread_cond_after(microseconds, &abs);
604 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200605 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000606
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200607 /* mut must be locked by me -- part of the condition
608 * protocol */
609 while (success == PY_LOCK_FAILURE) {
610 if (microseconds > 0) {
611 status = pthread_cond_timedwait(
612 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900613 &thelock->mut, &abs);
614 if (status == 1) {
615 break;
616 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200617 if (status == ETIMEDOUT)
618 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900619 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200620 }
621 else {
622 status = pthread_cond_wait(
623 &thelock->lock_released,
624 &thelock->mut);
625 CHECK_STATUS_PTHREAD("pthread_cond_wait");
626 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000627
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200628 if (intr_flag && status == 0 && thelock->locked) {
629 /* We were woken up, but didn't get the lock. We probably received
630 * a signal. Return PY_LOCK_INTR to allow the caller to handle
631 * it and retry. */
632 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200634 }
635 else if (status == 0 && !thelock->locked) {
636 success = PY_LOCK_ACQUIRED;
637 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000638 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200640 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
641 status = pthread_mutex_unlock( &thelock->mut );
642 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000644
Antoine Pitrou810023d2010-12-15 22:59:16 +0000645 if (error) success = PY_LOCK_FAILURE;
646 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
647 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000649}
650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000652PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 pthread_lock *thelock = (pthread_lock *)lock;
655 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000656
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200657 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000659
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100661 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 /* wake up someone (anyone, if any) waiting on the lock */
666 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100667 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000668
669 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100670 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000671}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000672
673#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000674
Antoine Pitrou810023d2010-12-15 22:59:16 +0000675int
676PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
677{
678 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
679}
680
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000681/* set the thread stack size.
682 * Return 0 if size is valid, -1 if size is invalid,
683 * -2 if setting stack size is not supported.
684 */
685static int
686_pythread_pthread_set_stacksize(size_t size)
687{
688#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 pthread_attr_t attrs;
690 size_t tss_min;
691 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000692#endif
693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 /* set to default */
695 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100696 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 return 0;
698 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000699
700#if defined(THREAD_STACK_SIZE)
701#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
703 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000704#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000706#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 if (size >= tss_min) {
708 /* validate stack size by setting thread attribute */
709 if (pthread_attr_init(&attrs) == 0) {
710 rc = pthread_attr_setstacksize(&attrs, size);
711 pthread_attr_destroy(&attrs);
712 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100713 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 return 0;
715 }
716 }
717 }
718 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000719#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000721#endif
722}
723
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000725
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000726
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900727/* Thread Local Storage (TLS) API
728
729 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
730*/
731
732/* Issue #25658: On platforms where native TLS key is defined in a way that
733 cannot be safely cast to int, PyThread_create_key returns immediately a
734 failure status and other TLS functions all are no-ops. This indicates
735 clearly that the old API is not supported on platforms where it cannot be
736 used reliably, and that no effort will be made to add such support.
737
738 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
739 removing this API.
740*/
741
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000742int
743PyThread_create_key(void)
744{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900745#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000746 pthread_key_t key;
747 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200748 if (fail)
749 return -1;
750 if (key > INT_MAX) {
751 /* Issue #22206: handle integer overflow */
752 pthread_key_delete(key);
753 errno = ENOMEM;
754 return -1;
755 }
756 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900757#else
758 return -1; /* never return valid key value. */
759#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000760}
761
762void
763PyThread_delete_key(int key)
764{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900765#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000766 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900767#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000768}
769
770void
771PyThread_delete_key_value(int key)
772{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900773#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000774 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900775#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000776}
777
778int
779PyThread_set_key_value(int key, void *value)
780{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900781#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
782 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000783 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900784#else
785 return -1;
786#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000787}
788
789void *
790PyThread_get_key_value(int key)
791{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900792#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000793 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900794#else
795 return NULL;
796#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000797}
798
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900799
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000800void
801PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900802{
803}
804
805
806/* Thread Specific Storage (TSS) API
807
808 Platform-specific components of TSS API implementation.
809*/
810
811int
812PyThread_tss_create(Py_tss_t *key)
813{
814 assert(key != NULL);
815 /* If the key has been created, function is silently skipped. */
816 if (key->_is_initialized) {
817 return 0;
818 }
819
820 int fail = pthread_key_create(&(key->_key), NULL);
821 if (fail) {
822 return -1;
823 }
824 key->_is_initialized = 1;
825 return 0;
826}
827
828void
829PyThread_tss_delete(Py_tss_t *key)
830{
831 assert(key != NULL);
832 /* If the key has not been created, function is silently skipped. */
833 if (!key->_is_initialized) {
834 return;
835 }
836
837 pthread_key_delete(key->_key);
838 /* pthread has not provided the defined invalid value for the key. */
839 key->_is_initialized = 0;
840}
841
842int
843PyThread_tss_set(Py_tss_t *key, void *value)
844{
845 assert(key != NULL);
846 int fail = pthread_setspecific(key->_key, value);
847 return fail ? -1 : 0;
848}
849
850void *
851PyThread_tss_get(Py_tss_t *key)
852{
853 assert(key != NULL);
854 return pthread_getspecific(key->_key);
855}