blob: 740b521b9446218344a18a53bdf22a003067adb4 [file] [log] [blame]
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00001
Guido van Rossum66020991996-06-11 18:32:18 +00002/* Posix threads interface */
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +00003
Guido van Rossum66020991996-06-11 18:32:18 +00004#include <stdlib.h>
Guido van Rossum9e46e561998-10-07 16:39:47 +00005#include <string.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +00006#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +00007#define destructor xxdestructor
8#endif
Guido van Rossum66020991996-06-11 18:32:18 +00009#include <pthread.h>
Martin v. Löwisa7a76d32002-10-04 07:21:24 +000010#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
Jack Jansen76689572002-01-15 20:36:14 +000011#undef destructor
12#endif
Guido van Rossum80230992001-10-12 21:49:17 +000013#include <signal.h>
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000014
Jake Teslerb121f632019-05-22 08:43:17 -070015#if defined(__linux__)
16# include <sys/syscall.h> /* syscall(SYS_gettid) */
17#elif defined(__FreeBSD__)
18# include <pthread_np.h> /* pthread_getthreadid_np() */
David Carlier0b9956e2019-06-03 16:43:33 +010019#elif defined(__OpenBSD__)
20# include <unistd.h> /* getthrid() */
Jake Teslerb121f632019-05-22 08:43:17 -070021#endif
22
Thomas Wouters0e3f5912006-08-11 14:57:12 +000023/* The POSIX spec requires that use of pthread_attr_setstacksize
24 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
25#ifdef _POSIX_THREAD_ATTR_STACKSIZE
26#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000028#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070029
Ned Deily7ca97d52012-03-13 11:18:18 -070030/* The default stack size for new threads on OSX and BSD is small enough that
31 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
32 * exceptions.
33 *
34 * The default stack sizes below are the empirically determined minimal stack
35 * sizes where a simple recursive function doesn't cause a hard crash.
36 */
37#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
38#undef THREAD_STACK_SIZE
39#define THREAD_STACK_SIZE 0x500000
40#endif
41#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070042#undef THREAD_STACK_SIZE
43#define THREAD_STACK_SIZE 0x400000
44#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000045/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080046#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
48#ifdef THREAD_STACK_SIZE
49#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
50#endif
51#endif
52
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000053/* The POSIX spec says that implementations supporting the sem_*
54 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000056#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000058 we need to add 0 to make it work there as well. */
59#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000060#define HAVE_BROKEN_POSIX_SEMAPHORES
61#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000062#include <semaphore.h>
63#include <errno.h>
64#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000065#endif
Guido van Rossum66020991996-06-11 18:32:18 +000066
Guido van Rossumd6353e21997-05-13 17:51:13 +000067
Martin v. Löwiscc898662002-03-17 09:53:51 +000068/* Whether or not to use semaphores directly rather than emulating them with
69 * mutexes and condition variables:
70 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000071#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
72 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000073# define USE_SEMAPHORES
74#else
75# undef USE_SEMAPHORES
76#endif
77
78
Guido van Rossum80230992001-10-12 21:49:17 +000079/* On platforms that don't use standard POSIX threads pthread_sigmask()
80 * isn't present. DEC threads uses sigprocmask() instead as do most
81 * other UNIX International compliant systems that don't have the full
82 * pthread implementation.
83 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000084#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000085# define SET_THREAD_SIGMASK pthread_sigmask
86#else
87# define SET_THREAD_SIGMASK sigprocmask
88#endif
89
90
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000091/* We assume all modern POSIX systems have gettimeofday() */
92#ifdef GETTIMEOFDAY_NO_TZ
93#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
94#else
95#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
96#endif
97
98#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
99do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 struct timeval tv; \
101 GETTIMEOFDAY(&tv); \
102 tv.tv_usec += microseconds % 1000000; \
103 tv.tv_sec += microseconds / 1000000; \
104 tv.tv_sec += tv.tv_usec / 1000000; \
105 tv.tv_usec %= 1000000; \
106 ts.tv_sec = tv.tv_sec; \
107 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000108} while(0)
109
110
Inada Naoki001fee12019-02-20 10:00:09 +0900111/*
112 * pthread_cond support
113 */
114
115#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
116// monotonic is supported statically. It doesn't mean it works on runtime.
117#define CONDATTR_MONOTONIC
118#endif
119
120// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
121static pthread_condattr_t *condattr_monotonic = NULL;
122
123static void
124init_condattr()
125{
126#ifdef CONDATTR_MONOTONIC
127 static pthread_condattr_t ca;
128 pthread_condattr_init(&ca);
129 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
130 condattr_monotonic = &ca; // Use monotonic clock
131 }
132#endif
133}
134
135int
136_PyThread_cond_init(PyCOND_T *cond)
137{
138 return pthread_cond_init(cond, condattr_monotonic);
139}
140
141void
142_PyThread_cond_after(long long us, struct timespec *abs)
143{
144#ifdef CONDATTR_MONOTONIC
145 if (condattr_monotonic) {
146 clock_gettime(CLOCK_MONOTONIC, abs);
147 abs->tv_sec += us / 1000000;
148 abs->tv_nsec += (us % 1000000) * 1000;
149 abs->tv_sec += abs->tv_nsec / 1000000000;
150 abs->tv_nsec %= 1000000000;
151 return;
152 }
153#endif
154
155 struct timespec ts;
156 MICROSECONDS_TO_TIMESPEC(us, ts);
157 *abs = ts;
158}
159
160
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000161/* A pthread mutex isn't sufficient to model the Python lock type
162 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
163 * following are undefined:
164 * -> a thread tries to lock a mutex it already has locked
165 * -> a thread tries to unlock a mutex locked by a different thread
166 * pthread mutexes are designed for serializing threads over short pieces
167 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000168 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000169 *
170 * The pthread_lock struct implements a Python lock as a "locked?" bit
171 * and a <condition, mutex> pair. In general, if the bit can be acquired
172 * instantly, it is, else the pair is used to block the thread until the
173 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000174 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000175
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000176typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 char locked; /* 0=unlocked, 1=locked */
178 /* a <cond, mutex> pair to handle an acquire of a locked lock */
179 pthread_cond_t lock_released;
180 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000181} pthread_lock;
182
Guido van Rossum9e46e561998-10-07 16:39:47 +0000183#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100184#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
185 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000186
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000187/*
188 * Initialization.
189 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000190static void
191PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000192{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000193#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200194 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000196#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900197 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000198}
199
200/*
201 * Thread support.
202 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000203
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530204/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
205 "void func(void *)" to "void* func(void *)": always return NULL.
206
207 PyThread_start_new_thread() uses "void func(void *)" type, whereas
208 pthread_create() requires a void* return value. */
209typedef struct {
210 void (*func) (void *);
211 void *arg;
212} pythread_callback;
213
214static void *
215pythread_wrapper(void *arg)
216{
217 /* copy func and func_arg and free the temporary structure */
218 pythread_callback *callback = arg;
219 void (*func)(void *) = callback->func;
220 void *func_arg = callback->arg;
221 PyMem_RawFree(arg);
222
223 func(func_arg);
224 return NULL;
225}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000226
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200227unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000228PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 pthread_t th;
231 int status;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000232#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000234#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000235#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000237#endif
238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 dprintf(("PyThread_start_new_thread called\n"));
240 if (!initialized)
241 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000242
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000243#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200245 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000246#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000247#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100248 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600249 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
250 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 if (tss != 0) {
252 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
253 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200254 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 }
256 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000257#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000260#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000261
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530262 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
263
264 if (callback == NULL) {
265 return PYTHREAD_INVALID_THREAD_ID;
266 }
267
268 callback->func = func;
269 callback->arg = arg;
270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000272#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000274#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000276#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530277 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000278
Fred Drake03459a52001-11-09 16:00:41 +0000279#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000281#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530282
283 if (status != 0) {
284 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200285 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530286 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000289
Guido van Rossum3c288632001-10-16 21:13:49 +0000290#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200291 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000292#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200293 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000294#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000295}
296
Trent Mick635f6fb2000-08-23 21:33:05 +0000297/* XXX This implementation is considered (to quote Tim Peters) "inherently
298 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000299 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200300 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100301 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000302*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200303unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000304PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 volatile pthread_t threadid;
307 if (!initialized)
308 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200310 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000311}
312
Jake Teslerb121f632019-05-22 08:43:17 -0700313#ifdef PY_HAVE_THREAD_NATIVE_ID
314unsigned long
315PyThread_get_thread_native_id(void)
316{
317 if (!initialized)
318 PyThread_init_thread();
319#ifdef __APPLE__
320 uint64_t native_id;
321 (void) pthread_threadid_np(NULL, &native_id);
322#elif defined(__linux__)
323 pid_t native_id;
324 native_id = syscall(SYS_gettid);
325#elif defined(__FreeBSD__)
326 int native_id;
327 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100328#elif defined(__OpenBSD__)
329 pid_t native_id;
330 native_id = getthrid();
Jake Teslerb121f632019-05-22 08:43:17 -0700331#endif
332 return (unsigned long) native_id;
333}
334#endif
335
Victor Stinnerc664b342019-05-04 11:48:05 -0400336void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000337PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000338{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200340 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200342 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000343}
344
Martin v. Löwiscc898662002-03-17 09:53:51 +0000345#ifdef USE_SEMAPHORES
346
347/*
348 * Lock support.
349 */
350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000352PyThread_allocate_lock(void)
353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 sem_t *lock;
355 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 dprintf(("PyThread_allocate_lock called\n"));
358 if (!initialized)
359 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000360
Victor Stinner80aa5652013-07-07 17:17:59 +0200361 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (lock) {
364 status = sem_init(lock,0,1);
365 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200368 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 lock = NULL;
370 }
371 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000372
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600373 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000375}
376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000378PyThread_free_lock(PyThread_type_lock lock)
379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 sem_t *thelock = (sem_t *)lock;
381 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000382
Christian Heimes56379c02012-12-02 08:37:00 +0100383 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 if (!thelock)
387 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 status = sem_destroy(thelock);
390 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000391
Victor Stinner80aa5652013-07-07 17:17:59 +0200392 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000393}
394
395/*
396 * As of February 2002, Cygwin thread implementations mistakenly report error
397 * codes in the return value of the sem_ calls (like the pthread_ functions).
398 * Correct implementations return -1 and put the code in errno. This supports
399 * either.
400 */
401static int
402fix_status(int status)
403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000405}
406
Antoine Pitrou810023d2010-12-15 22:59:16 +0000407PyLockStatus
408PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
409 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000410{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000411 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 sem_t *thelock = (sem_t *)lock;
413 int status, error = 0;
414 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700415 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000416
Christian Heimes56379c02012-12-02 08:37:00 +0100417 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000418 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
419 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000420
Victor Stinner850a18e2017-10-24 16:53:32 -0700421 if (microseconds > PY_TIMEOUT_MAX) {
422 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
423 }
424
425 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700427
428 if (!intr_flag) {
429 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
430 check done above */
431 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
432 deadline = _PyTime_GetMonotonicClock() + timeout;
433 }
434 }
435
436 while (1) {
437 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700439 }
440 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700442 }
443 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700445 }
446
Antoine Pitrou810023d2010-12-15 22:59:16 +0000447 /* Retry if interrupted by a signal, unless the caller wants to be
448 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700449 if (intr_flag || status != EINTR) {
450 break;
451 }
452
453 if (microseconds > 0) {
454 /* wait interrupted by a signal (EINTR): recompute the timeout */
455 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
456 if (dt < 0) {
457 status = ETIMEDOUT;
458 break;
459 }
460 else if (dt > 0) {
461 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
462 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
463 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
464 check done above */
465 Py_UNREACHABLE();
466 }
467 /* no need to update microseconds value, the code only care
468 if (microseconds > 0 or (microseconds == 0). */
469 }
470 else {
471 microseconds = 0;
472 }
473 }
474 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000475
Antoine Pitrou810023d2010-12-15 22:59:16 +0000476 /* Don't check the status if we're stopping because of an interrupt. */
477 if (!(intr_flag && status == EINTR)) {
478 if (microseconds > 0) {
479 if (status != ETIMEDOUT)
480 CHECK_STATUS("sem_timedwait");
481 }
482 else if (microseconds == 0) {
483 if (status != EAGAIN)
484 CHECK_STATUS("sem_trywait");
485 }
486 else {
487 CHECK_STATUS("sem_wait");
488 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000490
Antoine Pitrou810023d2010-12-15 22:59:16 +0000491 if (status == 0) {
492 success = PY_LOCK_ACQUIRED;
493 } else if (intr_flag && status == EINTR) {
494 success = PY_LOCK_INTR;
495 } else {
496 success = PY_LOCK_FAILURE;
497 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498
Antoine Pitrou810023d2010-12-15 22:59:16 +0000499 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
500 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000502}
503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000505PyThread_release_lock(PyThread_type_lock lock)
506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 sem_t *thelock = (sem_t *)lock;
508 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000509
Christian Heimes56379c02012-12-02 08:37:00 +0100510 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 status = sem_post(thelock);
514 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000515}
516
517#else /* USE_SEMAPHORES */
518
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000519/*
520 * Lock support.
521 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000523PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000524{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 pthread_lock *lock;
526 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 dprintf(("PyThread_allocate_lock called\n"));
529 if (!initialized)
530 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000531
Victor Stinner80aa5652013-07-07 17:17:59 +0200532 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 if (lock) {
534 memset((void *)lock, '\0', sizeof(pthread_lock));
535 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000536
Inada Naoki001fee12019-02-20 10:00:09 +0900537 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100538 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 /* Mark the pthread mutex underlying a Python mutex as
540 pure happens-before. We can't simply mark the
541 Python-level mutex as a mutex because it can be
542 acquired and released in different threads, which
543 will cause errors. */
544 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000545
Inada Naoki001fee12019-02-20 10:00:09 +0900546 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100547 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200550 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 lock = 0;
552 }
553 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000554
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600555 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000557}
558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000560PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 pthread_lock *thelock = (pthread_lock *)lock;
563 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000564
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200565 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000567
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000568 /* some pthread-like implementations tie the mutex to the cond
569 * and must have the cond destroyed first.
570 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100572 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000573
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000574 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100575 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000576
Victor Stinner80aa5652013-07-07 17:17:59 +0200577 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000578}
579
Antoine Pitrou810023d2010-12-15 22:59:16 +0000580PyLockStatus
581PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
582 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000583{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200584 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 pthread_lock *thelock = (pthread_lock *)lock;
586 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000587
Antoine Pitrou810023d2010-12-15 22:59:16 +0000588 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
589 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000590
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200591 if (microseconds == 0) {
592 status = pthread_mutex_trylock( &thelock->mut );
593 if (status != EBUSY)
594 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
595 }
596 else {
597 status = pthread_mutex_lock( &thelock->mut );
598 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
599 }
600 if (status == 0) {
601 if (thelock->locked == 0) {
602 success = PY_LOCK_ACQUIRED;
603 }
604 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900605 struct timespec abs;
606 if (microseconds > 0) {
607 _PyThread_cond_after(microseconds, &abs);
608 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200609 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000610
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200611 /* mut must be locked by me -- part of the condition
612 * protocol */
613 while (success == PY_LOCK_FAILURE) {
614 if (microseconds > 0) {
615 status = pthread_cond_timedwait(
616 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900617 &thelock->mut, &abs);
618 if (status == 1) {
619 break;
620 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200621 if (status == ETIMEDOUT)
622 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900623 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200624 }
625 else {
626 status = pthread_cond_wait(
627 &thelock->lock_released,
628 &thelock->mut);
629 CHECK_STATUS_PTHREAD("pthread_cond_wait");
630 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000631
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200632 if (intr_flag && status == 0 && thelock->locked) {
633 /* We were woken up, but didn't get the lock. We probably received
634 * a signal. Return PY_LOCK_INTR to allow the caller to handle
635 * it and retry. */
636 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200638 }
639 else if (status == 0 && !thelock->locked) {
640 success = PY_LOCK_ACQUIRED;
641 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000642 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200644 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
645 status = pthread_mutex_unlock( &thelock->mut );
646 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000648
Antoine Pitrou810023d2010-12-15 22:59:16 +0000649 if (error) success = PY_LOCK_FAILURE;
650 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
651 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000653}
654
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000656PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 pthread_lock *thelock = (pthread_lock *)lock;
659 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000660
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200661 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000663
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100665 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000668
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 /* wake up someone (anyone, if any) waiting on the lock */
670 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100671 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000672
673 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100674 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000675}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000676
677#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000678
Antoine Pitrou810023d2010-12-15 22:59:16 +0000679int
680PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
681{
682 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
683}
684
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000685/* set the thread stack size.
686 * Return 0 if size is valid, -1 if size is invalid,
687 * -2 if setting stack size is not supported.
688 */
689static int
690_pythread_pthread_set_stacksize(size_t size)
691{
692#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 pthread_attr_t attrs;
694 size_t tss_min;
695 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000696#endif
697
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 /* set to default */
699 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100700 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 return 0;
702 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000703
704#if defined(THREAD_STACK_SIZE)
705#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
707 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000708#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000710#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 if (size >= tss_min) {
712 /* validate stack size by setting thread attribute */
713 if (pthread_attr_init(&attrs) == 0) {
714 rc = pthread_attr_setstacksize(&attrs, size);
715 pthread_attr_destroy(&attrs);
716 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100717 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 return 0;
719 }
720 }
721 }
722 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000723#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000725#endif
726}
727
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000729
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000730
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900731/* Thread Local Storage (TLS) API
732
733 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
734*/
735
736/* Issue #25658: On platforms where native TLS key is defined in a way that
737 cannot be safely cast to int, PyThread_create_key returns immediately a
738 failure status and other TLS functions all are no-ops. This indicates
739 clearly that the old API is not supported on platforms where it cannot be
740 used reliably, and that no effort will be made to add such support.
741
742 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
743 removing this API.
744*/
745
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000746int
747PyThread_create_key(void)
748{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900749#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000750 pthread_key_t key;
751 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200752 if (fail)
753 return -1;
754 if (key > INT_MAX) {
755 /* Issue #22206: handle integer overflow */
756 pthread_key_delete(key);
757 errno = ENOMEM;
758 return -1;
759 }
760 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900761#else
762 return -1; /* never return valid key value. */
763#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000764}
765
766void
767PyThread_delete_key(int key)
768{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900769#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000770 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900771#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000772}
773
774void
775PyThread_delete_key_value(int key)
776{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900777#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000778 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900779#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000780}
781
782int
783PyThread_set_key_value(int key, void *value)
784{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900785#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
786 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000787 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900788#else
789 return -1;
790#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000791}
792
793void *
794PyThread_get_key_value(int key)
795{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900796#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000797 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900798#else
799 return NULL;
800#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000801}
802
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900803
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000804void
805PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900806{
807}
808
809
810/* Thread Specific Storage (TSS) API
811
812 Platform-specific components of TSS API implementation.
813*/
814
815int
816PyThread_tss_create(Py_tss_t *key)
817{
818 assert(key != NULL);
819 /* If the key has been created, function is silently skipped. */
820 if (key->_is_initialized) {
821 return 0;
822 }
823
824 int fail = pthread_key_create(&(key->_key), NULL);
825 if (fail) {
826 return -1;
827 }
828 key->_is_initialized = 1;
829 return 0;
830}
831
832void
833PyThread_tss_delete(Py_tss_t *key)
834{
835 assert(key != NULL);
836 /* If the key has not been created, function is silently skipped. */
837 if (!key->_is_initialized) {
838 return;
839 }
840
841 pthread_key_delete(key->_key);
842 /* pthread has not provided the defined invalid value for the key. */
843 key->_is_initialized = 0;
844}
845
846int
847PyThread_tss_set(Py_tss_t *key, void *value)
848{
849 assert(key != NULL);
850 int fail = pthread_setspecific(key->_key, value);
851 return fail ? -1 : 0;
852}
853
854void *
855PyThread_tss_get(Py_tss_t *key)
856{
857 assert(key != NULL);
858 return pthread_getspecific(key->_key);
859}