blob: 25f58d9446d8d607dd0c268a5669c864ad3375ca [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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000015/* The POSIX spec requires that use of pthread_attr_setstacksize
16 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
17#ifdef _POSIX_THREAD_ATTR_STACKSIZE
18#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000020#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070021
Ned Deily7ca97d52012-03-13 11:18:18 -070022/* The default stack size for new threads on OSX and BSD is small enough that
23 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
24 * exceptions.
25 *
26 * The default stack sizes below are the empirically determined minimal stack
27 * sizes where a simple recursive function doesn't cause a hard crash.
28 */
29#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
30#undef THREAD_STACK_SIZE
31#define THREAD_STACK_SIZE 0x500000
32#endif
33#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070034#undef THREAD_STACK_SIZE
35#define THREAD_STACK_SIZE 0x400000
36#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000037/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080038#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
40#ifdef THREAD_STACK_SIZE
41#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
42#endif
43#endif
44
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000045/* The POSIX spec says that implementations supporting the sem_*
46 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000048#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000050 we need to add 0 to make it work there as well. */
51#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000052#define HAVE_BROKEN_POSIX_SEMAPHORES
53#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000054#include <semaphore.h>
55#include <errno.h>
56#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000057#endif
Guido van Rossum66020991996-06-11 18:32:18 +000058
Guido van Rossumd6353e21997-05-13 17:51:13 +000059
Martin v. Löwiscc898662002-03-17 09:53:51 +000060/* Whether or not to use semaphores directly rather than emulating them with
61 * mutexes and condition variables:
62 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000063#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
64 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000065# define USE_SEMAPHORES
66#else
67# undef USE_SEMAPHORES
68#endif
69
70
Guido van Rossum80230992001-10-12 21:49:17 +000071/* On platforms that don't use standard POSIX threads pthread_sigmask()
72 * isn't present. DEC threads uses sigprocmask() instead as do most
73 * other UNIX International compliant systems that don't have the full
74 * pthread implementation.
75 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000076#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000077# define SET_THREAD_SIGMASK pthread_sigmask
78#else
79# define SET_THREAD_SIGMASK sigprocmask
80#endif
81
82
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000083/* We assume all modern POSIX systems have gettimeofday() */
84#ifdef GETTIMEOFDAY_NO_TZ
85#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
86#else
87#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
88#endif
89
90#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
91do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 struct timeval tv; \
93 GETTIMEOFDAY(&tv); \
94 tv.tv_usec += microseconds % 1000000; \
95 tv.tv_sec += microseconds / 1000000; \
96 tv.tv_sec += tv.tv_usec / 1000000; \
97 tv.tv_usec %= 1000000; \
98 ts.tv_sec = tv.tv_sec; \
99 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000100} while(0)
101
102
Inada Naoki001fee12019-02-20 10:00:09 +0900103/*
104 * pthread_cond support
105 */
106
107#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
108// monotonic is supported statically. It doesn't mean it works on runtime.
109#define CONDATTR_MONOTONIC
110#endif
111
112// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
113static pthread_condattr_t *condattr_monotonic = NULL;
114
115static void
116init_condattr()
117{
118#ifdef CONDATTR_MONOTONIC
119 static pthread_condattr_t ca;
120 pthread_condattr_init(&ca);
121 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
122 condattr_monotonic = &ca; // Use monotonic clock
123 }
124#endif
125}
126
127int
128_PyThread_cond_init(PyCOND_T *cond)
129{
130 return pthread_cond_init(cond, condattr_monotonic);
131}
132
133void
134_PyThread_cond_after(long long us, struct timespec *abs)
135{
136#ifdef CONDATTR_MONOTONIC
137 if (condattr_monotonic) {
138 clock_gettime(CLOCK_MONOTONIC, abs);
139 abs->tv_sec += us / 1000000;
140 abs->tv_nsec += (us % 1000000) * 1000;
141 abs->tv_sec += abs->tv_nsec / 1000000000;
142 abs->tv_nsec %= 1000000000;
143 return;
144 }
145#endif
146
147 struct timespec ts;
148 MICROSECONDS_TO_TIMESPEC(us, ts);
149 *abs = ts;
150}
151
152
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000153/* A pthread mutex isn't sufficient to model the Python lock type
154 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
155 * following are undefined:
156 * -> a thread tries to lock a mutex it already has locked
157 * -> a thread tries to unlock a mutex locked by a different thread
158 * pthread mutexes are designed for serializing threads over short pieces
159 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000160 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000161 *
162 * The pthread_lock struct implements a Python lock as a "locked?" bit
163 * and a <condition, mutex> pair. In general, if the bit can be acquired
164 * instantly, it is, else the pair is used to block the thread until the
165 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000166 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000167
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000168typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 char locked; /* 0=unlocked, 1=locked */
170 /* a <cond, mutex> pair to handle an acquire of a locked lock */
171 pthread_cond_t lock_released;
172 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000173} pthread_lock;
174
Guido van Rossum9e46e561998-10-07 16:39:47 +0000175#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100176#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
177 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000178
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000179/*
180 * Initialization.
181 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000182static void
183PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000184{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000185#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200186 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000188#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900189 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000190}
191
192/*
193 * Thread support.
194 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000195
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530196/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
197 "void func(void *)" to "void* func(void *)": always return NULL.
198
199 PyThread_start_new_thread() uses "void func(void *)" type, whereas
200 pthread_create() requires a void* return value. */
201typedef struct {
202 void (*func) (void *);
203 void *arg;
204} pythread_callback;
205
206static void *
207pythread_wrapper(void *arg)
208{
209 /* copy func and func_arg and free the temporary structure */
210 pythread_callback *callback = arg;
211 void (*func)(void *) = callback->func;
212 void *func_arg = callback->arg;
213 PyMem_RawFree(arg);
214
215 func(func_arg);
216 return NULL;
217}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000218
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200219unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000220PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 pthread_t th;
223 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000224#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000226#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000227#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000229#endif
230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 dprintf(("PyThread_start_new_thread called\n"));
232 if (!initialized)
233 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000234
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000235#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200237 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000238#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000239#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100240 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600241 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
242 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 if (tss != 0) {
244 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
245 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200246 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 }
248 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000249#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000250#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000252#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000253
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530254 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
255
256 if (callback == NULL) {
257 return PYTHREAD_INVALID_THREAD_ID;
258 }
259
260 callback->func = func;
261 callback->arg = arg;
262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000264#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000266#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000268#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530269 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000270
Fred Drake03459a52001-11-09 16:00:41 +0000271#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000273#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530274
275 if (status != 0) {
276 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200277 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530278 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000281
Guido van Rossum3c288632001-10-16 21:13:49 +0000282#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200283 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000284#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200285 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000286#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000287}
288
Trent Mick635f6fb2000-08-23 21:33:05 +0000289/* XXX This implementation is considered (to quote Tim Peters) "inherently
290 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000291 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200292 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100293 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000294*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200295unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000296PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 volatile pthread_t threadid;
299 if (!initialized)
300 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200302 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000303}
304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000306PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200309 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200311 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000312}
313
Martin v. Löwiscc898662002-03-17 09:53:51 +0000314#ifdef USE_SEMAPHORES
315
316/*
317 * Lock support.
318 */
319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000321PyThread_allocate_lock(void)
322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 sem_t *lock;
324 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 dprintf(("PyThread_allocate_lock called\n"));
327 if (!initialized)
328 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000329
Victor Stinner80aa5652013-07-07 17:17:59 +0200330 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 if (lock) {
333 status = sem_init(lock,0,1);
334 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200337 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 lock = NULL;
339 }
340 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
343 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000344}
345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000347PyThread_free_lock(PyThread_type_lock lock)
348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 sem_t *thelock = (sem_t *)lock;
350 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000351
Christian Heimes56379c02012-12-02 08:37:00 +0100352 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 if (!thelock)
356 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 status = sem_destroy(thelock);
359 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000360
Victor Stinner80aa5652013-07-07 17:17:59 +0200361 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000362}
363
364/*
365 * As of February 2002, Cygwin thread implementations mistakenly report error
366 * codes in the return value of the sem_ calls (like the pthread_ functions).
367 * Correct implementations return -1 and put the code in errno. This supports
368 * either.
369 */
370static int
371fix_status(int status)
372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000374}
375
Antoine Pitrou810023d2010-12-15 22:59:16 +0000376PyLockStatus
377PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
378 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000379{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000380 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 sem_t *thelock = (sem_t *)lock;
382 int status, error = 0;
383 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700384 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000385
Christian Heimes56379c02012-12-02 08:37:00 +0100386 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000387 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
388 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000389
Victor Stinner850a18e2017-10-24 16:53:32 -0700390 if (microseconds > PY_TIMEOUT_MAX) {
391 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
392 }
393
394 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700396
397 if (!intr_flag) {
398 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
399 check done above */
400 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
401 deadline = _PyTime_GetMonotonicClock() + timeout;
402 }
403 }
404
405 while (1) {
406 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700408 }
409 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700411 }
412 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700414 }
415
Antoine Pitrou810023d2010-12-15 22:59:16 +0000416 /* Retry if interrupted by a signal, unless the caller wants to be
417 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700418 if (intr_flag || status != EINTR) {
419 break;
420 }
421
422 if (microseconds > 0) {
423 /* wait interrupted by a signal (EINTR): recompute the timeout */
424 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
425 if (dt < 0) {
426 status = ETIMEDOUT;
427 break;
428 }
429 else if (dt > 0) {
430 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
431 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
432 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
433 check done above */
434 Py_UNREACHABLE();
435 }
436 /* no need to update microseconds value, the code only care
437 if (microseconds > 0 or (microseconds == 0). */
438 }
439 else {
440 microseconds = 0;
441 }
442 }
443 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000444
Antoine Pitrou810023d2010-12-15 22:59:16 +0000445 /* Don't check the status if we're stopping because of an interrupt. */
446 if (!(intr_flag && status == EINTR)) {
447 if (microseconds > 0) {
448 if (status != ETIMEDOUT)
449 CHECK_STATUS("sem_timedwait");
450 }
451 else if (microseconds == 0) {
452 if (status != EAGAIN)
453 CHECK_STATUS("sem_trywait");
454 }
455 else {
456 CHECK_STATUS("sem_wait");
457 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000459
Antoine Pitrou810023d2010-12-15 22:59:16 +0000460 if (status == 0) {
461 success = PY_LOCK_ACQUIRED;
462 } else if (intr_flag && status == EINTR) {
463 success = PY_LOCK_INTR;
464 } else {
465 success = PY_LOCK_FAILURE;
466 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467
Antoine Pitrou810023d2010-12-15 22:59:16 +0000468 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
469 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000471}
472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000474PyThread_release_lock(PyThread_type_lock lock)
475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 sem_t *thelock = (sem_t *)lock;
477 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000478
Christian Heimes56379c02012-12-02 08:37:00 +0100479 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 status = sem_post(thelock);
483 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000484}
485
486#else /* USE_SEMAPHORES */
487
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000488/*
489 * Lock support.
490 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000492PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 pthread_lock *lock;
495 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 dprintf(("PyThread_allocate_lock called\n"));
498 if (!initialized)
499 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000500
Victor Stinner80aa5652013-07-07 17:17:59 +0200501 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 if (lock) {
503 memset((void *)lock, '\0', sizeof(pthread_lock));
504 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000505
Inada Naoki001fee12019-02-20 10:00:09 +0900506 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100507 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 /* Mark the pthread mutex underlying a Python mutex as
509 pure happens-before. We can't simply mark the
510 Python-level mutex as a mutex because it can be
511 acquired and released in different threads, which
512 will cause errors. */
513 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000514
Inada Naoki001fee12019-02-20 10:00:09 +0900515 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100516 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000517
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200519 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 lock = 0;
521 }
522 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 dprintf(("PyThread_allocate_lock() -> %p\n", lock));
525 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000526}
527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000529PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 pthread_lock *thelock = (pthread_lock *)lock;
532 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000533
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200534 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000536
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000537 /* some pthread-like implementations tie the mutex to the cond
538 * and must have the cond destroyed first.
539 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100541 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000542
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000543 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100544 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000545
Victor Stinner80aa5652013-07-07 17:17:59 +0200546 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000547}
548
Antoine Pitrou810023d2010-12-15 22:59:16 +0000549PyLockStatus
550PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
551 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000552{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200553 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 pthread_lock *thelock = (pthread_lock *)lock;
555 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000556
Antoine Pitrou810023d2010-12-15 22:59:16 +0000557 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
558 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000559
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200560 if (microseconds == 0) {
561 status = pthread_mutex_trylock( &thelock->mut );
562 if (status != EBUSY)
563 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
564 }
565 else {
566 status = pthread_mutex_lock( &thelock->mut );
567 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
568 }
569 if (status == 0) {
570 if (thelock->locked == 0) {
571 success = PY_LOCK_ACQUIRED;
572 }
573 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900574 struct timespec abs;
575 if (microseconds > 0) {
576 _PyThread_cond_after(microseconds, &abs);
577 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200578 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000579
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200580 /* mut must be locked by me -- part of the condition
581 * protocol */
582 while (success == PY_LOCK_FAILURE) {
583 if (microseconds > 0) {
584 status = pthread_cond_timedwait(
585 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900586 &thelock->mut, &abs);
587 if (status == 1) {
588 break;
589 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200590 if (status == ETIMEDOUT)
591 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900592 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200593 }
594 else {
595 status = pthread_cond_wait(
596 &thelock->lock_released,
597 &thelock->mut);
598 CHECK_STATUS_PTHREAD("pthread_cond_wait");
599 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000600
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200601 if (intr_flag && status == 0 && thelock->locked) {
602 /* We were woken up, but didn't get the lock. We probably received
603 * a signal. Return PY_LOCK_INTR to allow the caller to handle
604 * it and retry. */
605 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200607 }
608 else if (status == 0 && !thelock->locked) {
609 success = PY_LOCK_ACQUIRED;
610 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000611 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200613 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
614 status = pthread_mutex_unlock( &thelock->mut );
615 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000617
Antoine Pitrou810023d2010-12-15 22:59:16 +0000618 if (error) success = PY_LOCK_FAILURE;
619 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
620 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000622}
623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000625PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000626{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 pthread_lock *thelock = (pthread_lock *)lock;
628 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000629
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200630 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100634 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000635
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000637
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 /* wake up someone (anyone, if any) waiting on the lock */
639 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100640 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000641
642 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100643 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000644}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000645
646#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000647
Antoine Pitrou810023d2010-12-15 22:59:16 +0000648int
649PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
650{
651 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
652}
653
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000654/* set the thread stack size.
655 * Return 0 if size is valid, -1 if size is invalid,
656 * -2 if setting stack size is not supported.
657 */
658static int
659_pythread_pthread_set_stacksize(size_t size)
660{
661#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 pthread_attr_t attrs;
663 size_t tss_min;
664 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000665#endif
666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 /* set to default */
668 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100669 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 return 0;
671 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000672
673#if defined(THREAD_STACK_SIZE)
674#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
676 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000677#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000679#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000680 if (size >= tss_min) {
681 /* validate stack size by setting thread attribute */
682 if (pthread_attr_init(&attrs) == 0) {
683 rc = pthread_attr_setstacksize(&attrs, size);
684 pthread_attr_destroy(&attrs);
685 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100686 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 return 0;
688 }
689 }
690 }
691 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000692#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000694#endif
695}
696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000698
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000699
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900700/* Thread Local Storage (TLS) API
701
702 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
703*/
704
705/* Issue #25658: On platforms where native TLS key is defined in a way that
706 cannot be safely cast to int, PyThread_create_key returns immediately a
707 failure status and other TLS functions all are no-ops. This indicates
708 clearly that the old API is not supported on platforms where it cannot be
709 used reliably, and that no effort will be made to add such support.
710
711 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
712 removing this API.
713*/
714
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000715int
716PyThread_create_key(void)
717{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900718#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000719 pthread_key_t key;
720 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200721 if (fail)
722 return -1;
723 if (key > INT_MAX) {
724 /* Issue #22206: handle integer overflow */
725 pthread_key_delete(key);
726 errno = ENOMEM;
727 return -1;
728 }
729 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900730#else
731 return -1; /* never return valid key value. */
732#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000733}
734
735void
736PyThread_delete_key(int key)
737{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900738#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000739 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900740#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000741}
742
743void
744PyThread_delete_key_value(int key)
745{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900746#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000747 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900748#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000749}
750
751int
752PyThread_set_key_value(int key, void *value)
753{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900754#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
755 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000756 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900757#else
758 return -1;
759#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000760}
761
762void *
763PyThread_get_key_value(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 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900767#else
768 return NULL;
769#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000770}
771
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900772
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000773void
774PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900775{
776}
777
778
779/* Thread Specific Storage (TSS) API
780
781 Platform-specific components of TSS API implementation.
782*/
783
784int
785PyThread_tss_create(Py_tss_t *key)
786{
787 assert(key != NULL);
788 /* If the key has been created, function is silently skipped. */
789 if (key->_is_initialized) {
790 return 0;
791 }
792
793 int fail = pthread_key_create(&(key->_key), NULL);
794 if (fail) {
795 return -1;
796 }
797 key->_is_initialized = 1;
798 return 0;
799}
800
801void
802PyThread_tss_delete(Py_tss_t *key)
803{
804 assert(key != NULL);
805 /* If the key has not been created, function is silently skipped. */
806 if (!key->_is_initialized) {
807 return;
808 }
809
810 pthread_key_delete(key->_key);
811 /* pthread has not provided the defined invalid value for the key. */
812 key->_is_initialized = 0;
813}
814
815int
816PyThread_tss_set(Py_tss_t *key, void *value)
817{
818 assert(key != NULL);
819 int fail = pthread_setspecific(key->_key, value);
820 return fail ? -1 : 0;
821}
822
823void *
824PyThread_tss_get(Py_tss_t *key)
825{
826 assert(key != NULL);
827 return pthread_getspecific(key->_key);
828}