Skip to content

Commit 3876dd0

Browse files
committed
Changes from review
1 parent 9c1c0fe commit 3876dd0

File tree

8 files changed

+54
-59
lines changed

8 files changed

+54
-59
lines changed

Include/internal/pycore_genobject.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,6 @@ PyGenObject *_PyGen_GetGeneratorFromFrame(_PyInterpreterFrame *frame)
3434
return (PyGenObject *)(((char *)frame) - offset_in_gen);
3535
}
3636

37-
// Mark the generator as executing. Returns true if the state was changed,
38-
// false if it was already executing or finished.
39-
static inline bool
40-
_PyGen_SetExecuting(PyGenObject *gen)
41-
{
42-
#ifdef Py_GIL_DISABLED
43-
if (!_PyObject_IsUniquelyReferenced((PyObject *)gen)) {
44-
int8_t frame_state = _Py_atomic_load_int8_relaxed(&gen->gi_frame_state);
45-
while (frame_state < FRAME_EXECUTING) {
46-
if (_Py_atomic_compare_exchange_int8(&gen->gi_frame_state,
47-
&frame_state,
48-
FRAME_EXECUTING)) {
49-
return true;
50-
}
51-
}
52-
}
53-
#endif
54-
if (gen->gi_frame_state < FRAME_EXECUTING) {
55-
gen->gi_frame_state = FRAME_EXECUTING;
56-
return true;
57-
}
58-
return false;
59-
}
60-
6137
extern void _PyGen_Finalize(PyObject *self);
6238

6339
// Export for '_asyncio' shared extension

Objects/genobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, int exc)
234234
_PyErr_ChainStackItem();
235235
}
236236

237-
#if defined(Py_GIL_DISABLED) && defined(Py_DEBUG)
237+
#if defined(Py_GIL_DISABLED)
238238
((_PyThreadStateImpl *)tstate)->gen_last_frame_state = FRAME_EXECUTING;
239239
#endif
240240

Python/bytecodes.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ dummy_func(
13381338
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
13391339
if ((tstate->interp->eval_frame == NULL) &&
13401340
(Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) == &PyCoro_Type) &&
1341-
_PyGen_SetExecuting((PyGenObject *)receiver_o))
1341+
gen_try_set_executing((PyGenObject *)receiver_o))
13421342
{
13431343
PyGenObject *gen = (PyGenObject *)receiver_o;
13441344
_PyInterpreterFrame *gen_frame = &gen->gi_iframe;
@@ -1385,7 +1385,7 @@ dummy_func(
13851385
op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) {
13861386
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver);
13871387
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type);
1388-
DEOPT_IF(!_PyGen_SetExecuting((PyGenObject *)gen));
1388+
DEOPT_IF(!gen_try_set_executing((PyGenObject *)gen));
13891389
STAT_INC(SEND, hit);
13901390
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
13911391
_PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v));
@@ -1422,10 +1422,7 @@ dummy_func(
14221422
_PyInterpreterFrame *gen_frame = frame;
14231423
frame = tstate->current_frame = frame->previous;
14241424
gen_frame->previous = NULL;
1425-
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg);
1426-
#ifdef Py_GIL_DISABLED
1427-
((_PyThreadStateImpl *)tstate)->gen_last_frame_state = FRAME_SUSPENDED + oparg;
1428-
#endif
1425+
gen_set_frame_state(gen, tstate, FRAME_SUSPENDED + oparg);
14291426
/* We don't know which of these is relevant here, so keep them equal */
14301427
assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER);
14311428
#if TIER_ONE
@@ -3424,7 +3421,7 @@ dummy_func(
34243421
op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame)) {
34253422
PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter);
34263423
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type);
3427-
DEOPT_IF(!_PyGen_SetExecuting((PyGenObject *)gen));
3424+
DEOPT_IF(!gen_try_set_executing((PyGenObject *)gen));
34283425
STAT_INC(FOR_ITER, hit);
34293426
_PyInterpreterFrame *pushed_frame = &gen->gi_iframe;
34303427
_PyFrame_StackPush(pushed_frame, PyStackRef_None);

Python/ceval.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,10 +2304,7 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
23042304
{
23052305
assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
23062306
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
2307-
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_CLEARED);
2308-
#ifdef Py_GIL_DISABLED
2309-
((_PyThreadStateImpl *)tstate)->gen_last_frame_state = FRAME_CLEARED;
2310-
#endif
2307+
gen_set_frame_state(gen, tstate, FRAME_CLEARED);
23112308
assert(tstate->exc_info == &gen->gi_exc_state);
23122309
tstate->exc_info = gen->gi_exc_state.previous_item;
23132310
gen->gi_exc_state.previous_item = NULL;

Python/ceval_macros.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,39 @@ check_periodics(PyThreadState *tstate) {
495495
return 0;
496496
}
497497

498+
499+
500+
// Mark the generator as executing. Returns true if the state was changed,
501+
// false if it was already executing or finished.
502+
static inline bool
503+
gen_try_set_executing(PyGenObject *gen)
504+
{
505+
#ifdef Py_GIL_DISABLED
506+
if (!_PyObject_IsUniquelyReferenced((PyObject *)gen)) {
507+
int8_t frame_state = _Py_atomic_load_int8_relaxed(&gen->gi_frame_state);
508+
while (frame_state < FRAME_EXECUTING) {
509+
if (_Py_atomic_compare_exchange_int8(&gen->gi_frame_state,
510+
&frame_state,
511+
FRAME_EXECUTING)) {
512+
return true;
513+
}
514+
}
515+
}
516+
#endif
517+
// Use faster non-atomic modifications in the GIL-enabled build and when
518+
// the object is uniquely referenced in the free-threaded build.
519+
if (gen->gi_frame_state < FRAME_EXECUTING) {
520+
gen->gi_frame_state = FRAME_EXECUTING;
521+
return true;
522+
}
523+
return false;
524+
}
525+
526+
static inline void
527+
gen_set_frame_state(PyGenObject *gen, PyThreadState *tstate, int8_t frame_state)
528+
{
529+
FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, frame_state);
530+
#ifdef Py_GIL_DISABLED
531+
((_PyThreadStateImpl *)tstate)->gen_last_frame_state = frame_state;
532+
#endif
533+
}

Python/executor_cases.c.h

Lines changed: 5 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 5 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/analyzer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,8 @@ def has_error_without_pop(op: parser.CodeDef) -> bool:
643643
"_PyFrame_StackPush",
644644
"_PyFunction_SetVersion",
645645
"_PyGen_GetGeneratorFromFrame",
646-
"_PyGen_SetExecuting",
646+
"gen_try_set_executing",
647+
"gen_set_frame_state",
647648
"_PyInterpreterState_GET",
648649
"_PyList_AppendTakeRef",
649650
"_PyList_ITEMS",

0 commit comments

Comments
 (0)