blob: c36ce6ff9835d869d94c9e8f3c9057d101a4b881 [file] [log] [blame]
Guido van Rossum34679b71993-01-26 13:33:44 +00001
Guido van Rossum1d5735e1994-08-30 08:27:36 +00002/* Thread package.
3 This is intended to be usable independently from Python.
4 The implementation for system foobar is in a file thread_foobar.h
5 which is included by this file dependent on config settings.
6 Stuff shared by all thread_*.h files is collected here. */
7
Martin v. Löwiscdc44512002-01-12 11:05:12 +00008#include "Python.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01009#include "pycore_pystate.h"
Guido van Rossum1d5735e1994-08-30 08:27:36 +000010
Matthias Klosea2542be2004-08-16 11:35:51 +000011#ifndef _POSIX_THREADS
12/* This means pthreads are not implemented in libc headers, hence the macro
13 not present in unistd.h. But they still can be implemented as an external
14 library (e.g. gnu pth in pthread emulation) */
15# ifdef HAVE_PTHREAD_H
16# include <pthread.h> /* _POSIX_THREADS */
17# endif
18#endif
19
Guido van Rossum2571cc81999-04-07 16:07:23 +000020#ifndef DONT_HAVE_STDIO_H
Guido van Rossum1d5735e1994-08-30 08:27:36 +000021#include <stdio.h>
Guido van Rossum2571cc81999-04-07 16:07:23 +000022#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +000023
Guido van Rossum1d5735e1994-08-30 08:27:36 +000024#include <stdlib.h>
Guido van Rossum1d5735e1994-08-30 08:27:36 +000025
Guido van Rossum49b56061998-10-01 20:42:43 +000026#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027
Guido van Rossum1d5735e1994-08-30 08:27:36 +000028#ifndef _POSIX_THREADS
29
Guido van Rossum539c6622005-09-14 17:49:54 +000030/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
Ezio Melotti13925002011-03-16 11:05:33 +020031 enough of the Posix threads package is implemented to support python
Guido van Rossum539c6622005-09-14 17:49:54 +000032 threads.
33
34 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
Martin Panter7462b6492015-11-02 03:37:02 +000035 a check of __ia64 to verify that we're running on an ia64 system instead
Guido van Rossum539c6622005-09-14 17:49:54 +000036 of a pa-risc system.
37*/
38#ifdef __hpux
39#ifdef _SC_THREADS
40#define _POSIX_THREADS
41#endif
42#endif
43
Sjoerd Mullender66bca321993-12-03 16:54:45 +000044#endif /* _POSIX_THREADS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000045
Guido van Rossum1984f1e1992-08-04 12:41:02 +000046
Guido van Rossum408027e1996-12-30 16:17:54 +000047#ifdef Py_DEBUG
Guido van Rossum1d5735e1994-08-30 08:27:36 +000048static int thread_debug = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049#define dprintf(args) (void)((thread_debug & 1) && printf args)
50#define d2printf(args) ((thread_debug & 8) && printf args)
Guido van Rossum1d5735e1994-08-30 08:27:36 +000051#else
52#define dprintf(args)
53#define d2printf(args)
54#endif
55
Guido van Rossum1984f1e1992-08-04 12:41:02 +000056static int initialized;
57
Thomas Wouters8ec68fd2000-07-24 14:39:50 +000058static void PyThread__init_thread(void); /* Forward */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000059
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000060void
61PyThread_init_thread(void)
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000062{
Guido van Rossum408027e1996-12-30 16:17:54 +000063#ifdef Py_DEBUG
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +020064 const char *p = Py_GETENV("PYTHONTHREADDEBUG");
Sjoerd Mullender66bca321993-12-03 16:54:45 +000065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 if (p) {
67 if (*p)
68 thread_debug = atoi(p);
69 else
70 thread_debug = 1;
71 }
Guido van Rossum408027e1996-12-30 16:17:54 +000072#endif /* Py_DEBUG */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 if (initialized)
74 return;
75 initialized = 1;
76 dprintf(("PyThread_init_thread called\n"));
77 PyThread__init_thread();
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000078}
79
Masayuki Yamamotoaa0aa042017-07-03 20:34:38 +090080#if defined(_POSIX_THREADS)
81# define PYTHREAD_NAME "pthread"
82# include "thread_pthread.h"
83#elif defined(NT_THREADS)
84# define PYTHREAD_NAME "nt"
85# include "thread_nt.h"
86#else
Masayuki Yamamoto731e1892017-10-06 19:41:34 +090087# error "Require native threads. See https://bugs.python.org/issue31370"
Guido van Rossumc3f82b61995-01-17 16:29:31 +000088#endif
89
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000090
Thomas Wouters0e3f5912006-08-11 14:57:12 +000091/* return the current thread stack size */
92size_t
93PyThread_get_stacksize(void)
94{
Victor Stinnercaba55b2018-08-03 15:33:52 +020095 return _PyInterpreterState_Get()->pythread_stacksize;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000096}
97
98/* Only platforms defining a THREAD_SET_STACKSIZE() macro
99 in thread_<platform>.h support changing the stack size.
100 Return 0 if stack size is valid,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 -1 if stack size value is invalid,
102 -2 if setting stack size is not supported. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000103int
104PyThread_set_stacksize(size_t size)
105{
106#if defined(THREAD_SET_STACKSIZE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 return THREAD_SET_STACKSIZE(size);
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000108#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 return -2;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000110#endif
111}
112
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000113
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900114/* Thread Specific Storage (TSS) API
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000115
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900116 Cross-platform components of TSS API implementation.
117*/
Tim Petersfda787f2004-10-09 22:33:09 +0000118
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900119Py_tss_t *
120PyThread_tss_alloc(void)
121{
122 Py_tss_t *new_key = (Py_tss_t *)PyMem_RawMalloc(sizeof(Py_tss_t));
123 if (new_key == NULL) {
124 return NULL;
125 }
126 new_key->_is_initialized = 0;
127 return new_key;
128}
Tim Petersfda787f2004-10-09 22:33:09 +0000129
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900130void
131PyThread_tss_free(Py_tss_t *key)
132{
133 if (key != NULL) {
134 PyThread_tss_delete(key);
135 PyMem_RawFree((void *)key);
136 }
137}
Tim Petersfda787f2004-10-09 22:33:09 +0000138
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900139int
140PyThread_tss_is_created(Py_tss_t *key)
141{
142 assert(key != NULL);
143 return key->_is_initialized;
144}
Tim Petersfda787f2004-10-09 22:33:09 +0000145
Victor Stinner754851f2011-04-19 23:58:51 +0200146
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200147PyDoc_STRVAR(threadinfo__doc__,
148"sys.thread_info\n\
149\n\
Paul Ganssle2bb6bf02019-09-12 03:50:29 +0100150A named tuple holding information about the thread implementation.");
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200151
152static PyStructSequence_Field threadinfo_fields[] = {
153 {"name", "name of the thread implementation"},
154 {"lock", "name of the lock implementation"},
155 {"version", "name and version of the thread library"},
156 {0}
157};
158
159static PyStructSequence_Desc threadinfo_desc = {
160 "sys.thread_info", /* name */
161 threadinfo__doc__, /* doc */
162 threadinfo_fields, /* fields */
163 3
164};
165
166static PyTypeObject ThreadInfoType;
167
Victor Stinner754851f2011-04-19 23:58:51 +0200168PyObject*
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200169PyThread_GetInfo(void)
Victor Stinner754851f2011-04-19 23:58:51 +0200170{
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200171 PyObject *threadinfo, *value;
172 int pos = 0;
Victor Stinnere07f5222011-04-20 12:23:26 +0200173#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
174 && defined(_CS_GNU_LIBPTHREAD_VERSION))
Victor Stinner754851f2011-04-19 23:58:51 +0200175 char buffer[255];
176 int len;
Victor Stinnere07f5222011-04-20 12:23:26 +0200177#endif
Victor Stinner754851f2011-04-19 23:58:51 +0200178
Victor Stinner1c8f0592013-07-22 22:24:54 +0200179 if (ThreadInfoType.tp_name == 0) {
180 if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0)
181 return NULL;
182 }
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200183
184 threadinfo = PyStructSequence_New(&ThreadInfoType);
185 if (threadinfo == NULL)
Victor Stinner754851f2011-04-19 23:58:51 +0200186 return NULL;
187
188 value = PyUnicode_FromString(PYTHREAD_NAME);
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200189 if (value == NULL) {
190 Py_DECREF(threadinfo);
191 return NULL;
192 }
193 PyStructSequence_SET_ITEM(threadinfo, pos++, value);
Victor Stinner754851f2011-04-19 23:58:51 +0200194
195#ifdef _POSIX_THREADS
196#ifdef USE_SEMAPHORES
197 value = PyUnicode_FromString("semaphore");
198#else
199 value = PyUnicode_FromString("mutex+cond");
200#endif
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200201 if (value == NULL) {
202 Py_DECREF(threadinfo);
Victor Stinner754851f2011-04-19 23:58:51 +0200203 return NULL;
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200204 }
205#else
206 Py_INCREF(Py_None);
207 value = Py_None;
208#endif
209 PyStructSequence_SET_ITEM(threadinfo, pos++, value);
Victor Stinner754851f2011-04-19 23:58:51 +0200210
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200211#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
212 && defined(_CS_GNU_LIBPTHREAD_VERSION))
213 value = NULL;
Victor Stinner754851f2011-04-19 23:58:51 +0200214 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
Victor Stinner98ea54c2014-08-15 23:30:40 +0200215 if (1 < len && (size_t)len < sizeof(buffer)) {
Victor Stinner754851f2011-04-19 23:58:51 +0200216 value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
217 if (value == NULL)
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200218 PyErr_Clear();
Victor Stinner754851f2011-04-19 23:58:51 +0200219 }
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200220 if (value == NULL)
Victor Stinner754851f2011-04-19 23:58:51 +0200221#endif
Victor Stinnerd5c355c2011-04-30 14:53:09 +0200222 {
223 Py_INCREF(Py_None);
224 value = Py_None;
225 }
226 PyStructSequence_SET_ITEM(threadinfo, pos++, value);
227 return threadinfo;
Victor Stinner754851f2011-04-19 23:58:51 +0200228}