summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpage <mpage@meta.com>2024-02-12 17:44:00 (GMT)
committerGitHub <noreply@github.com>2024-02-12 17:44:00 (GMT)
commitde7d67b19b9f31d7712de7211ffac5bf6018157f (patch)
tree4312e48fc02b18b828a498dcac0fdb0bc0314e2b
parent879f4546bfbc9c47ef228e7c3d2f126f3d8d64bf (diff)
downloadcpython-de7d67b19b9f31d7712de7211ffac5bf6018157f.zip
cpython-de7d67b19b9f31d7712de7211ffac5bf6018157f.tar.gz
cpython-de7d67b19b9f31d7712de7211ffac5bf6018157f.tar.bz2
gh-114271: Make `PyInterpreterState.threads.count` thread-safe in free-threaded builds (gh-115093)
Use atomics to mutate PyInterpreterState.threads.count.
-rw-r--r--Include/internal/pycore_interp.h2
-rw-r--r--Modules/_threadmodule.c6
2 files changed, 4 insertions, 4 deletions
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 31d8807..485b191 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -112,7 +112,7 @@ struct _is {
/* The thread currently executing in the __main__ module, if any. */
PyThreadState *main;
/* Used in Modules/_threadmodule.c. */
- long count;
+ Py_ssize_t count;
/* Support for runtime thread stack size tuning.
A value of 0 means using the platform's default stack size
or the size specified by the THREAD_STACK_SIZE macro. */
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index df02b02..d7840ea 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -1244,7 +1244,7 @@ thread_run(void *boot_raw)
_PyThreadState_Bind(tstate);
PyEval_AcquireThread(tstate);
- tstate->interp->threads.count++;
+ _Py_atomic_add_ssize(&tstate->interp->threads.count, 1);
PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs);
if (res == NULL) {
@@ -1262,7 +1262,7 @@ thread_run(void *boot_raw)
thread_bootstate_free(boot, 1);
- tstate->interp->threads.count--;
+ _Py_atomic_add_ssize(&tstate->interp->threads.count, -1);
PyThreadState_Clear(tstate);
_PyThreadState_DeleteCurrent(tstate);
@@ -1539,7 +1539,7 @@ static PyObject *
thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
{
PyInterpreterState *interp = _PyInterpreterState_GET();
- return PyLong_FromLong(interp->threads.count);
+ return PyLong_FromSsize_t(_Py_atomic_load_ssize(&interp->threads.count));
}
PyDoc_STRVAR(_count_doc,