mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-112175: Add eval_breaker
to PyThreadState
(#115194)
This change adds an `eval_breaker` field to `PyThreadState`. The primary motivation is for performance in free-threaded builds: with thread-local eval breakers, we can stop a specific thread (e.g., for an async exception) without interrupting other threads. The source of truth for the global instrumentation version is stored in the `instrumentation_version` field in PyInterpreterState. Threads usually read the version from their local `eval_breaker`, where it continues to be colocated with the eval breaker bits.
This commit is contained in:
parent
e71468ba4f
commit
0749244d13
19 changed files with 265 additions and 172 deletions
6
Python/generated_cases.c.h
generated
6
Python/generated_cases.c.h
generated
|
@ -3139,7 +3139,7 @@
|
|||
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
|
||||
next_instr += 1;
|
||||
INSTRUCTION_STATS(INSTRUMENTED_RESUME);
|
||||
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
||||
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
||||
uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version;
|
||||
if (code_version != global_version) {
|
||||
if (_Py_Instrument(_PyFrame_GetCode(frame), tstate->interp)) {
|
||||
|
@ -4809,7 +4809,7 @@
|
|||
TIER_ONE_ONLY
|
||||
assert(frame == tstate->current_frame);
|
||||
uintptr_t global_version =
|
||||
_Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker) &
|
||||
_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) &
|
||||
~_PY_EVAL_EVENTS_MASK;
|
||||
uintptr_t code_version = _PyFrame_GetCode(frame)->_co_instrumentation_version;
|
||||
assert((code_version & 255) == 0);
|
||||
|
@ -4836,7 +4836,7 @@
|
|||
DEOPT_IF(_Py_emscripten_signal_clock == 0, RESUME);
|
||||
_Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING;
|
||||
#endif
|
||||
uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->interp->ceval.eval_breaker);
|
||||
uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker);
|
||||
uintptr_t version = _PyFrame_GetCode(frame)->_co_instrumentation_version;
|
||||
assert((version & _PY_EVAL_EVENTS_MASK) == 0);
|
||||
DEOPT_IF(eval_breaker != version, RESUME);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue