blob: 5678b05ced3698e973c6ae01e3e6eafa295056e7 [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() */
Miss Islington (bot)886d83e2019-06-13 15:54:04 -070021#elif defined(_AIX)
22# include <sys/thread.h> /* thread_self() */
23#elif defined(__NetBSD__)
24# include <lwp.h> /* _lwp_self() */
Jake Teslerb121f632019-05-22 08:43:17 -070025#endif
26
Thomas Wouters0e3f5912006-08-11 14:57:12 +000027/* The POSIX spec requires that use of pthread_attr_setstacksize
28 be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
29#ifdef _POSIX_THREAD_ATTR_STACKSIZE
30#ifndef THREAD_STACK_SIZE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031#define THREAD_STACK_SIZE 0 /* use default stack size */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000032#endif
Ned Deily9a7c5242011-05-28 00:19:56 -070033
Ned Deily7ca97d52012-03-13 11:18:18 -070034/* The default stack size for new threads on OSX and BSD is small enough that
35 * we'll get hard crashes instead of 'maximum recursion depth exceeded'
36 * exceptions.
37 *
38 * The default stack sizes below are the empirically determined minimal stack
39 * sizes where a simple recursive function doesn't cause a hard crash.
40 */
41#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
42#undef THREAD_STACK_SIZE
Miss Islington (bot)83996412019-08-01 07:38:57 -070043/* Note: This matches the value of -Wl,-stack_size in configure.ac */
44#define THREAD_STACK_SIZE 0x1000000
Ned Deily7ca97d52012-03-13 11:18:18 -070045#endif
46#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
Ned Deily9a7c5242011-05-28 00:19:56 -070047#undef THREAD_STACK_SIZE
48#define THREAD_STACK_SIZE 0x400000
49#endif
Miss Islington (bot)f92bb6e2019-08-28 22:35:41 -070050#if defined(_AIX) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
51#undef THREAD_STACK_SIZE
52#define THREAD_STACK_SIZE 0x200000
53#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054/* for safety, ensure a viable minimum stacksize */
Victor Stinner8c663fd2017-11-08 14:44:44 -080055#define THREAD_STACK_MIN 0x8000 /* 32 KiB */
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
57#ifdef THREAD_STACK_SIZE
58#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
59#endif
60#endif
61
Martin v. Löwis42ab61e2002-03-17 17:19:00 +000062/* The POSIX spec says that implementations supporting the sem_*
63 family of functions must indicate this by defining
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 _POSIX_SEMAPHORES. */
Martin v. Löwiscc898662002-03-17 09:53:51 +000065#ifdef _POSIX_SEMAPHORES
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
Martin v. Löwis8b8fb3d2005-03-28 12:34:20 +000067 we need to add 0 to make it work there as well. */
68#if (_POSIX_SEMAPHORES+0) == -1
Anthony Baxter19b23692005-03-16 04:15:07 +000069#define HAVE_BROKEN_POSIX_SEMAPHORES
70#else
Martin v. Löwiscc898662002-03-17 09:53:51 +000071#include <semaphore.h>
72#include <errno.h>
73#endif
Anthony Baxter19b23692005-03-16 04:15:07 +000074#endif
Guido van Rossum66020991996-06-11 18:32:18 +000075
Guido van Rossumd6353e21997-05-13 17:51:13 +000076
Martin v. Löwiscc898662002-03-17 09:53:51 +000077/* Whether or not to use semaphores directly rather than emulating them with
78 * mutexes and condition variables:
79 */
Antoine Pitrou19f8edc2010-10-10 08:37:22 +000080#if (defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) && \
81 defined(HAVE_SEM_TIMEDWAIT))
Martin v. Löwiscc898662002-03-17 09:53:51 +000082# define USE_SEMAPHORES
83#else
84# undef USE_SEMAPHORES
85#endif
86
87
Guido van Rossum80230992001-10-12 21:49:17 +000088/* On platforms that don't use standard POSIX threads pthread_sigmask()
89 * isn't present. DEC threads uses sigprocmask() instead as do most
90 * other UNIX International compliant systems that don't have the full
91 * pthread implementation.
92 */
Jason Tishlerfac083d2003-07-22 15:20:49 +000093#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
Guido van Rossum80230992001-10-12 21:49:17 +000094# define SET_THREAD_SIGMASK pthread_sigmask
95#else
96# define SET_THREAD_SIGMASK sigprocmask
97#endif
98
99
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000100/* We assume all modern POSIX systems have gettimeofday() */
101#ifdef GETTIMEOFDAY_NO_TZ
102#define GETTIMEOFDAY(ptv) gettimeofday(ptv)
103#else
104#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL)
105#endif
106
107#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \
108do { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 struct timeval tv; \
110 GETTIMEOFDAY(&tv); \
111 tv.tv_usec += microseconds % 1000000; \
112 tv.tv_sec += microseconds / 1000000; \
113 tv.tv_sec += tv.tv_usec / 1000000; \
114 tv.tv_usec %= 1000000; \
115 ts.tv_sec = tv.tv_sec; \
116 ts.tv_nsec = tv.tv_usec * 1000; \
Antoine Pitrou7c3e5772010-04-14 15:44:10 +0000117} while(0)
118
119
Inada Naoki001fee12019-02-20 10:00:09 +0900120/*
121 * pthread_cond support
122 */
123
124#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
125// monotonic is supported statically. It doesn't mean it works on runtime.
126#define CONDATTR_MONOTONIC
127#endif
128
129// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported.
130static pthread_condattr_t *condattr_monotonic = NULL;
131
132static void
133init_condattr()
134{
135#ifdef CONDATTR_MONOTONIC
136 static pthread_condattr_t ca;
137 pthread_condattr_init(&ca);
138 if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) {
139 condattr_monotonic = &ca; // Use monotonic clock
140 }
141#endif
142}
143
144int
145_PyThread_cond_init(PyCOND_T *cond)
146{
147 return pthread_cond_init(cond, condattr_monotonic);
148}
149
150void
151_PyThread_cond_after(long long us, struct timespec *abs)
152{
153#ifdef CONDATTR_MONOTONIC
154 if (condattr_monotonic) {
155 clock_gettime(CLOCK_MONOTONIC, abs);
156 abs->tv_sec += us / 1000000;
157 abs->tv_nsec += (us % 1000000) * 1000;
158 abs->tv_sec += abs->tv_nsec / 1000000000;
159 abs->tv_nsec %= 1000000000;
160 return;
161 }
162#endif
163
164 struct timespec ts;
165 MICROSECONDS_TO_TIMESPEC(us, ts);
166 *abs = ts;
167}
168
169
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000170/* A pthread mutex isn't sufficient to model the Python lock type
171 * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
172 * following are undefined:
173 * -> a thread tries to lock a mutex it already has locked
174 * -> a thread tries to unlock a mutex locked by a different thread
175 * pthread mutexes are designed for serializing threads over short pieces
176 * of code anyway, so wouldn't be an appropriate implementation of
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000177 * Python's locks regardless.
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000178 *
179 * The pthread_lock struct implements a Python lock as a "locked?" bit
180 * and a <condition, mutex> pair. In general, if the bit can be acquired
181 * instantly, it is, else the pair is used to block the thread until the
182 * bit is cleared. 9 May 1994 tim@ksr.com
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000183 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000184
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000185typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 char locked; /* 0=unlocked, 1=locked */
187 /* a <cond, mutex> pair to handle an acquire of a locked lock */
188 pthread_cond_t lock_released;
189 pthread_mutex_t mut;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000190} pthread_lock;
191
Guido van Rossum9e46e561998-10-07 16:39:47 +0000192#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100193#define CHECK_STATUS_PTHREAD(name) if (status != 0) { fprintf(stderr, \
194 "%s: %s\n", name, strerror(status)); error = 1; }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000195
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000196/*
197 * Initialization.
198 */
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000199static void
200PyThread__init_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000201{
Guido van Rossumd21744a1998-09-10 03:04:40 +0000202#if defined(_AIX) && defined(__GNUC__)
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200203 extern void pthread_init(void);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 pthread_init();
Guido van Rossumd21744a1998-09-10 03:04:40 +0000205#endif
Inada Naoki001fee12019-02-20 10:00:09 +0900206 init_condattr();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000207}
208
209/*
210 * Thread support.
211 */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000212
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530213/* bpo-33015: pythread_callback struct and pythread_wrapper() cast
214 "void func(void *)" to "void* func(void *)": always return NULL.
215
216 PyThread_start_new_thread() uses "void func(void *)" type, whereas
217 pthread_create() requires a void* return value. */
218typedef struct {
219 void (*func) (void *);
220 void *arg;
221} pythread_callback;
222
223static void *
224pythread_wrapper(void *arg)
225{
226 /* copy func and func_arg and free the temporary structure */
227 pythread_callback *callback = arg;
228 void (*func)(void *) = callback->func;
229 void *func_arg = callback->arg;
230 PyMem_RawFree(arg);
231
232 func(func_arg);
233 return NULL;
234}
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000235
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200236unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000237PyThread_start_new_thread(void (*func)(void *), void *arg)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 pthread_t th;
240 int status;
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 pthread_attr_t attrs;
Jack Jansenc51395d2001-08-29 15:24:53 +0000243#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000244#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 size_t tss;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000246#endif
247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 dprintf(("PyThread_start_new_thread called\n"));
249 if (!initialized)
250 PyThread_init_thread();
Guido van Rossumd6353e21997-05-13 17:51:13 +0000251
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000252#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 if (pthread_attr_init(&attrs) != 0)
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200254 return PYTHREAD_INVALID_THREAD_ID;
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000255#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#if defined(THREAD_STACK_SIZE)
Victor Stinner50b48572018-11-01 01:51:40 +0100257 PyThreadState *tstate = _PyThreadState_GET();
Eric Snow2ebc5ce2017-09-07 23:51:28 -0600258 size_t stacksize = tstate ? tstate->interp->pythread_stacksize : 0;
259 tss = (stacksize != 0) ? stacksize : THREAD_STACK_SIZE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 if (tss != 0) {
261 if (pthread_attr_setstacksize(&attrs, tss) != 0) {
262 pthread_attr_destroy(&attrs);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200263 return PYTHREAD_INVALID_THREAD_ID;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000264 }
265 }
Jack Jansenc51395d2001-08-29 15:24:53 +0000266#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000267#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000269#endif
Guido van Rossum80230992001-10-12 21:49:17 +0000270
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530271 pythread_callback *callback = PyMem_RawMalloc(sizeof(pythread_callback));
272
273 if (callback == NULL) {
274 return PYTHREAD_INVALID_THREAD_ID;
275 }
276
277 callback->func = func;
278 callback->arg = arg;
279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 status = pthread_create(&th,
Guido van Rossumd0b69ec2001-09-10 14:10:54 +0000281#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 &attrs,
Jack Jansenc51395d2001-08-29 15:24:53 +0000283#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 (pthread_attr_t*)NULL,
Jack Jansenc51395d2001-08-29 15:24:53 +0000285#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530286 pythread_wrapper, callback);
Guido van Rossum80230992001-10-12 21:49:17 +0000287
Fred Drake03459a52001-11-09 16:00:41 +0000288#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 pthread_attr_destroy(&attrs);
Jack Jansenc51395d2001-08-29 15:24:53 +0000290#endif
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530291
292 if (status != 0) {
293 PyMem_RawFree(callback);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200294 return PYTHREAD_INVALID_THREAD_ID;
Siddhesh Poyarekar9eea6ea2018-11-30 20:44:25 +0530295 }
Martin v. Löwis910ae622003-04-19 07:44:52 +0000296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 pthread_detach(th);
Martin v. Löwis910ae622003-04-19 07:44:52 +0000298
Guido van Rossum3c288632001-10-16 21:13:49 +0000299#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200300 return (unsigned long) th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000301#else
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200302 return (unsigned long) *(unsigned long *) &th;
Guido van Rossum3c288632001-10-16 21:13:49 +0000303#endif
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000304}
305
Trent Mick635f6fb2000-08-23 21:33:05 +0000306/* XXX This implementation is considered (to quote Tim Peters) "inherently
307 hosed" because:
Skip Montanaro6babcc22004-03-03 08:42:23 +0000308 - It does not guarantee the promise that a non-zero integer is returned.
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200309 - The cast to unsigned long is inherently unsafe.
Jesus Cea736e7fc2011-03-14 17:36:54 +0100310 - It is not clear that the 'volatile' (for AIX?) are any longer necessary.
Trent Mick635f6fb2000-08-23 21:33:05 +0000311*/
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200312unsigned long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000313PyThread_get_thread_ident(void)
Guido van Rossume944da81994-05-23 12:43:41 +0000314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 volatile pthread_t threadid;
316 if (!initialized)
317 PyThread_init_thread();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 threadid = pthread_self();
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +0200319 return (unsigned long) threadid;
Guido van Rossume944da81994-05-23 12:43:41 +0000320}
321
Jake Teslerb121f632019-05-22 08:43:17 -0700322#ifdef PY_HAVE_THREAD_NATIVE_ID
323unsigned long
324PyThread_get_thread_native_id(void)
325{
326 if (!initialized)
327 PyThread_init_thread();
328#ifdef __APPLE__
329 uint64_t native_id;
330 (void) pthread_threadid_np(NULL, &native_id);
331#elif defined(__linux__)
332 pid_t native_id;
333 native_id = syscall(SYS_gettid);
334#elif defined(__FreeBSD__)
335 int native_id;
336 native_id = pthread_getthreadid_np();
David Carlier0b9956e2019-06-03 16:43:33 +0100337#elif defined(__OpenBSD__)
338 pid_t native_id;
339 native_id = getthrid();
Miss Islington (bot)886d83e2019-06-13 15:54:04 -0700340#elif defined(_AIX)
341 tid_t native_id;
342 native_id = thread_self();
Miss Islington (bot)c9ca96d2019-06-12 09:03:04 -0700343#elif defined(__NetBSD__)
344 lwpid_t native_id;
345 native_id = _lwp_self();
Jake Teslerb121f632019-05-22 08:43:17 -0700346#endif
347 return (unsigned long) native_id;
348}
349#endif
350
Victor Stinnerc664b342019-05-04 11:48:05 -0400351void _Py_NO_RETURN
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000352PyThread_exit_thread(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000353{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 dprintf(("PyThread_exit_thread called\n"));
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200355 if (!initialized)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 exit(0);
Antoine Pitrou0d5e52d2011-05-04 20:02:30 +0200357 pthread_exit(0);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000358}
359
Martin v. Löwiscc898662002-03-17 09:53:51 +0000360#ifdef USE_SEMAPHORES
361
362/*
363 * Lock support.
364 */
365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366PyThread_type_lock
Martin v. Löwiscc898662002-03-17 09:53:51 +0000367PyThread_allocate_lock(void)
368{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 sem_t *lock;
370 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 dprintf(("PyThread_allocate_lock called\n"));
373 if (!initialized)
374 PyThread_init_thread();
Martin v. Löwiscc898662002-03-17 09:53:51 +0000375
Victor Stinner80aa5652013-07-07 17:17:59 +0200376 lock = (sem_t *)PyMem_RawMalloc(sizeof(sem_t));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 if (lock) {
379 status = sem_init(lock,0,1);
380 CHECK_STATUS("sem_init");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200383 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 lock = NULL;
385 }
386 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000387
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600388 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 return (PyThread_type_lock)lock;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000390}
391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000393PyThread_free_lock(PyThread_type_lock lock)
394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 sem_t *thelock = (sem_t *)lock;
396 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000397
Christian Heimes56379c02012-12-02 08:37:00 +0100398 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 dprintf(("PyThread_free_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 if (!thelock)
402 return;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 status = sem_destroy(thelock);
405 CHECK_STATUS("sem_destroy");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000406
Victor Stinner80aa5652013-07-07 17:17:59 +0200407 PyMem_RawFree((void *)thelock);
Martin v. Löwiscc898662002-03-17 09:53:51 +0000408}
409
410/*
411 * As of February 2002, Cygwin thread implementations mistakenly report error
412 * codes in the return value of the sem_ calls (like the pthread_ functions).
413 * Correct implementations return -1 and put the code in errno. This supports
414 * either.
415 */
416static int
417fix_status(int status)
418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 return (status == -1) ? errno : status;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000420}
421
Antoine Pitrou810023d2010-12-15 22:59:16 +0000422PyLockStatus
423PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
424 int intr_flag)
Martin v. Löwiscc898662002-03-17 09:53:51 +0000425{
Antoine Pitrou810023d2010-12-15 22:59:16 +0000426 PyLockStatus success;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 sem_t *thelock = (sem_t *)lock;
428 int status, error = 0;
429 struct timespec ts;
Victor Stinner850a18e2017-10-24 16:53:32 -0700430 _PyTime_t deadline = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000431
Christian Heimes56379c02012-12-02 08:37:00 +0100432 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrou810023d2010-12-15 22:59:16 +0000433 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
434 lock, microseconds, intr_flag));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000435
Victor Stinner850a18e2017-10-24 16:53:32 -0700436 if (microseconds > PY_TIMEOUT_MAX) {
437 Py_FatalError("Timeout larger than PY_TIMEOUT_MAX");
438 }
439
440 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 MICROSECONDS_TO_TIMESPEC(microseconds, ts);
Victor Stinner850a18e2017-10-24 16:53:32 -0700442
443 if (!intr_flag) {
444 /* cannot overflow thanks to (microseconds > PY_TIMEOUT_MAX)
445 check done above */
446 _PyTime_t timeout = _PyTime_FromNanoseconds(microseconds * 1000);
447 deadline = _PyTime_GetMonotonicClock() + timeout;
448 }
449 }
450
451 while (1) {
452 if (microseconds > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 status = fix_status(sem_timedwait(thelock, &ts));
Victor Stinner850a18e2017-10-24 16:53:32 -0700454 }
455 else if (microseconds == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 status = fix_status(sem_trywait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700457 }
458 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 status = fix_status(sem_wait(thelock));
Victor Stinner850a18e2017-10-24 16:53:32 -0700460 }
461
Antoine Pitrou810023d2010-12-15 22:59:16 +0000462 /* Retry if interrupted by a signal, unless the caller wants to be
463 notified. */
Victor Stinner850a18e2017-10-24 16:53:32 -0700464 if (intr_flag || status != EINTR) {
465 break;
466 }
467
468 if (microseconds > 0) {
469 /* wait interrupted by a signal (EINTR): recompute the timeout */
470 _PyTime_t dt = deadline - _PyTime_GetMonotonicClock();
471 if (dt < 0) {
472 status = ETIMEDOUT;
473 break;
474 }
475 else if (dt > 0) {
476 _PyTime_t realtime_deadline = _PyTime_GetSystemClock() + dt;
477 if (_PyTime_AsTimespec(realtime_deadline, &ts) < 0) {
478 /* Cannot occur thanks to (microseconds > PY_TIMEOUT_MAX)
479 check done above */
480 Py_UNREACHABLE();
481 }
482 /* no need to update microseconds value, the code only care
483 if (microseconds > 0 or (microseconds == 0). */
484 }
485 else {
486 microseconds = 0;
487 }
488 }
489 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000490
Antoine Pitrou810023d2010-12-15 22:59:16 +0000491 /* Don't check the status if we're stopping because of an interrupt. */
492 if (!(intr_flag && status == EINTR)) {
493 if (microseconds > 0) {
494 if (status != ETIMEDOUT)
495 CHECK_STATUS("sem_timedwait");
496 }
497 else if (microseconds == 0) {
498 if (status != EAGAIN)
499 CHECK_STATUS("sem_trywait");
500 }
501 else {
502 CHECK_STATUS("sem_wait");
503 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 }
Martin v. Löwiscc898662002-03-17 09:53:51 +0000505
Antoine Pitrou810023d2010-12-15 22:59:16 +0000506 if (status == 0) {
507 success = PY_LOCK_ACQUIRED;
508 } else if (intr_flag && status == EINTR) {
509 success = PY_LOCK_INTR;
510 } else {
511 success = PY_LOCK_FAILURE;
512 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513
Antoine Pitrou810023d2010-12-15 22:59:16 +0000514 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
515 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 return success;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000517}
518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519void
Martin v. Löwiscc898662002-03-17 09:53:51 +0000520PyThread_release_lock(PyThread_type_lock lock)
521{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 sem_t *thelock = (sem_t *)lock;
523 int status, error = 0;
Martin v. Löwiscc898662002-03-17 09:53:51 +0000524
Christian Heimes56379c02012-12-02 08:37:00 +0100525 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 dprintf(("PyThread_release_lock(%p) called\n", lock));
Martin v. Löwiscc898662002-03-17 09:53:51 +0000527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 status = sem_post(thelock);
529 CHECK_STATUS("sem_post");
Martin v. Löwiscc898662002-03-17 09:53:51 +0000530}
531
532#else /* USE_SEMAPHORES */
533
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000534/*
535 * Lock support.
536 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537PyThread_type_lock
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000538PyThread_allocate_lock(void)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 pthread_lock *lock;
541 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 dprintf(("PyThread_allocate_lock called\n"));
544 if (!initialized)
545 PyThread_init_thread();
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000546
Victor Stinner80aa5652013-07-07 17:17:59 +0200547 lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 if (lock) {
549 memset((void *)lock, '\0', sizeof(pthread_lock));
550 lock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000551
Inada Naoki001fee12019-02-20 10:00:09 +0900552 status = pthread_mutex_init(&lock->mut, NULL);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100553 CHECK_STATUS_PTHREAD("pthread_mutex_init");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 /* Mark the pthread mutex underlying a Python mutex as
555 pure happens-before. We can't simply mark the
556 Python-level mutex as a mutex because it can be
557 acquired and released in different threads, which
558 will cause errors. */
559 _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut);
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000560
Inada Naoki001fee12019-02-20 10:00:09 +0900561 status = _PyThread_cond_init(&lock->lock_released);
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100562 CHECK_STATUS_PTHREAD("pthread_cond_init");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000563
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 if (error) {
Victor Stinner80aa5652013-07-07 17:17:59 +0200565 PyMem_RawFree((void *)lock);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 lock = 0;
567 }
568 }
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000569
Zackery Spytz1a2252e2019-05-06 10:56:51 -0600570 dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 return (PyThread_type_lock) lock;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000572}
573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000575PyThread_free_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 pthread_lock *thelock = (pthread_lock *)lock;
578 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000579
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200580 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 dprintf(("PyThread_free_lock(%p) called\n", lock));
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000582
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000583 /* some pthread-like implementations tie the mutex to the cond
584 * and must have the cond destroyed first.
585 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 status = pthread_cond_destroy( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100587 CHECK_STATUS_PTHREAD("pthread_cond_destroy");
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000588
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000589 status = pthread_mutex_destroy( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100590 CHECK_STATUS_PTHREAD("pthread_mutex_destroy");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000591
Victor Stinner80aa5652013-07-07 17:17:59 +0200592 PyMem_RawFree((void *)thelock);
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000593}
594
Antoine Pitrou810023d2010-12-15 22:59:16 +0000595PyLockStatus
596PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds,
597 int intr_flag)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000598{
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200599 PyLockStatus success = PY_LOCK_FAILURE;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 pthread_lock *thelock = (pthread_lock *)lock;
601 int status, error = 0;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000602
Antoine Pitrou810023d2010-12-15 22:59:16 +0000603 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n",
604 lock, microseconds, intr_flag));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000605
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200606 if (microseconds == 0) {
607 status = pthread_mutex_trylock( &thelock->mut );
608 if (status != EBUSY)
609 CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]");
610 }
611 else {
612 status = pthread_mutex_lock( &thelock->mut );
613 CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]");
614 }
615 if (status == 0) {
616 if (thelock->locked == 0) {
617 success = PY_LOCK_ACQUIRED;
618 }
619 else if (microseconds != 0) {
Inada Naoki001fee12019-02-20 10:00:09 +0900620 struct timespec abs;
621 if (microseconds > 0) {
622 _PyThread_cond_after(microseconds, &abs);
623 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200624 /* continue trying until we get the lock */
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000625
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200626 /* mut must be locked by me -- part of the condition
627 * protocol */
628 while (success == PY_LOCK_FAILURE) {
629 if (microseconds > 0) {
630 status = pthread_cond_timedwait(
631 &thelock->lock_released,
Inada Naoki001fee12019-02-20 10:00:09 +0900632 &thelock->mut, &abs);
633 if (status == 1) {
634 break;
635 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200636 if (status == ETIMEDOUT)
637 break;
Inada Naoki001fee12019-02-20 10:00:09 +0900638 CHECK_STATUS_PTHREAD("pthread_cond_timedwait");
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200639 }
640 else {
641 status = pthread_cond_wait(
642 &thelock->lock_released,
643 &thelock->mut);
644 CHECK_STATUS_PTHREAD("pthread_cond_wait");
645 }
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000646
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200647 if (intr_flag && status == 0 && thelock->locked) {
648 /* We were woken up, but didn't get the lock. We probably received
649 * a signal. Return PY_LOCK_INTR to allow the caller to handle
650 * it and retry. */
651 success = PY_LOCK_INTR;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000652 break;
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200653 }
654 else if (status == 0 && !thelock->locked) {
655 success = PY_LOCK_ACQUIRED;
656 }
Antoine Pitrou810023d2010-12-15 22:59:16 +0000657 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 }
Antoine Pitrouf84ac422017-06-26 20:41:07 +0200659 if (success == PY_LOCK_ACQUIRED) thelock->locked = 1;
660 status = pthread_mutex_unlock( &thelock->mut );
661 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 }
Martin v. Löwis1509a152003-04-18 11:11:09 +0000663
Antoine Pitrou810023d2010-12-15 22:59:16 +0000664 if (error) success = PY_LOCK_FAILURE;
665 dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n",
666 lock, microseconds, intr_flag, success));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 return success;
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000668}
669
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000671PyThread_release_lock(PyThread_type_lock lock)
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000673 pthread_lock *thelock = (pthread_lock *)lock;
674 int status, error = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000675
Antoine Pitrou9a00e0a2013-06-18 22:17:48 +0200676 (void) error; /* silence unused-but-set-variable warning */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000677 dprintf(("PyThread_release_lock(%p) called\n", lock));
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 status = pthread_mutex_lock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100680 CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000681
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 thelock->locked = 0;
Guido van Rossumb98b1b31994-05-11 08:42:04 +0000683
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 /* wake up someone (anyone, if any) waiting on the lock */
685 status = pthread_cond_signal( &thelock->lock_released );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100686 CHECK_STATUS_PTHREAD("pthread_cond_signal");
Kristján Valur Jónsson187aa542012-06-05 22:17:42 +0000687
688 status = pthread_mutex_unlock( &thelock->mut );
Daniel Birnstield7fa6b22017-03-21 14:06:06 +0100689 CHECK_STATUS_PTHREAD("pthread_mutex_unlock[3]");
Guido van Rossum2c8cb9f1994-05-09 15:12:46 +0000690}
Martin v. Löwiscc898662002-03-17 09:53:51 +0000691
692#endif /* USE_SEMAPHORES */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000693
Antoine Pitrou810023d2010-12-15 22:59:16 +0000694int
695PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
696{
697 return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
698}
699
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000700/* set the thread stack size.
701 * Return 0 if size is valid, -1 if size is invalid,
702 * -2 if setting stack size is not supported.
703 */
704static int
705_pythread_pthread_set_stacksize(size_t size)
706{
707#if defined(THREAD_STACK_SIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 pthread_attr_t attrs;
709 size_t tss_min;
710 int rc = 0;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000711#endif
712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 /* set to default */
714 if (size == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100715 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 return 0;
717 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000718
719#if defined(THREAD_STACK_SIZE)
720#if defined(PTHREAD_STACK_MIN)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
722 : THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000723#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 tss_min = THREAD_STACK_MIN;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000725#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 if (size >= tss_min) {
727 /* validate stack size by setting thread attribute */
728 if (pthread_attr_init(&attrs) == 0) {
729 rc = pthread_attr_setstacksize(&attrs, size);
730 pthread_attr_destroy(&attrs);
731 if (rc == 0) {
Victor Stinner50b48572018-11-01 01:51:40 +0100732 _PyInterpreterState_GET_UNSAFE()->pythread_stacksize = size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 return 0;
734 }
735 }
736 }
737 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000738#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000740#endif
741}
742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000744
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000745
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900746/* Thread Local Storage (TLS) API
747
748 This API is DEPRECATED since Python 3.7. See PEP 539 for details.
749*/
750
751/* Issue #25658: On platforms where native TLS key is defined in a way that
752 cannot be safely cast to int, PyThread_create_key returns immediately a
753 failure status and other TLS functions all are no-ops. This indicates
754 clearly that the old API is not supported on platforms where it cannot be
755 used reliably, and that no effort will be made to add such support.
756
757 Note: PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT will be unnecessary after
758 removing this API.
759*/
760
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000761int
762PyThread_create_key(void)
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_t key;
766 int fail = pthread_key_create(&key, NULL);
Victor Stinnerdaca3d72014-08-17 22:11:06 +0200767 if (fail)
768 return -1;
769 if (key > INT_MAX) {
770 /* Issue #22206: handle integer overflow */
771 pthread_key_delete(key);
772 errno = ENOMEM;
773 return -1;
774 }
775 return (int)key;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900776#else
777 return -1; /* never return valid key value. */
778#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000779}
780
781void
782PyThread_delete_key(int key)
783{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900784#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000785 pthread_key_delete(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900786#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000787}
788
789void
790PyThread_delete_key_value(int key)
791{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900792#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000793 pthread_setspecific(key, NULL);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900794#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000795}
796
797int
798PyThread_set_key_value(int key, void *value)
799{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900800#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
801 int fail = pthread_setspecific(key, value);
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000802 return fail ? -1 : 0;
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900803#else
804 return -1;
805#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000806}
807
808void *
809PyThread_get_key_value(int key)
810{
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900811#ifdef PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000812 return pthread_getspecific(key);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900813#else
814 return NULL;
815#endif
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000816}
817
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900818
Kristján Valur Jónsson2fea9b92010-09-20 02:11:49 +0000819void
820PyThread_ReInitTLS(void)
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900821{
822}
823
824
825/* Thread Specific Storage (TSS) API
826
827 Platform-specific components of TSS API implementation.
828*/
829
830int
831PyThread_tss_create(Py_tss_t *key)
832{
833 assert(key != NULL);
834 /* If the key has been created, function is silently skipped. */
835 if (key->_is_initialized) {
836 return 0;
837 }
838
839 int fail = pthread_key_create(&(key->_key), NULL);
840 if (fail) {
841 return -1;
842 }
843 key->_is_initialized = 1;
844 return 0;
845}
846
847void
848PyThread_tss_delete(Py_tss_t *key)
849{
850 assert(key != NULL);
851 /* If the key has not been created, function is silently skipped. */
852 if (!key->_is_initialized) {
853 return;
854 }
855
856 pthread_key_delete(key->_key);
857 /* pthread has not provided the defined invalid value for the key. */
858 key->_is_initialized = 0;
859}
860
861int
862PyThread_tss_set(Py_tss_t *key, void *value)
863{
864 assert(key != NULL);
865 int fail = pthread_setspecific(key->_key, value);
866 return fail ? -1 : 0;
867}
868
869void *
870PyThread_tss_get(Py_tss_t *key)
871{
872 assert(key != NULL);
873 return pthread_getspecific(key->_key);
874}