bpo-35081: Cleanup pystate.c and pystate.h (GH-10240)

* Remove _PyThreadState_Current
* Replace GET_TSTATE() with PyThreadState_GET()
* Replace GET_INTERP_STATE() with _PyInterpreterState_GET_UNSAFE()
* Replace direct access to _PyThreadState_Current with
  PyThreadState_GET()
* Replace _PyThreadState_Current with
  _PyRuntime.gilstate.tstate_current
* Rename SET_TSTATE() to _PyThreadState_SET(), name more
  consistent with _PyThreadState_GET()
* Update outdated comments
This commit is contained in:
Victor Stinner 2018-10-30 15:13:17 +01:00 committed by GitHub
parent 3c09dca4b5
commit 9204fb8623
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 31 deletions

View File

@ -208,8 +208,8 @@ typedef struct _ts {
* if the thread holds the last reference to the lock, decref'ing the * 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 * 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 * 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 * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest
* can be allowed to run (in particular it must not be possible to * of C code can be allowed to run (in particular it must not be possible to
* release the GIL). * release the GIL).
* So instead of holding the lock directly, the tstate holds a weakref to * 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 * the lock: that's the value of on_delete_data below. Decref'ing a
@ -307,9 +307,8 @@ PyAPI_FUNC(int) PyThreadState_SetAsyncExc(unsigned long, PyObject *);
/* Assuming the current thread holds the GIL, this is the /* Assuming the current thread holds the GIL, this is the
PyThreadState for the current thread. */ PyThreadState for the current thread. */
#ifdef Py_BUILD_CORE #ifdef Py_BUILD_CORE
# define _PyThreadState_Current _PyRuntime.gilstate.tstate_current
# define PyThreadState_GET() \ # define PyThreadState_GET() \
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) ((PyThreadState*)_Py_atomic_load_relaxed(&_PyRuntime.gilstate.tstate_current))
#else #else
# define PyThreadState_GET() PyThreadState_Get() # define PyThreadState_GET() PyThreadState_Get()
#endif #endif

View File

@ -1314,8 +1314,8 @@ PyDict_GetItem(PyObject *op, PyObject *key)
/* We can arrive here with a NULL tstate during initialization: try /* We can arrive here with a NULL tstate during initialization: try
running "python -Wi" for an example related to string interning. running "python -Wi" for an example related to string interning.
Let's just hope that no exception occurs then... This must be Let's just hope that no exception occurs then... This must be
_PyThreadState_Current and not PyThreadState_GET() because in debug PyThreadState_GET() and not PyThreadState_Get() because the latter
mode, the latter complains if tstate is NULL. */ abort Python if tstate is NULL. */
tstate = PyThreadState_GET(); tstate = PyThreadState_GET();
if (tstate != NULL && tstate->curexc_type != NULL) { if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */ /* preserve the existing exception */

View File

@ -188,8 +188,7 @@ PyEval_ReleaseLock(void)
We therefore avoid PyThreadState_GET() which dumps a fatal error We therefore avoid PyThreadState_GET() which dumps a fatal error
in debug mode. in debug mode.
*/ */
drop_gil((PyThreadState*)_Py_atomic_load_relaxed( drop_gil(PyThreadState_GET());
&_PyThreadState_Current));
} }
void void

View File

