8000 Factor out "current_fast" helpers. · python/cpython@a5eb3d8 · GitHub
[go: up one dir, main page]

Skip to content

Commit a5eb3d8

Browse files
Factor out "current_fast" helpers.
1 parent 5903b39 commit a5eb3d8

File tree

1 file changed

+41
-21
lines changed

1 file changed

+41
-21
lines changed

Python/pystate.c

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,30 @@ static void _PyThreadState_Delete(PyThreadState *tstate, int check_current);
4444

4545
/* the current thread state */
4646

47-
#define _PyRuntimeGILState_GetThreadState(gilstate) \
48-
((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current))
49-
#define _PyRuntimeGILState_SetThreadState(gilstate, value) \
50-
_Py_atomic_store_relaxed(&(gilstate)->tstate_current, \
51-
(uintptr_t)(value))
47+
static inline PyThreadState *
48+
current_fast_get(_PyRuntimeState *runtime)
49+
{
50+
// The GIL must be held by the current thread.
51+
return (PyThreadState*)_Py_atomic_load_relaxed(
52+
&runtime->gilstate.tstate_current);
53+
}
54+
55+
static inline void
56+
current_fast_set(_PyRuntimeState *runtime, PyThreadState *tstate)
57+
{
58+
// The GIL must be held by the current thread.
59+
assert(tstate != NULL);
60+
_Py_atomic_store_relaxed(&runtime->gilstate.tstate_current,
61+
(uintptr_t)tstate);
62+
}
63+
64+
static inline void
65+
current_fast_clear(_PyRuntimeState *runtime)
66+
{
67+
// The GIL must be held by the current thread.
68+
_Py_atomic_store_relaxed(&runtime->gilstate.tstate_current,
69+
(uintptr_t)NULL);
70+
}
5271

5372

5473
static int
@@ -1145,8 +1164,7 @@ PyThreadState_Clear(PyThreadState *tstate)
11451164

11461165
/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
11471166
static void
1148-
tstate_delete_common(PyThreadState *tstate,
1149-
struct _gilstate_runtime_state *gilstate)
1167+
tstate_delete_common(PyThreadState *tstate)
11501168
{
11511169
_Py_EnsureTstateNotNULL(tstate);
11521170
PyInterpreterState *interp = tstate->interp;
@@ -1187,13 +1205,12 @@ tstate_delete_common(PyThreadState *tstate,
11871205
static void
11881206
_PyThreadState_Delete(PyThreadState *tstate, int check_current)
11891207
{
1190-
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
11911208
if (check_current) {
1192-
if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
1209+
if (tstate == current_fast_get(tstate->interp->runtime)) {
11931210
_Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate);
11941211
}
11951212
}
1196-
tstate_delete_common(tstate, gilstate);
1213+
tstate_delete_common(tstate);
11971214
free_threadstate(tstate);
11981215
}
11991216

@@ -1209,18 +1226,16 @@ void
12091226
_PyThreadState_DeleteCurrent(PyThreadState *tstate)
12101227
{
12111228
_Py_EnsureTstateNotNULL(tstate);
1212-
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
1213-
tstate_delete_common(tstate, gilstate);
1214-
_PyRuntimeGILState_SetThreadState(gilstate, NULL);
1229+
tstate_delete_common(tstate);
1230+
current_fast_clear(tstate->interp->runtime);
12151231
_PyEval_ReleaseLock(tstate);
12161232
free_threadstate(tstate);
12171233
}
12181234

12191235
void
12201236
PyThreadState_DeleteCurrent(void)
12211237
{
1222-
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
1223-
PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate);
1238+
PyThreadState *tstate = current_fast_get(&_PyRuntime);
12241239
_PyThreadState_DeleteCurrent(tstate);
12251240
}
12261241

@@ -1286,9 +1301,14 @@ PyThreadState_Get(void)
12861301
PyThreadState *
12871302
_PyThreadState_Swap(_PyRuntimeState *runtime, PyThreadState *newts)
12881303
{
1289-
PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(&runtime->gilstate);
1304+
PyThreadState *oldts = current_fast_get(runtime);
12901305

1291-
_PyRuntimeGILState_SetThreadState(&runtime->gilstate, newts);
1306+
if (newts == NULL) {
1307+
current_fast_clear(runtime);
1308+
}
1309+
else {
1310+
current_fast_set(runtime, newts);
1311+
}
12921312
/* It should not be possible for more than one thread state
12931313
to be used for a thread. Check this the best we can in debug
12941314
builds.
@@ -1590,7 +1610,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
15901610
_PyRuntimeState *runtime = tstate->interp->runtime;
15911611
/* Must be the tstate for this thread */
15921612
assert(tstate == current_tss_get(runtime));
1593-
return tstate == _PyRuntimeGILState_GetThreadState(&runtime->gilstate);
1613+
return tstate == current_fast_get(runtime);
15941614
}
15951615

15961616
/* Internal initialization/finalization functions called by
@@ -1738,7 +1758,7 @@ PyGILState_Check(void)
17381758
return 1;
17391759
}
17401760

1741-
PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(&runtime->gilstate);
1761+
PyThreadState *tstate = current_fast_get(runtime);
17421762
if (tstate == NULL) {
17431763
return 0;
17441764
}
@@ -1830,7 +1850,7 @@ PyGILState_Release(PyGILState_STATE oldstate)
18301850
* races; see bugs 225673 and 1061968 (that nasty bug has a
18311851
* habit of coming back).
18321852
*/
1833-
assert(_PyRuntimeGILState_GetThreadState(&runtime->gilstate) == tstate);
1853+
assert(current_fast_get(runtime) == tstate);
18341854
_PyThreadState_DeleteCurrent(tstate);
18351855
}
18361856
/* Release the lock if necessary */
@@ -2017,7 +2037,7 @@ _call_in_interpreter(PyInterpreterState *interp, releasefunc func, void *arg)
20172037
*/
20182038
_PyRuntimeState *runtime = interp->runtime;
20192039
PyThreadState *save_tstate = NULL;
2020-
if (interp != _PyRuntimeGILState_GetThreadState(&runtime->gilstate)->interp) {
2040+
if (interp != current_fast_get(runtime)->interp) {
20212041
// XXX Using the "head" thread isn't strictly correct.
20222042
PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
20232043
// XXX Possible GILState issues?

0 commit comments

Comments
 (0)
0