Skip to content

Commit c3057f3

Browse files
committed
Sync thread.c with CPython
1 parent 6bfebc6 commit c3057f3

File tree

2 files changed

+265
-11
lines changed

2 files changed

+265
-11
lines changed

graalpython/com.oracle.graal.python.cext/src/thread.c

Lines changed: 265 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,155 @@
1-
/* Copyright (c) 2021, 2023, Oracle and/or its affiliates.
1+
/* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2022 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
55
*/
66
#include "capi.h"
77

8-
Py_tss_t* PyThread_tss_alloc(void) {
8+
#if 0 // GraalPy change
9+
/* Thread package.
10+
This is intended to be usable independently from Python.
11+
The implementation for system foobar is in a file thread_foobar.h
12+
which is included by this file dependent on config settings.
13+
Stuff shared by all thread_*.h files is collected here. */
14+
15+
#include "Python.h"
16+
#include "pycore_pystate.h" // _PyInterpreterState_GET()
17+
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
18+
19+
#ifndef _POSIX_THREADS
20+
/* This means pthreads are not implemented in libc headers, hence the macro
21+
not present in unistd.h. But they still can be implemented as an external
22+
library (e.g. gnu pth in pthread emulation) */
23+
# ifdef HAVE_PTHREAD_H
24+
# include <pthread.h> /* _POSIX_THREADS */
25+
# endif
26+
#endif
27+
28+
#ifndef DONT_HAVE_STDIO_H
29+
#include <stdio.h>
30+
#endif
31+
32+
#include <stdlib.h>
33+
34+
#ifndef _POSIX_THREADS
35+
36+
/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
37+
enough of the Posix threads package is implemented to support python
38+
threads.
39+
40+
This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
41+
a check of __ia64 to verify that we're running on an ia64 system instead
42+
of a pa-risc system.
43+
*/
44+
#ifdef __hpux
45+
#ifdef _SC_THREADS
46+
#define _POSIX_THREADS
47+
#endif
48+
#endif
49+
50+
#endif /* _POSIX_THREADS */
51+
52+
53+
#ifdef Py_DEBUG
54+
static int thread_debug = 0;
55+
# define dprintf(args) (void)((thread_debug & 1) && printf args)
56+
#else
57+
# define dprintf(args)
58+
#endif
59+
60+
static int initialized;
61+
62+
static void PyThread__init_thread(void); /* Forward */
63+
64+
void
65+
PyThread_init_thread(void)
66+
{
67+
#ifdef Py_DEBUG
68+
const char *p = Py_GETENV("PYTHONTHREADDEBUG");
69+
70+
if (p) {
71+
if (*p)
72+
thread_debug = atoi(p);
73+
else
74+
thread_debug = 1;
75+
}
76+
#endif /* Py_DEBUG */
77+
if (initialized)
78+
return;
79+
initialized = 1;
80+
dprintf(("PyThread_init_thread called\n"));
81+
PyThread__init_thread();
82+
}
83+
84+
void
85+
_PyThread_debug_deprecation(void)
86+
{
87+
#ifdef Py_DEBUG
88+
if (thread_debug) {
89+
// Flush previous dprintf() logs
90+
fflush(stdout);
91+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
92+
"The threading debug (PYTHONTHREADDEBUG environment "
93+
"variable) is deprecated and will be removed "
94+
"in Python 3.12",
95+
0))
96+
{
97+
_PyErr_WriteUnraisableMsg("at Python startup", NULL);
98+
}
99+
}
100+
#endif
101+
}
102+
103+
#if defined(HAVE_PTHREAD_STUBS)
104+
# define PYTHREAD_NAME "pthread-stubs"
105+
# include "thread_pthread_stubs.h"
106+
#elif defined(_POSIX_THREADS)
107+
# if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__)
108+
# define PYTHREAD_NAME "pthread-stubs"
109+
# else
110+
# define PYTHREAD_NAME "pthread"
111+
# endif
112+
# include "thread_pthread.h"
113+
#elif defined(NT_THREADS)
114+
# define PYTHREAD_NAME "nt"
115+
# include "thread_nt.h"
116+
#else
117+
# error "Require native threads. See https://bugs.python.org/issue31370"
118+
#endif
119+
120+
121+
/* return the current thread stack size */
122+
size_t
123+
PyThread_get_stacksize(void)
124+
{
125+
return _PyInterpreterState_GET()->threads.stacksize;
126+
}
127+
128+
/* Only platforms defining a THREAD_SET_STACKSIZE() macro
129+
in thread_<platform>.h support changing the stack size.
130+
Return 0 if stack size is valid,
131+
-1 if stack size value is invalid,
132+
-2 if setting stack size is not supported. */
133+
int
134+
PyThread_set_stacksize(size_t size)
135+
{
136+
#if defined(THREAD_SET_STACKSIZE)
137+
return THREAD_SET_STACKSIZE(size);
138+
#else
139+
return -2;
140+
#endif
141+
}
142+
#endif // GraalPy change
143+
144+
145+
/* Thread Specific Storage (TSS) API
146+
147+
Cross-platform components of TSS API implementation.
148+
*/
149+
150+
Py_tss_t *
151+
PyThread_tss_alloc(void)
152+
{
9153
Py_tss_t *new_key = (Py_tss_t *)PyMem_RawMalloc(sizeof(Py_tss_t));
10154
if (new_key == NULL) {
11155
return NULL;
@@ -14,18 +158,125 @@ Py_tss_t* PyThread_tss_alloc(void) {
14158
return new_key;
15159
}
16160

17-
void PyThread_tss_free(Py_tss_t *key) {
161+
void
162+
PyThread_tss_free(Py_tss_t *key)
163+
{
18164
if (key != NULL) {
19165
PyThread_tss_delete(key);
20166
PyMem_RawFree((void *)key);
21167
}
22168
}
23169

24-
int PyThread_tss_is_created(Py_tss_t *key) {
170+
int
171+
PyThread_tss_is_created(Py_tss_t *key)
172+
{
173+
assert(key != NULL);
25174
return key->_is_initialized;
26175
}
27176

28-
int PyThread_tss_create(Py_tss_t *key)
177+
178+
#if 0 // GraalPy change
179+
PyDoc_STRVAR(threadinfo__doc__,
180+
"sys.thread_info\n\
181+
\n\
182+
A named tuple holding information about the thread implementation.");
183+
184+
static PyStructSequence_Field threadinfo_fields[] = {
185+
{"name", "name of the thread implementation"},
186+
{"lock", "name of the lock implementation"},
187+
{"version", "name and version of the thread library"},
188+
{0}
189+
};
190+
191+
static PyStructSequence_Desc threadinfo_desc = {
192+
"sys.thread_info", /* name */
193+
threadinfo__doc__, /* doc */
194+
threadinfo_fields, /* fields */
195+
3
196+
};
197+
198+
static PyTypeObject ThreadInfoType;
199+
200+
PyObject*
201+
PyThread_GetInfo(void)
202+
{
203+
PyObject *threadinfo, *value;
204+
int pos = 0;
205+
#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
206+
&& defined(_CS_GNU_LIBPTHREAD_VERSION))
207+
char buffer[255];
208+
int len;
209+
#endif
210+
211+
if (ThreadInfoType.tp_name == 0) {
212+
if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0)
213+
return NULL;
214+
}
215+
216+
threadinfo = PyStructSequence_New(&ThreadInfoType);
217+
if (threadinfo == NULL)
218+
return NULL;
219+
220+
value = PyUnicode_FromString(PYTHREAD_NAME);
221+
if (value == NULL) {
222+
Py_DECREF(threadinfo);
223+
return NULL;
224+
}
225+
PyStructSequence_SET_ITEM(threadinfo, pos++, value);
226+
227+
#ifdef HAVE_PTHREAD_STUBS
228+
value = Py_NewRef(Py_None);
229+
#elif defined(_POSIX_THREADS)
230+
#ifdef USE_SEMAPHORES
231+
value = PyUnicode_FromString("semaphore");
232+
#else
233+
value = PyUnicode_FromString("mutex+cond");
234+
#endif
235+
if (value == NULL) {
236+
Py_DECREF(threadinfo);
237+
return NULL;
238+
}
239+
#else
240+
value = Py_NewRef(Py_None);
241+
#endif
242+
PyStructSequence_SET_ITEM(threadinfo, pos++, value);
243+
244+
#if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
245+
&& defined(_CS_GNU_LIBPTHREAD_VERSION))
246+
value = NULL;
247+
len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
248+
if (1 < len && (size_t)len < sizeof(buffer)) {
249+
value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
250+
if (value == NULL)
251+
PyErr_Clear();
252+
}
253+
if (value == NULL)
254+
#endif
255+
{
256+
Py_INCREF(Py_None);
257+
value = Py_None;
258+
}
259+
PyStructSequence_SET_ITEM(threadinfo, pos++, value);
260+
return threadinfo;
261+
}
262+
263+
264+
void
265+
_PyThread_FiniType(PyInterpreterState *interp)
266+
{
267+
if (!_Py_IsMainInterpreter(interp)) {
268+
return;
269+
}
270+
271+
_PyStructSequence_FiniType(&ThreadInfoType);
272+
}
273+
#endif // GraalPy change
274+
275+
276+
// GraalPy change: In CPython, the following functions have separate implementations for posix and win32 in different files. We just put ours here.
277+
278+
int
279+
PyThread_tss_create(Py_tss_t *key)
29280
{
30281
if (key->_is_initialized) {
31282
return 0;
@@ -35,15 +286,21 @@ int PyThread_tss_create(Py_tss_t *key)
35286
return 0;
36287
}
37288

38-
void* PyThread_tss_get(Py_tss_t *key) {
289+
void *
290+
PyThread_tss_get(Py_tss_t *key)
291+
{
39292
return GraalPyTruffle_tss_get(key->_key);
40293
}
41294

42-
int PyThread_tss_set(Py_tss_t *key, void *value) {
295+
int
296+
PyThread_tss_set(Py_tss_t *key, void *value)
297+
{
43298
return GraalPyTruffle_tss_set(key->_key, value);
44299
}
45300

46-
void PyThread_tss_delete(Py_tss_t *key){
301+
void
302+
PyThread_tss_delete(Py_tss_t *key)
303+
{
47304
if (!key->_is_initialized) {
48305
return;
49306
}

mx.graalpython/mx_graalpython_import.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ def copy(self, source_dir, graalpy_dir, graalpy_path, overrides):
156156
"graalpython/com.oracle.graal.python.cext/src/pystrtod.c": CopyFrom("Python/pystrtod.c"),
157157
"graalpython/com.oracle.graal.python.cext/src/pystrhex.c": CopyFrom("Python/pystrhex.c"),
158158
"graalpython/com.oracle.graal.python.cext/src/typeslots.inc": CopyFrom("Objects/typeslots.inc"),
159-
# These files take functions from CPython, but they don't follow the same structure, so they are impossible
160-
# to meaningfully merge
161-
"graalpython/com.oracle.graal.python.cext/src/thread.c": Ignore(),
162159

163160
"graalpython/com.oracle.graal.python.cext/src": CopyFromWithOverrides("Objects"),
164161

0 commit comments

Comments
 (0)