Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ typedef struct _ts {
* if the thread holds the last reference to the lock, decref'ing the
* lock will delete the lock, and that may trigger arbitrary Python code
* if there's a weakref, with a callback, to the lock. But by this time
* _PyThreadState_Current is already NULL, so only the simplest of C code
* can be allowed to run (in particular it must not be possible to
* _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
* of C code can be allowed to run (in particular it must not be possible to
* release the GIL).
* So instead of holding the lock directly, the tstate holds a weakref to
* the lock: that's the value of on_delete_data below. Decref'ing a
Expand Down Expand Up @@ -307,9 +307,8 @@ PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
/* Assuming the current thread holds the GIL, this is the
PyThreadState for the current thread. */
#ifdef Py_BUILD_CORE
# define _PyThreadState_Current _PyRuntime.gilstate.tstate_current
# define PyThreadState_GET() \
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
((PyThreadState*)_Py_atomic_load_relaxed(&_PyRuntime.gilstate.tstate_current))
#else
# define PyThreadState_GET() PyThreadState_Get()
#endif
Expand Down
4 changes: 2 additions & 2 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1314,8 +1314,8 @@ PyDict_GetItem(PyObject *op, PyObject *key)
/* We can arrive here with a NULL tstate during initialization: try
running "python -Wi" for an example related to string interning.
Let's just hope that no exception occurs then... This must be
_PyThreadState_Current and not PyThreadState_GET() because in debug
mode, the latter complains if tstate is NULL. */
PyThreadState_GET() and not PyThreadState_Get() because the latter
abort Python if tstate is NULL. */
tstate = PyThreadState_GET();
if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */
Expand Down
3 changes: 1 addition & 2 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ PyEval_ReleaseLock(void)
We therefore avoid PyThreadState_GET() which dumps a fatal error
in debug mode.
*/
drop_gil((PyThreadState*)_Py_atomic_load_relaxed(
&_PyThreadState_Current));
drop_gil(PyThreadState_GET());
}

void
Expand Down
43 changes: 20 additions & 23 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
#include "Python.h"
#include "internal/pystate.h"

#define GET_TSTATE() \
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
#define SET_TSTATE(value) \
_Py_atomic_store_relaxed(&_PyThreadState_Current, (uintptr_t)(value))
#define GET_INTERP_STATE() \
(GET_TSTATE()->interp)
#define _PyThreadState_SET(value) \
_Py_atomic_store_relaxed(&_PyRuntime.gilstate.tstate_current, \
(uintptr_t)(value))


/* --------------------------------------------------------------------------
Expand Down Expand Up @@ -309,7 +306,7 @@ _PyInterpreterState_DeleteExceptMain()
PyInterpreterState *
_PyInterpreterState_Get(void)
{
PyThreadState *tstate = GET_TSTATE();
PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL) {
Py_FatalError("_PyInterpreterState_Get(): no current thread state");
}
Expand Down Expand Up @@ -508,7 +505,7 @@ PyObject*
PyState_FindModule(struct PyModuleDef* module)
{
Py_ssize_t index = module->m_base.m_index;
PyInterpreterState *state = GET_INTERP_STATE();
PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE();
PyObject *res;
if (module->m_slots) {
return NULL;
Expand Down Expand Up @@ -536,7 +533,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def)
"PyState_AddModule called on module with slots");
return -1;
}
state = GET_INTERP_STATE();
state = _PyInterpreterState_GET_UNSAFE();
if (!state->modules_by_index) {
state->modules_by_index = PyList_New(0);
if (!state->modules_by_index)
Expand All @@ -554,7 +551,7 @@ int
PyState_AddModule(PyObject* module, struct PyModuleDef* def)
{
Py_ssize_t index;
PyInterpreterState *state = GET_INTERP_STATE();
PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE();
if (!def) {
Py_FatalError("PyState_AddModule: Module Definition is NULL");
return -1;
Expand All @@ -581,7 +578,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
"PyState_RemoveModule called on module with slots");
return -1;
}
state = GET_INTERP_STATE();
state = _PyInterpreterState_GET_UNSAFE();
if (index == 0) {
Py_FatalError("PyState_RemoveModule: Module index invalid.");
return -1;
Expand All @@ -601,7 +598,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
void
_PyState_ClearModules(void)
{
PyInterpreterState *state = GET_INTERP_STATE();
PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE();
if (state->modules_by_index) {
Py_ssize_t i;
for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
Expand Down Expand Up @@ -691,7 +688,7 @@ tstate_delete_common(PyThreadState *tstate)
void
PyThreadState_Delete(PyThreadState *tstate)
{
if (tstate == GET_TSTATE())
if (tstate == PyThreadState_GET())
Py_FatalError("PyThreadState_Delete: tstate is still current");
if (_PyRuntime.gilstate.autoInterpreterState &&
PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate)
Expand All @@ -705,7 +702,7 @@ PyThreadState_Delete(PyThreadState *tstate)
void
PyThreadState_DeleteCurrent()
{
PyThreadState *tstate = GET_TSTATE();
PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL)
Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate");
Expand All @@ -715,7 +712,7 @@ PyThreadState_DeleteCurrent()
{
PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL);
}
SET_TSTATE(NULL);
_PyThreadState_SET(NULL);
PyEval_ReleaseLock();
}

Expand Down Expand Up @@ -760,14 +757,14 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
PyThreadState *
_PyThreadState_UncheckedGet(void)
{
return GET_TSTATE();
return PyThreadState_GET();
}


PyThreadState *
PyThreadState_Get(void)
{
PyThreadState *tstate = GET_TSTATE();
PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL)
Py_FatalError("PyThreadState_Get: no current thread");

Expand All @@ -778,9 +775,9 @@ PyThreadState_Get(void)
PyThreadState *
PyThreadState_Swap(PyThreadState *newts)
{
PyThreadState *oldts = GET_TSTATE();
PyThreadState *oldts = PyThreadState_GET();

SET_TSTATE(newts);
_PyThreadState_SET(newts);
/* It should not be possible for more than one thread state
to be used for a thread. Check this the best we can in debug
builds.
Expand Down Expand Up @@ -809,7 +806,7 @@ PyThreadState_Swap(PyThreadState *newts)
PyObject *
PyThreadState_GetDict(void)
{
PyThreadState *tstate = GET_TSTATE();
PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL)
return NULL;

Expand All @@ -834,7 +831,7 @@ PyThreadState_GetDict(void)
int
PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
{
PyInterpreterState *interp = GET_INTERP_STATE();
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
PyThreadState *p;

/* Although the GIL is held, a few C API functions can be called
Expand Down Expand Up @@ -960,7 +957,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
{
/* Must be the tstate for this thread */
assert(PyGILState_GetThisThreadState()==tstate);
return tstate == GET_TSTATE();
return tstate == PyThreadState_GET();
}

/* Internal initialization/finalization functions called by
Expand Down Expand Up @@ -1087,7 +1084,7 @@ PyGILState_Check(void)
return 1;
}

tstate = GET_TSTATE();
tstate = PyThreadState_GET();
if (tstate == NULL)
return 0;

Expand Down