@ -4,12 +4,9 @@
#include "Python.h" #include "Python.h"
#include "internal/pystate.h" #include "internal/pystate.h"
#define GET_TSTATE() \ #define _PyThreadState_SET(value) \
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) _Py_atomic_store_relaxed(&_PyRuntime.gilstate.tstate_current, \
#define SET_TSTATE(value) \ (uintptr_t)(value))
_Py_atomic_store_relaxed(&_PyThreadState_Current, (uintptr_t)(value))
#define GET_INTERP_STATE() \
(GET_TSTATE()->interp)
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
@ -309,7 +306,7 @@ _PyInterpreterState_DeleteExceptMain()
PyInterpreterState * PyInterpreterState *
_PyInterpreterState_Get(void) _PyInterpreterState_Get(void)
{ {
PyThreadState *tstate = GET_TSTATE(); PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL) { if (tstate == NULL) {
Py_FatalError("_PyInterpreterState_Get(): no current thread state"); Py_FatalError("_PyInterpreterState_Get(): no current thread state");
} }
@ -508,7 +505,7 @@ PyObject*
PyState_FindModule(struct PyModuleDef* module) PyState_FindModule(struct PyModuleDef* module)
{ {
Py_ssize_t index = module->m_base.m_index; Py_ssize_t index = module->m_base.m_index;
PyInterpreterState *state = GET_INTERP_STATE(); PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE();
PyObject *res; PyObject *res;
if (module->m_slots) { if (module->m_slots) {
return NULL; return NULL;
@ -536,7 +533,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def)
"PyState_AddModule called on module with slots"); "PyState_AddModule called on module with slots");
return -1; return -1;
} }
state = GET_INTERP_STATE(); state = _PyInterpreterState_GET_UNSAFE();
if (!state->modules_by_index) { if (!state->modules_by_index) {
state->modules_by_index = PyList_New(0); state->modules_by_index = PyList_New(0);
if (!state->modules_by_index) if (!state->modules_by_index)
@ -554,7 +551,7 @@ int
PyState_AddModule(PyObject* module, struct PyModuleDef* def) PyState_AddModule(PyObject* module, struct PyModuleDef* def)
{ {
Py_ssize_t index; Py_ssize_t index;
PyInterpreterState *state = GET_INTERP_STATE(); PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE();
if (!def) { if (!def) {
Py_FatalError("PyState_AddModule: Module Definition is NULL"); Py_FatalError("PyState_AddModule: Module Definition is NULL");
return -1; return -1;
@ -581,7 +578,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
"PyState_RemoveModule called on module with slots"); "PyState_RemoveModule called on module with slots");
return -1; return -1;
} }
state = GET_INTERP_STATE(); state = _PyInterpreterState_GET_UNSAFE();
if (index == 0) { if (index == 0) {
Py_FatalError("PyState_RemoveModule: Module index invalid."); Py_FatalError("PyState_RemoveModule: Module index invalid.");
return -1; return -1;
@ -601,7 +598,7 @@ PyState_RemoveModule(struct PyModuleDef* def)
void void
_PyState_ClearModules(void) _PyState_ClearModules(void)
{ {
PyInterpreterState *state = GET_INTERP_STATE(); PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE();
if (state->modules_by_index) { if (state->modules_by_index) {
Py_ssize_t i; Py_ssize_t i;
for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) { for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) {
@ -691,7 +688,7 @@ tstate_delete_common(PyThreadState *tstate)
void void
PyThreadState_Delete(PyThreadState *tstate) PyThreadState_Delete(PyThreadState *tstate)
{ {
if (tstate == GET_TSTATE()) if (tstate == PyThreadState_GET())
Py_FatalError("PyThreadState_Delete: tstate is still current"); Py_FatalError("PyThreadState_Delete: tstate is still current");
if (_PyRuntime.gilstate.autoInterpreterState && if (_PyRuntime.gilstate.autoInterpreterState &&
PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate) PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey) == tstate)
@ -705,7 +702,7 @@ PyThreadState_Delete(PyThreadState *tstate)
void void
PyThreadState_DeleteCurrent() PyThreadState_DeleteCurrent()
{ {
PyThreadState *tstate = GET_TSTATE(); PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL) if (tstate == NULL)
Py_FatalError( Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate"); "PyThreadState_DeleteCurrent: no current tstate");
@ -715,7 +712,7 @@ PyThreadState_DeleteCurrent()
{ {
PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL); PyThread_tss_set(&_PyRuntime.gilstate.autoTSSkey, NULL);
} }
SET_TSTATE(NULL); _PyThreadState_SET(NULL);
PyEval_ReleaseLock(); PyEval_ReleaseLock();
} }
@ -760,14 +757,14 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
PyThreadState * PyThreadState *
_PyThreadState_UncheckedGet(void) _PyThreadState_UncheckedGet(void)
{ {
return GET_TSTATE(); return PyThreadState_GET();
} }
PyThreadState * PyThreadState *
PyThreadState_Get(void) PyThreadState_Get(void)
{ {
PyThreadState *tstate = GET_TSTATE(); PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL) if (tstate == NULL)
Py_FatalError("PyThreadState_Get: no current thread"); Py_FatalError("PyThreadState_Get: no current thread");
@ -778,9 +775,9 @@ PyThreadState_Get(void)
PyThreadState * PyThreadState *
PyThreadState_Swap(PyThreadState *newts) 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 /* 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 to be used for a thread. Check this the best we can in debug
builds. builds.
@ -809,7 +806,7 @@ PyThreadState_Swap(PyThreadState *newts)
PyObject * PyObject *
PyThreadState_GetDict(void) PyThreadState_GetDict(void)
{ {
PyThreadState *tstate = GET_TSTATE(); PyThreadState *tstate = PyThreadState_GET();
if (tstate == NULL) if (tstate == NULL)
return NULL; return NULL;
@ -834,7 +831,7 @@ PyThreadState_GetDict(void)
int int
PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
{ {
PyInterpreterState *interp = GET_INTERP_STATE(); PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
PyThreadState *p; PyThreadState *p;
/* Although the GIL is held, a few C API functions can be called /* Although the GIL is held, a few C API functions can be called
@ -960,7 +957,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
{ {
/* Must be the tstate for this thread */ /* Must be the tstate for this thread */
assert(PyGILState_GetThisThreadState()==tstate); assert(PyGILState_GetThisThreadState()==tstate);
return tstate == GET_TSTATE(); return tstate == PyThreadState_GET();
} }
/* Internal initialization/finalization functions called by /* Internal initialization/finalization functions called by
@ -1087,7 +1084,7 @@ PyGILState_Check(void)
return 1; return 1;
} }
tstate = GET_TSTATE(); tstate = PyThreadState_GET();
if (tstate == NULL) if (tstate == NULL)
return 0; return 0;