blob: f57a1e7bb78bafdf2ad67d5db34694f1a992bbd3 [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() */
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 Teslerb121f632019-05-22 08:43:17 -0700311#ifdef PY_HAVE_THREAD_NATIVE_ID
312unsigned long
313PyThread_get_thread_native_id(void)
314{
315 if (!initialized)
316 PyThread_init_thread();
317#ifdef __APPLE__
318 uint64_t native_id;
319 (void) pthread_threadid_np(NULL, &native_id);
320#elif defined(__linux__)
321 pid_t native_id;
322 native_id = syscall(SYS_gettid);
323#elif defined(__FreeBSD__)
324 int native_id;
325 native_id = pthread_getthreadid_np();
326#endif
327 return (unsigned long) native_id;
328}
329#endif
330
Victor Stinnerc664b342019-05-04 11:48:05 -0400331void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000332PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200335 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200337 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000338}
339
Martin v. Löwiscc898662002-03-17 09:53:51 +0000340#ifdef USE_SEMAPHORES
341
342/*
343 * Lock support.
344 */
345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000347PyThread_allocate_lock(void)
348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 sem_t *lock;
350 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 dprintf(("PyThread_allocate_lock called\n"));
353 if (!initialized)
354 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000355
Victor Stinner80aa5652013-07-07 17:17:59 +0200356 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 if (lock) {
359 status = sem_init(lock,0,1);
360 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200363 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 lock = NULL;
365 }
366 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000367
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600368 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000370}
371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000373PyThread_free_lock(PyThread_type_lock lock)
374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 sem_t *thelock = (sem_t *)lock;
376 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000377
Christian Heimes56379c02012-12-02 08:37:00 +0100378 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (!thelock)
382 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 status = sem_destroy(thelock);
385 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000386
Victor Stinner80aa5652013-07-07 17:17:59 +0200387 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000388}
389
390/*
391 * As of February 2002, Cygwin thread implementations mistakenly report error
392 * codes in the return value of the sem_ calls (like the pthread_ functions).
393 * Correct implementations return -1 and put the code in errno. This supports
394 * either.
395 */
396static int
397fix_status(int status)
398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000400}
401
Antoine Pitrou810023d2010-12-15 22:59:16 +0000402PyLockStatus
403PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
404 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000405{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000406 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 sem_t *thelock = (sem_t *)lock;
408 int status, error = 0;
409 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700410 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000411
Christian Heimes56379c02012-12-02 08:37:00 +0100412 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000413 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
414 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000415
Victor Stinner850a18e2017-10-24 16:53:32 -0700416 if (microseconds > PY_TIMEOUT_MAX) {
417 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
418 }
419
420 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700422
423 if (!intr_flag) {
424 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
425 check done above */
426 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
427 deadline = _PyTime_GetMonotonicClock() + timeout;
428 }
429 }
430
431 while (1) {
432 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700434 }
435 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700437 }
438 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700440 }
441
Antoine Pitrou810023d2010-12-15 22:59:16 +0000442 /* Retry if interrupted by a signal, unless the caller wants to be
443 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700444 if (intr_flag || status != EINTR) {
445 break;
446 }
447
448 if (microseconds > 0) {
449 /* wait interrupted by a signal (EINTR): recompute the timeout */
450 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
451 if (dt < 0) {
452 status = ETIMEDOUT;
453 break;
454 }
455 else if (dt > 0) {
456 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
457 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
458 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
459 check done above */
460 Py_UNREACHABLE();
461 }
462 /* no need to update microseconds value, the code only care
463 if (microseconds > 0 or (microseconds == 0). */
464 }
465 else {
466 microseconds = 0;
467 }
468 }
469 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000470
Antoine Pitrou810023d2010-12-15 22:59:16 +0000471 /* Don't check the status if we're stopping because of an interrupt. */
472 if (!(intr_flag && status == EINTR)) {
473 if (microseconds > 0) {
474 if (status != ETIMEDOUT)
475 CHECK_STATUS("sem_timedwait");
476 }
477 else if (microseconds == 0) {
478 if (status != EAGAIN)
479 CHECK_STATUS("sem_trywait");
480 }
481 else {
482 CHECK_STATUS("sem_wait");
483 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000485
Antoine Pitrou810023d2010-12-15 22:59:16 +0000486 if (status == 0) {
487 success = PY_LOCK_ACQUIRED;
488 } else if (intr_flag && status == EINTR) {
489 success = PY_LOCK_INTR;
490 } else {
491 success = PY_LOCK_FAILURE;
492 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493
Antoine Pitrou810023d2010-12-15 22:59:16 +0000494 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
495 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000497}
498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000500PyThread_release_lock(PyThread_type_lock lock)
501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 sem_t *thelock = (sem_t *)lock;
503 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000504
Christian Heimes56379c02012-12-02 08:37:00 +0100505 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 status = sem_post(thelock);
509 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000510}
511
512#else /* USE_SEMAPHORES */
513
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000514/*
515 * Lock support.
516 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000518PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 pthread_lock *lock;
521 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 dprintf(("PyThread_allocate_lock called\n"));
524 if (!initialized)
525 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000526
Victor Stinner80aa5652013-07-07 17:17:59 +0200527 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 if (lock) {
529 memset((void *)lock, '\0', sizeof(pthread_lock));
530 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000531
Inada Naoki001fee12019-02-20 10:00:09 +0900532 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100533 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 /* Mark the pthread mutex underlying a Python mutex as
535 pure happens-before. We can't simply mark the
536 Python-level mutex as a mutex because it can be
537 acquired and released in different threads, which
538 will cause errors. */
539 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000540
Inada Naoki001fee12019-02-20 10:00:09 +0900541 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100542 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200545 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 lock = 0;
547 }
548 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000549
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600550 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000552}
553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000555PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 pthread_lock *thelock = (pthread_lock *)lock;
558 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000559
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200560 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000562
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000563 /* some pthread-like implementations tie the mutex to the cond
564 * and must have the cond destroyed first.
565 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100567 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000568
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000569 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100570 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000571
Victor Stinner80aa5652013-07-07 17:17:59 +0200572 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000573}
574
Antoine Pitrou810023d2010-12-15 22:59:16 +0000575PyLockStatus
576PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
577 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000578{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200579 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 pthread_lock *thelock = (pthread_lock *)lock;
581 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000582
Antoine Pitrou810023d2010-12-15 22:59:16 +0000583 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
584 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000585
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200586 if (microseconds == 0) {
587 status = pthread_mutex_trylock( &thelock->mut );
588 if (status != EBUSY)
589 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
590 }
591 else {
592 status = pthread_mutex_lock( &thelock->mut );
593 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
594 }
595 if (status == 0) {
596 if (thelock->locked == 0) {
597 success = PY_LOCK_ACQUIRED;
598 }
599 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900600 struct timespec abs;
601 if (microseconds > 0) {
602 _PyThread_cond_after(microseconds, &abs);
603 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200604 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000605
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200606 /* mut must be locked by me -- part of the condition
607 * protocol */
608 while (success == PY_LOCK_FAILURE) {
609 if (microseconds > 0) {
610 status = pthread_cond_timedwait(
611 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900612 &thelock->mut, &abs);
613 if (status == 1) {
614 break;
615 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200616 if (status == ETIMEDOUT)
617 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900618 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200619 }
620 else {
621 status = pthread_cond_wait(
622 &thelock->lock_released,
623 &thelock->mut);
624 CHECK_STATUS_PTHREAD("pthread_cond_wait");
625 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000626
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200627 if (intr_flag && status == 0 && thelock->locked) {
628 /* We were woken up, but didn't get the lock. We probably received
629 * a signal. Return PY_LOCK_INTR to allow the caller to handle
630 * it and retry. */
631 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000632 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200633 }
634 else if (status == 0 && !thelock->locked) {
635 success = PY_LOCK_ACQUIRED;
636 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000637 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200639 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
640 status = pthread_mutex_unlock( &thelock->mut );
641 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000643
Antoine Pitrou810023d2010-12-15 22:59:16 +0000644 if (error) success = PY_LOCK_FAILURE;
645 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
646 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000648}
649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000651PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 pthread_lock *thelock = (pthread_lock *)lock;
654 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000655
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200656 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100660 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000661
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 /* wake up someone (anyone, if any) waiting on the lock */
665 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100666 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000667
668 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100669 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000670}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000671
672#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000673
Antoine Pitrou810023d2010-12-15 22:59:16 +0000674int
675PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
676{
677 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
678}
679
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000680/* set the thread stack size.
681 * Return 0 if size is valid, -1 if size is invalid,
682 * -2 if setting stack size is not supported.
683 */
684static int
685_pythread_pthread_set_stacksize(size_t size)
686{
687#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 pthread_attr_t attrs;
689 size_t tss_min;
690 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000691#endif
692
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 /* set to default */
694 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100695 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 return 0;
697 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000698
699#if defined(THREAD_STACK_SIZE)
700#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
702 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000703#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000704 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000705#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 if (size >= tss_min) {
707 /* validate stack size by setting thread attribute */
708 if (pthread_attr_init(&attrs) == 0) {
709 rc = pthread_attr_setstacksize(&attrs, size);
710 pthread_attr_destroy(&attrs);
711 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100712 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 return 0;
714 }
715 }
716 }
717 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000718#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000720#endif
721}
722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000724
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000725
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900726/* Thread Local Storage (TLS) API
727
728 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
729*/
730
731/* Issue #25658: On platforms where native TLS key is defined in a way that
732 cannot be safely cast to int, PyThread_create_key returns immediately a
733 failure status and other TLS functions all are no-ops. This indicates
734 clearly that the old API is not supported on platforms where it cannot be
735 used reliably, and that no effort will be made to add such support.
736
737 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
738 removing this API.
739*/
740
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000741int
742PyThread_create_key(void)
743{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900744#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000745 pthread_key_t key;
746 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200747 if (fail)
748 return -1;
749 if (key > INT_MAX) {
750 /* Issue #22206: handle integer overflow */
751 pthread_key_delete(key);
752 errno = ENOMEM;
753 return -1;
754 }
755 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900756#else
757 return -1; /* never return valid key value. */
758#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000759}
760
761void
762PyThread_delete_key(int key)
763{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900764#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000765 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900766#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000767}
768
769void
770PyThread_delete_key_value(int key)
771{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900772#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000773 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900774#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000775}
776
777int
778PyThread_set_key_value(int key, void *value)
779{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900780#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
781 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000782 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900783#else
784 return -1;
785#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000786}
787
788void *
789PyThread_get_key_value(int key)
790{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900791#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000792 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900793#else
794 return NULL;
795#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000796}
797
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900798
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000799void
800PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900801{
802}
803
804
805/* Thread Specific Storage (TSS) API
806
807 Platform-specific components of TSS API implementation.
808*/
809
810int
811PyThread_tss_create(Py_tss_t *key)
812{
813 assert(key != NULL);
814 /* If the key has been created, function is silently skipped. */
815 if (key->_is_initialized) {
816 return 0;
817 }
818
819 int fail = pthread_key_create(&(key->_key), NULL);
820 if (fail) {
821 return -1;
822 }
823 key->_is_initialized = 1;
824 return 0;
825}
826
827void
828PyThread_tss_delete(Py_tss_t *key)
829{
830 assert(key != NULL);
831 /* If the key has not been created, function is silently skipped. */
832 if (!key->_is_initialized) {
833 return;
834 }
835
836 pthread_key_delete(key->_key);
837 /* pthread has not provided the defined invalid value for the key. */
838 key->_is_initialized = 0;
839}
840
841int
842PyThread_tss_set(Py_tss_t *key, void *value)
843{
844 assert(key != NULL);
845 int fail = pthread_setspecific(key->_key, value);
846 return fail ? -1 : 0;
847}
848
849void *
850PyThread_tss_get(Py_tss_t *key)
851{
852 assert(key != NULL);
853 return pthread_getspecific(key->_key);
854}