Skip to content

Commit a9cde7f

Browse files
Make PyThreadState._status more granular.
1 parent 963e239 commit a9cde7f

File tree

3 files changed

+26
-19
lines changed

3 files changed

+26
-19
lines changed

Include/cpython/pystate.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,22 @@ struct _ts {
119119
PyThreadState *next;
120120
PyInterpreterState *interp;
121121

122-
int _status;
122+
struct {
123+
/* Has been initialized to a safe state.
124+
125+
In order to be effective, this must be set to 0 during or right
126+
after allocation. */
127+
unsigned int initialized:1;
128+
/* Has been bound to an OS thread. */
129+
unsigned int bound:1;
130+
/* Has been unbound from its OS thread. */
131+
unsigned int unbound:1;
132+
// XXX finalizing
133+
// XXX cleared
134+
// XXX finalized
135+
/* padding to align to 4 bytes */
136+
unsigned int :29;
137+
} _status;
123138

124139
int py_recursion_remaining;
125140
int py_recursion_limit;

Include/internal/pycore_pystate.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -137,18 +137,6 @@ _PyThreadState_UpdateTracingState(PyThreadState *tstate)
137137
}
138138

139139

140-
/* PyThreadState status */
141-
142-
#define PyThreadState_UNINITIALIZED 0
143-
/* Has been initialized to a safe state.
144-
145-
In order to be effective, this must be set to 0 during or right
146-
after allocation. */
147-
#define PyThreadState_INITIALIZED 1
148-
#define PyThreadState_BOUND 2
149-
#define PyThreadState_UNBOUND 3
150-
151-
152140
/* Other */
153141

154142
PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(

Python/pystate.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ static void
181181
bind_tstate(PyThreadState *tstate)
182182
{
183183
assert(tstate != NULL);
184-
assert(tstate->_status == PyThreadState_INITIALIZED);
184+
assert(tstate->_status.initialized && !tstate->_status.bound);
185+
// XXX tstate_alive()
185186
assert(tstate->thread_id == 0);
186187
assert(tstate->native_thread_id == 0);
187188
_PyRuntimeState *runtime = tstate->interp->runtime;
@@ -214,14 +215,15 @@ bind_tstate(PyThreadState *tstate)
214215
tstate->native_thread_id = PyThread_get_thread_native_id();
215216
#endif
216217

217-
tstate->_status = PyThreadState_BOUND;
218+
tstate->_status.bound = 1;
218219
}
219220

220221
static void
221222
unbind_tstate(PyThreadState *tstate)
222223
{
223224
assert(tstate != NULL);
224-
assert(tstate->_status == PyThreadState_BOUND);
225+
assert(tstate->_status.bound && !tstate->_status.unbound);
226+
// XXX tstate_alive()
225227
assert(tstate->thread_id > 0);
226228
#ifdef PY_HAVE_THREAD_NATIVE_ID
227229
assert(tstate->native_thread_id > 0);
@@ -239,7 +241,9 @@ unbind_tstate(PyThreadState *tstate)
239241
// Check the `_status` field to know if these values
240242
// are still valid.
241243

242-
tstate->_status = PyThreadState_UNBOUND;
244+
// We leave tstate->_status.bound set to 1
245+
// to indicate it was previously bound.
246+
tstate->_status.unbound = 1;
243247
}
244248

245249

@@ -1124,7 +1128,7 @@ init_threadstate(PyThreadState *tstate,
11241128
PyInterpreterState *interp, uint64_t id,
11251129
PyThreadState *next)
11261130
{
1127-
if (tstate->_status != PyThreadState_UNINITIALIZED) {
1131+
if (tstate->_status.initialized) {
11281132
Py_FatalError("thread state already initialized");
11291133
}
11301134

@@ -1160,7 +1164,7 @@ init_threadstate(PyThreadState *tstate,
11601164
tstate->datastack_top = NULL;
11611165
tstate->datastack_limit = NULL;
11621166

1163-
tstate->_status = PyThreadState_INITIALIZED;
1167+
tstate->_status.initialized = 1;
11641168
}
11651169

11661170
static PyThreadState *

0 commit comments

Comments
 (0)