Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit b45dc76

Browse files
author
Anselm Kruis
committed
Stackless issue #254: replace PyThreadState_GET b _PyThreadState_GET
bpo-35081 added _PyThreadState_GET() internal macro and changed the C-Python code to use it. This commit updates Stackless code to use _PyThreadState_GET().
1 parent 9752fb7 commit b45dc76

17 files changed

+124
-127
lines changed

Include/frameobject.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef PyObject *(PyFrame_ExecFunc) (struct _frame *, int, PyObject *);
1717
*
1818
* PyObject * example(PyFrameObject *f, int exc, PyObject *retval)
1919
* {
20-
* PyThreadState *ts = PyThreadState_GET();
20+
* PyThreadState *ts = _PyThreadState_GET();
2121
*
2222
* do something ....
2323
* if you change retval, use Py_SETREF(retval, new_value) or

Include/internal/pycore_stackless.h

+7-10
Original file line numberDiff line numberDiff line change
@@ -244,17 +244,14 @@ PyObject * slp_wrap_call_frame(PyFrameObject *frame, int exc, PyObject *retval);
244244

245245
#endif /* #if (SLP_WITH_FRAME_REF_DEBUG == 2) */
246246

247-
/* Access the thread state without a check for NULL */
248-
#define _SLP_PyThreadState_Current ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
249-
250247
/* Used in _Py_Dealloc() to eventually restore tstate->frame */
251248
#define SLP_WITH_VALID_CURRENT_FRAME(expr) \
252249
do { \
253-
if (_SLP_PyThreadState_Current != NULL && \
254-
(assert(_SLP_FRAME_STATE_IS_CONSISTENT(_SLP_PyThreadState_Current)), \
255-
_SLP_FRAME_IN_TRANSFER(_SLP_PyThreadState_Current))) \
250+
if (_PyThreadState_GET() != NULL && \
251+
(assert(_SLP_FRAME_STATE_IS_CONSISTENT(_PyThreadState_GET())), \
252+
_SLP_FRAME_IN_TRANSFER(_PyThreadState_GET()))) \
256253
{ \
257-
PyThreadState * ts = _SLP_PyThreadState_Current; \
254+
PyThreadState * ts = _PyThreadState_GET(); \
258255
PyFrameObject * frame = SLP_CLAIM_NEXT_FRAME(ts); \
259256
(void)(expr); \
260257
assert(frame == NULL || Py_REFCNT(frame) >= 1); \
@@ -264,8 +261,8 @@ PyObject * slp_wrap_call_frame(PyFrameObject *frame, int exc, PyObject *retval);
264261
Py_XDECREF(frame); \
265262
} else { \
266263
(void)(expr); \
267-
assert(_SLP_PyThreadState_Current == NULL || _SLP_FRAME_STATE_IS_CONSISTENT(_SLP_PyThreadState_Current)); \
268-
assert(_SLP_PyThreadState_Current == NULL || !_SLP_FRAME_IN_TRANSFER(_SLP_PyThreadState_Current)); \
264+
assert(_PyThreadState_GET() == NULL || _SLP_FRAME_STATE_IS_CONSISTENT(_PyThreadState_GET())); \
265+
assert(_PyThreadState_GET() == NULL || !_SLP_FRAME_IN_TRANSFER(_PyThreadState_GET())); \
269266
} \
270267
} while (0)
271268

@@ -446,7 +443,7 @@ PyTaskletObject * slp_get_watchdog(PyThreadState *ts, int interrupt);
446443
#undef STACKLESS__GETARG_ASSERT
447444
#endif
448445
#define STACKLESS__GETARG_ASSERT \
449-
assert(SLP_CURRENT_FRAME_IS_VALID(PyThreadState_GET()))
446+
assert(SLP_CURRENT_FRAME_IS_VALID(_PyThreadState_GET()))
450447

451448
/* descr must be of type PyWrapperDescrObject, but this type is undocumented.
452449
* Therefore this macro is in pycore_stackless.h and not in stackless_api.h

Objects/abstract.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2591,7 +2591,7 @@ PyIter_Next(PyObject *iter)
25912591
STACKLESS_PROMOTE_METHOD(iter, tp_iternext);
25922592
result = (*iter->ob_type->tp_iternext)(iter);
25932593
STACKLESS_ASSERT();
2594-
STACKLESS_ASSERT_UNWINDING_VALUE_IS_NOT(PyThreadState_GET(), result, NULL);
2594+
STACKLESS_ASSERT_UNWINDING_VALUE_IS_NOT(_PyThreadState_GET(), result, NULL);
25952595
if (result == NULL &&
25962596
PyErr_Occurred() &&
25972597
PyErr_ExceptionMatches(PyExc_StopIteration))

Objects/call.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ _Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where)
3737

3838
assert((callable != NULL) ^ (where != NULL));
3939

40-
if (STACKLESS_RETVAL(PyThreadState_GET(), result) == NULL) {
40+
if (STACKLESS_RETVAL(_PyThreadState_GET(), result) == NULL) {
4141
if (!err_occurred) {
4242
if (callable)
4343
PyErr_Format(PyExc_SystemError,
@@ -56,7 +56,7 @@ _Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where)
5656
}
5757
else {
5858
if (err_occurred) {
59-
Py_DECREF(STACKLESS_RETVAL(PyThreadState_GET(), result));
59+
Py_DECREF(STACKLESS_RETVAL(_PyThreadState_GET(), result));
6060

6161
if (callable) {
6262
_PyErr_FormatFromCause(PyExc_SystemError,

Objects/genobject.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, int exc, int closing, PyObject * o
342342
static PyObject*
343343
gen_iternext_callback(PyFrameObject *f, int exc, PyObject *result)
344344
{
345-
PyThreadState *ts = PyThreadState_GET();
345+
PyThreadState *ts = _PyThreadState_GET();
346346
PyCFrameObject *cf = (PyCFrameObject *) f;
347347
PyGenObject *gen = (PyGenObject *) cf->ob1;
348348
PyObject *arg = cf->ob2;

Objects/typeobject.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -5899,7 +5899,7 @@ wrap_next(PyObject *self, PyObject *args, void *wrapped)
58995899
STACKLESS_PROMOTE_ALL();
59005900
res = (*func)(self);
59015901
STACKLESS_ASSERT();
5902-
STACKLESS_ASSERT_UNWINDING_VALUE_IS_NOT(PyThreadState_GET(), res, NULL);
5902+
STACKLESS_ASSERT_UNWINDING_VALUE_IS_NOT(_PyThreadState_GET(), res, NULL);
59035903
if (res == NULL && !PyErr_Occurred())
59045904
PyErr_SetNone(PyExc_StopIteration);
59055905
return res;
@@ -6762,7 +6762,7 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value)
67626762
PyObject *
67636763
slp_tp_init_callback(PyFrameObject *f, int exc, PyObject *retval)
67646764
{
6765-
PyThreadState *ts = PyThreadState_GET();
6765+
PyThreadState *ts = _PyThreadState_GET();
67666766
PyCFrameObject *cf = (PyCFrameObject *) f;
67676767

67686768
f = cf->f_back;
@@ -6805,7 +6805,7 @@ slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
68056805
return -1;
68066806
Py_INCREF(self);
68076807
f->ob1 = self;
6808-
SLP_SET_CURRENT_FRAME(PyThreadState_GET(), (PyFrameObject *) f);
6808+
SLP_SET_CURRENT_FRAME(_PyThreadState_GET(), (PyFrameObject *) f);
68096809
/* f contains the only counted reference to current frame. This reference
68106810
* keeps the fame alive during the following PyObject_Call().
68116811
*/
@@ -6823,7 +6823,7 @@ slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
68236823
#ifdef STACKLESS
68246824
if (stackless && !STACKLESS_UNWINDING(res)) {
68256825
/* required, because we added a C-frame */
6826-
PyThreadState *ts = PyThreadState_GET();
6826+
PyThreadState *ts = _PyThreadState_GET();
68276827
STACKLESS_PACK(ts, res);
68286828
assert(f);
68296829
assert((PyFrameObject *)f == SLP_CURRENT_FRAME(ts));

Python/ceval.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -3892,7 +3892,7 @@ slp_eval_frame_yield_from(PyFrameObject *f, int throwflag, PyObject *retval)
38923892
static PyObject *
38933893
run_frame_dispatch(PyFrameObject *f, int exc, PyObject *retval)
38943894
{
3895-
PyThreadState *ts = PyThreadState_GET();
3895+
PyThreadState *ts = _PyThreadState_GET();
38963896
PyCFrameObject *cf = (PyCFrameObject*) f;
38973897
PyFrameObject *f_back;
38983898
int done = cf->i;
@@ -3938,7 +3938,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
39383938
* This method is not used by Stackless Python. It is provided for compatibility
39393939
* with extension modules and Cython.
39403940
*/
3941-
PyThreadState *tstate = PyThreadState_GET();
3941+
PyThreadState *tstate = _PyThreadState_GET();
39423942
PyObject * retval = NULL;
39433943
PyFrameObject * f_back;
39443944

@@ -4056,7 +4056,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
40564056
PyObject * _Py_HOT_FUNCTION
40574057
PyEval_EvalFrameEx_slp(PyFrameObject *f, int throwflag, PyObject *retval)
40584058
{
4059-
PyThreadState *tstate = PyThreadState_GET();
4059+
PyThreadState *tstate = _PyThreadState_GET();
40604060

40614061
/* Check, if an extension module has changed tstate->interp->eval_frame.
40624062
* PEP 523 defines this function pointer as an API to customise the frame
@@ -5111,7 +5111,7 @@ PyEval_GetGlobals(void)
51115111
PyFrameObject *current_frame = PyEval_GetFrame();
51125112
#if 1 && defined STACKLESS
51135113
if (current_frame == NULL) {
5114-
PyThreadState *ts = PyThreadState_GET();
5114+
PyThreadState *ts = _PyThreadState_GET();
51155115

51165116
if (ts->st.current != NULL)
51175117
return ts->st.current->def_globals;

Python/context.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ PyObject* slp_context_run_callback(PyFrameObject *f, int exc, PyObject *result)
627627

628628
if (cf->i) {
629629
/* called by tasklet.context_run(...) */
630-
PyThreadState *ts = PyThreadState_GET();
630+
PyThreadState *ts = _PyThreadState_GET();
631631
assert(ts);
632632
assert(NULL == context || PyContext_CheckExact(context));
633633
Py_XSETREF(ts->context, context);
@@ -640,7 +640,7 @@ PyObject* slp_context_run_callback(PyFrameObject *f, int exc, PyObject *result)
640640
Py_DECREF(context);
641641
}
642642

643-
SLP_STORE_NEXT_FRAME(PyThreadState_GET(), cf->f_back);
643+
SLP_STORE_NEXT_FRAME(_PyThreadState_GET(), cf->f_back);
644644
return result;
645645
}
646646

@@ -666,7 +666,7 @@ context_run(PyContext *self, PyObject *const *args,
666666
}
667667

668668
#ifdef STACKLESS
669-
PyThreadState *ts = PyThreadState_GET();
669+
PyThreadState *ts = _PyThreadState_GET();
670670
PyCFrameObject *f = NULL;
671671
if (stackless) {
672672
f = slp_cframe_new(slp_context_run_callback, 1);

Stackless/core/cframeobject.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ cframe_clear(PyCFrameObject *cf)
9191
PyCFrameObject *
9292
slp_cframe_new(PyFrame_ExecFunc *exec, unsigned int linked)
9393
{
94-
PyThreadState *ts = PyThreadState_GET();
94+
PyThreadState *ts = _PyThreadState_GET();
9595
PyCFrameObject *cf;
9696
PyFrameObject *back;
9797

@@ -247,7 +247,7 @@ static PyMethodDef cframe_methods[] = {
247247

248248
static PyObject * run_cframe(PyFrameObject *f, int exc, PyObject *retval)
249249
{
250-
PyThreadState *ts = PyThreadState_GET();
250+
PyThreadState *ts = _PyThreadState_GET();
251251
PyCFrameObject *cf = (PyCFrameObject*) f;
252252
PyTaskletObject *task = ts->st.current;
253253
int done = cf->i;
@@ -452,7 +452,7 @@ execute_soft_switchable_func(PyFrameObject *f, int exc, PyObject *retval)
452452
* Special rule for frame execution functions: we now own a reference to retval!
453453
*/
454454
PyCFrameObject *cf = (PyCFrameObject *)f;
455-
PyThreadState *ts = PyThreadState_GET();
455+
PyThreadState *ts = _PyThreadState_GET();
456456
PyObject *ob1, *ob2, *ob3;
457457
PyStacklessFunctionDeclarationObject *ssfd =
458458
(PyStacklessFunctionDeclarationObject*)cf->any2;
@@ -504,7 +504,7 @@ PyStackless_CallFunction(PyStacklessFunctionDeclarationObject *ssfd, PyObject *a
504504
PyObject *ob1, PyObject *ob2, PyObject *ob3, long n, void *any)
505505
{
506506
STACKLESS_GETARG();
507-
PyThreadState *ts = PyThreadState_GET();
507+
PyThreadState *ts = _PyThreadState_GET();
508508
PyObject *et=NULL, *ev=NULL, *tb=NULL;
509509

510510
assert(ssfd);

Stackless/core/slp_transfer.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ climb_stack_and_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
101101
* need to switch from a higher stacklevel, and the
102102
* needed stack size becomes *negative* :-))
103103
*/
104-
PyThreadState *ts = PyThreadState_GET();
104+
PyThreadState *ts = _PyThreadState_GET();
105105
intptr_t probe;
106106
register ptrdiff_t needed = &probe - ts->st.cstack_base;
107107
/* in rare cases, the need might have vanished due to the recursion */
@@ -124,7 +124,7 @@ int
124124
slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst,
125125
PyTaskletObject *prev)
126126
{
127-
PyThreadState *ts = PyThreadState_GET();
127+
PyThreadState *ts = _PyThreadState_GET();
128128
int result;
129129
/* Use a volatile pointer to prevent inlining of slp_switch().
130130
* See Stackless issue 183

Stackless/core/stackless_util.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ slp_get_frame(PyTaskletObject *task)
5858

5959
void slp_check_pending_irq()
6060
{
61-
PyThreadState *ts = PyThreadState_GET();
61+
PyThreadState *ts = _PyThreadState_GET();
6262
PyTaskletObject *current = ts->st.current;
6363

6464
/* act only if hard irq is in effect */
@@ -80,7 +80,7 @@ slp_return_wrapper(PyObject *retval)
8080
if (retval == NULL)
8181
return -1;
8282
if (STACKLESS_UNWINDING(retval)) {
83-
STACKLESS_UNPACK(PyThreadState_GET(), retval);
83+
STACKLESS_UNPACK(_PyThreadState_GET(), retval);
8484
Py_XDECREF(retval);
8585
return 1;
8686
}
@@ -115,7 +115,7 @@ slp_int_wrapper(PyObject *retval)
115115
int
116116
slp_current_wrapper( int(*func)(PyTaskletObject*), PyTaskletObject *task )
117117
{
118-
PyThreadState *ts = PyThreadState_GET();
118+
PyThreadState *ts = _PyThreadState_GET();
119119

120120
int ret;
121121
ts->st.main = (PyTaskletObject*)Py_None;

Stackless/core/stacklesseval.c

+13-13
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static void slp_cstack_cacheclear(void)
4141
static void
4242
cstack_dealloc(PyCStackObject *cst)
4343
{
44-
PyThreadState * ts = PyThreadState_GET();
44+
PyThreadState * ts = _PyThreadState_GET();
4545
ts->interp->st.cstack_chain = cst;
4646
SLP_CHAIN_REMOVE(PyCStackObject, &ts->interp->st.cstack_chain, cst, next,
4747
prev);
@@ -77,13 +77,13 @@ slp_cstack_new(PyCStackObject **cst, intptr_t *stackref, PyTaskletObject *task)
7777
ts = task->cstate->tstate;
7878
}
7979
if (ts == NULL) {
80-
ts = PyThreadState_GET();
80+
ts = _PyThreadState_GET();
8181
}
8282

8383
stackbase = ts->st.cstack_base;
8484
size = stackbase - stackref;
8585

86-
assert(size == 0 || ts == PyThreadState_GET());
86+
assert(size == 0 || ts == _PyThreadState_GET());
8787
assert(size >= 0);
8888

8989
if (*cst != NULL) {
@@ -223,7 +223,7 @@ PyTypeObject PyCStack_Type = {
223223
static int
224224
make_initial_stub(void)
225225
{
226-
PyThreadState *ts = PyThreadState_GET();
226+
PyThreadState *ts = _PyThreadState_GET();
227227
int result;
228228

229229
Py_CLEAR(ts->st.initial_stub);
@@ -253,7 +253,7 @@ climb_stack_and_eval_frame(PyFrameObject *f)
253253
* This way, initial_stub is always valid to be
254254
* used to return to the main c stack.
255255
*/
256-
PyThreadState *ts = PyThreadState_GET();
256+
PyThreadState *ts = _PyThreadState_GET();
257257
intptr_t probe;
258258
ptrdiff_t needed = &probe - ts->st.cstack_base;
259259
/* in rare cases, the need might have vanished due to the recursion */
@@ -279,7 +279,7 @@ slp_run_tasklet(void)
279279
* slp_transfer_return(). Therefore, this function must not hold
280280
* any reference during the execution of these sub-functions.
281281
*/
282-
PyThreadState *ts = PyThreadState_GET();
282+
PyThreadState *ts = _PyThreadState_GET();
283283
PyObject *retval;
284284

285285
SLP_ASSERT_FRAME_IN_TRANSFER(ts);
@@ -314,7 +314,7 @@ slp_run_tasklet(void)
314314
PyObject * _Py_HOT_FUNCTION
315315
slp_eval_frame(PyFrameObject *f)
316316
{
317-
PyThreadState *ts = PyThreadState_GET();
317+
PyThreadState *ts = _PyThreadState_GET();
318318
PyFrameObject *fprev = f->f_back;
319319
intptr_t * stackref;
320320
PyObject *retval;
@@ -405,7 +405,7 @@ get_current_main_and_watchdogs(PyThreadState *ts, PyObject *list)
405405
{
406406
PyTaskletObject *t;
407407

408-
assert(ts != PyThreadState_GET()); /* don't kill ourself */
408+
assert(ts != _PyThreadState_GET()); /* don't kill ourself */
409409
assert(PyList_CheckExact(list));
410410

411411
/* kill watchdogs */
@@ -501,7 +501,7 @@ run_other_threads(PyObject **sleep, Py_ssize_t count)
501501
*/
502502
void slp_kill_tasks_with_stacks(PyThreadState *target_ts)
503503
{
504-
PyThreadState *cts = PyThreadState_GET();
504+
PyThreadState *cts = _PyThreadState_GET();
505505
PyInterpreterState * interp = cts->interp;
506506
int in_loop = 0;
507507

@@ -845,7 +845,7 @@ void PyStackless_kill_tasks_with_stacks(int allthreads)
845845
static PyObject *
846846
eval_frame_callback(PyFrameObject *f, int exc, PyObject *retval)
847847
{
848-
PyThreadState *ts = PyThreadState_GET();
848+
PyThreadState *ts = _PyThreadState_GET();
849849
PyTaskletObject *cur = ts->st.current;
850850
PyCStackObject *cst;
851851
PyCFrameObject *cf = (PyCFrameObject *) f;
@@ -917,7 +917,7 @@ eval_frame_callback(PyFrameObject *f, int exc, PyObject *retval)
917917
PyObject *
918918
slp_eval_frame_newstack(PyFrameObject *f, int exc, PyObject *retval)
919919
{
920-
PyThreadState *ts = PyThreadState_GET();
920+
PyThreadState *ts = _PyThreadState_GET();
921921
PyTaskletObject *cur = ts->st.current;
922922
PyCFrameObject *cf = NULL;
923923
PyCStackObject *cst;
@@ -1026,7 +1026,7 @@ PyUnwindObject *Py_UnwindToken = &unwind_token;
10261026
PyObject * _Py_HOT_FUNCTION
10271027
slp_frame_dispatch(PyFrameObject *f, PyFrameObject *stopframe, int exc, PyObject *retval)
10281028
{
1029-
PyThreadState *ts = PyThreadState_GET();
1029+
PyThreadState *ts = _PyThreadState_GET();
10301030
PyFrameObject *first_frame = f;
10311031
++ts->st.nesting_level;
10321032

@@ -1070,7 +1070,7 @@ slp_frame_dispatch(PyFrameObject *f, PyFrameObject *stopframe, int exc, PyObject
10701070
static PyObject *
10711071
slp_frame_dispatch_top(PyObject *retval)
10721072
{
1073-
PyThreadState *ts = PyThreadState_GET();
1073+
PyThreadState *ts = _PyThreadState_GET();
10741074
PyFrameObject *f = SLP_CLAIM_NEXT_FRAME(ts);
10751075

10761076
if (f==NULL) return retval;

0 commit comments

Comments
 (0)