Skip to content

Commit 01b1cc1

Browse files
authored
bpo-36710: Add PyInterpreterState.runtime field (GH-17270)
Add PyInterpreterState.runtime field: reference to the _PyRuntime global variable. This field exists to not have to pass runtime in addition to tstate to a function. Get runtime from tstate: tstate->interp->runtime. Remove "_PyRuntimeState *runtime" parameter from functions already taking a "PyThreadState *tstate" parameter. _PyGC_Init() first parameter becomes "PyThreadState *tstate".
1 parent eb1cbbf commit 01b1cc1

File tree

8 files changed

+81
-94
lines changed

8 files changed

+81
-94
lines changed

Include/internal/pycore_pylifecycle.h

+3-8
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,12 @@ extern PyStatus _PyFaulthandler_Init(int enable);
3838
extern int _PyTraceMalloc_Init(int enable);
3939
extern PyObject * _PyBuiltin_Init(PyThreadState *tstate);
4040
extern PyStatus _PySys_Create(
41-
struct pyruntimestate *runtime,
4241
PyThreadState *tstate,
4342
PyObject **sysmod_p);
4443
extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
4544
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
4645
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
47-
extern int _PySys_InitMain(
48-
struct pyruntimestate *runtime,
49-
PyThreadState *tstate);
46+
extern int _PySys_InitMain(PyThreadState *tstate);
5047
extern PyStatus _PyImport_Init(PyThreadState *tstate);
5148
extern PyStatus _PyExc_Init(void);
5249
extern PyStatus _PyErr_Init(void);
@@ -57,7 +54,7 @@ extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
5754

5855
extern PyStatus _PyTypes_Init(void);
5956
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
60-
extern PyStatus _PyGC_Init(struct pyruntimestate *runtime);
57+
extern PyStatus _PyGC_Init(PyThreadState *tstate);
6158

6259

6360
/* Various internal finalizers */
@@ -89,9 +86,7 @@ extern void _PyHash_Fini(void);
8986
extern void _PyTraceMalloc_Fini(void);
9087
extern void _PyWarnings_Fini(PyInterpreterState *interp);
9188

92-
extern void _PyGILState_Init(
93-
struct pyruntimestate *runtime,
94-
PyThreadState *tstate);
89+
extern void _PyGILState_Init(PyThreadState *tstate);
9590
extern void _PyGILState_Fini(struct pyruntimestate *runtime);
9691

9792
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime);

Include/internal/pycore_pystate.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ struct _is {
6262
struct _is *next;
6363
struct _ts *tstate_head;
6464

65+
/* Reference to the _PyRuntime global variable. This field exists
66+
to not have to pass runtime in addition to tstate to a function.
67+
Get runtime from tstate: tstate->interp->runtime. */
68+
struct pyruntimestate *runtime;
69+
6570
int64_t id;
6671
int64_t id_refcount;
6772
int requires_idref;
@@ -301,7 +306,6 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);
301306
/* Other */
302307

303308
PyAPI_FUNC(void) _PyThreadState_Init(
304-
_PyRuntimeState *runtime,
305309
PyThreadState *tstate);
306310
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
307311
_PyRuntimeState *runtime,

Modules/_threadmodule.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ t_bootstrap(void *boot_raw)
10071007
runtime = boot->runtime;
10081008
tstate = boot->tstate;
10091009
tstate->thread_id = PyThread_get_thread_ident();
1010-
_PyThreadState_Init(runtime, tstate);
1010+
_PyThreadState_Init(tstate);
10111011
PyEval_AcquireThread(tstate);
10121012
tstate->interp->num_threads++;
10131013
res = PyObject_Call(boot->func, boot->args, boot->keyw);

Modules/gcmodule.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ _PyGC_InitializeRuntime(struct _gc_runtime_state *state)
155155

156156

157157
PyStatus
158-
_PyGC_Init(_PyRuntimeState *runtime)
158+
_PyGC_Init(PyThreadState *tstate)
159159
{
160-
struct _gc_runtime_state *state = &runtime->gc;
160+
struct _gc_runtime_state *state = &tstate->interp->runtime->gc;
161161
if (state->garbage == NULL) {
162162
state->garbage = PyList_New(0);
163163
if (state->garbage == NULL) {

Python/ceval.c

+16-12
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ static size_t opcache_global_misses = 0;
191191
int
192192
PyEval_ThreadsInitialized(void)
193193
{
194-
return gil_created(&_PyRuntime.ceval.gil);
194+
_PyRuntimeState *runtime = &_PyRuntime;
195+
return gil_created(&runtime->ceval.gil);
195196
}
196197

197198
void
@@ -235,8 +236,9 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval)
235236
}
236237

237238
static inline void
238-
exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate)
239+
exit_thread_if_finalizing(PyThreadState *tstate)
239240
{
241+
_PyRuntimeState *runtime = tstate->interp->runtime;
240242
/* _Py_Finalizing is protected by the GIL */
241243
if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) {
242244
drop_gil(&runtime->ceval, tstate);
@@ -283,7 +285,7 @@ PyEval_AcquireLock(void)
283285
Py_FatalError("PyEval_AcquireLock: current thread state is NULL");
284286
}
285287
take_gil(ceval, tstate);
286-
exit_thread_if_finalizing(runtime, tstate);
288+
exit_thread_if_finalizing(tstate);
287289
}
288290

289291
void
@@ -305,13 +307,13 @@ PyEval_AcquireThread(PyThreadState *tstate)
305307
Py_FatalError("PyEval_AcquireThread: NULL new thread state");
306308
}
307309

308-
_PyRuntimeState *runtime = &_PyRuntime;
310+
_PyRuntimeState *runtime = tstate->interp->runtime;
309311
struct _ceval_runtime_state *ceval = &runtime->ceval;
310312

311313
/* Check someone has called PyEval_InitThreads() to create the lock */
312314
assert(gil_created(&ceval->gil));
313315
take_gil(ceval, tstate);
314-
exit_thread_if_finalizing(runtime, tstate);
316+
exit_thread_if_finalizing(tstate);
315317
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
316318
Py_FatalError("PyEval_AcquireThread: non-NULL old thread state");
317319
}
@@ -324,7 +326,7 @@ PyEval_ReleaseThread(PyThreadState *tstate)
324326
Py_FatalError("PyEval_ReleaseThread: NULL thread state");
325327
}
326328

327-
_PyRuntimeState *runtime = &_PyRuntime;
329+
_PyRuntimeState *runtime = tstate->interp->runtime;
328330
PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
329331
if (new_tstate != tstate) {
330332
Py_FatalError("PyEval_ReleaseThread: wrong thread state");
@@ -384,7 +386,7 @@ PyEval_SaveThread(void)
384386
void
385387
PyEval_RestoreThread(PyThreadState *tstate)
386388
{
387-
_PyRuntimeState *runtime = &_PyRuntime;
389+
_PyRuntimeState *runtime = tstate->interp->runtime;
388390
struct _ceval_runtime_state *ceval = &runtime->ceval;
389391

390392
if (tstate == NULL) {
@@ -394,7 +396,7 @@ PyEval_RestoreThread(PyThreadState *tstate)
394396

395397
int err = errno;
396398
take_gil(ceval, tstate);
397-
exit_thread_if_finalizing(runtime, tstate);
399+
exit_thread_if_finalizing(tstate);
398400
errno = err;
399401

400402
_PyThreadState_Swap(&runtime->gilstate, tstate);
@@ -649,7 +651,8 @@ _PyEval_Initialize(struct _ceval_runtime_state *state)
649651
int
650652
Py_GetRecursionLimit(void)
651653
{
652-
return _PyRuntime.ceval.recursion_limit;
654+
struct _ceval_runtime_state *ceval = &_PyRuntime.ceval;
655+
return ceval->recursion_limit;
653656
}
654657

655658
void
@@ -668,7 +671,7 @@ Py_SetRecursionLimit(int new_limit)
668671
int
669672
_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
670673
{
671-
_PyRuntimeState *runtime = &_PyRuntime;
674+
_PyRuntimeState *runtime = tstate->interp->runtime;
672675
int recursion_limit = runtime->ceval.recursion_limit;
673676

674677
#ifdef USE_STACKCHECK
@@ -1245,7 +1248,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
12451248
take_gil(ceval, tstate);
12461249

12471250
/* Check if we should make a quick exit. */
1248-
exit_thread_if_finalizing(runtime, tstate);
1251+
exit_thread_if_finalizing(tstate);
12491252

12501253
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
12511254
Py_FatalError("ceval: orphan tstate");
@@ -4806,7 +4809,8 @@ _PyEval_GetAsyncGenFinalizer(void)
48064809
static PyFrameObject *
48074810
_PyEval_GetFrame(PyThreadState *tstate)
48084811
{
4809-
return _PyRuntime.gilstate.getframe(tstate);
4812+
_PyRuntimeState *runtime = tstate->interp->runtime;
4813+
return runtime->gilstate.getframe(tstate);
48104814
}
48114815

48124816
PyFrameObject *

Python/pylifecycle.c

+12-11
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
547547
_PyEval_FiniThreads(&runtime->ceval);
548548

549549
/* Auto-thread-state API */
550-
_PyGILState_Init(runtime, tstate);
550+
_PyGILState_Init(tstate);
551551

552552
/* Create the GIL */
553553
PyEval_InitThreads();
@@ -558,11 +558,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
558558

559559

560560
static PyStatus
561-
pycore_init_types(_PyRuntimeState *runtime)
561+
pycore_init_types(PyThreadState *tstate)
562562
{
563563
PyStatus status;
564564

565-
status = _PyGC_Init(runtime);
565+
status = _PyGC_Init(tstate);
566566
if (_PyStatus_EXCEPTION(status)) {
567567
return status;
568568
}
@@ -690,13 +690,13 @@ pyinit_config(_PyRuntimeState *runtime,
690690
config = &tstate->interp->config;
691691
*tstate_p = tstate;
692692

693-
status = pycore_init_types(runtime);
693+
status = pycore_init_types(tstate);
694694
if (_PyStatus_EXCEPTION(status)) {
695695
return status;
696696
}
697697

698698
PyObject *sysmod;
699-
status = _PySys_Create(runtime, tstate, &sysmod);
699+
status = _PySys_Create(tstate, &sysmod);
700700
if (_PyStatus_EXCEPTION(status)) {
701701
return status;
702702
}
@@ -915,8 +915,9 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
915915
* non-zero return code.
916916
*/
917917
static PyStatus
918-
pyinit_main(_PyRuntimeState *runtime, PyThreadState *tstate)
918+
pyinit_main(PyThreadState *tstate)
919919
{
920+
_PyRuntimeState *runtime = tstate->interp->runtime;
920921
if (!runtime->core_initialized) {
921922
return _PyStatus_ERR("runtime core not initialized");
922923
}
@@ -943,7 +944,7 @@ pyinit_main(_PyRuntimeState *runtime, PyThreadState *tstate)
943944
return _PyStatus_ERR("can't initialize time");
944945
}
945946

946-
if (_PySys_InitMain(runtime, tstate) < 0) {
947+
if (_PySys_InitMain(tstate) < 0) {
947948
return _PyStatus_ERR("can't finish initializing sys");
948949
}
949950

@@ -1022,7 +1023,7 @@ _Py_InitializeMain(void)
10221023
}
10231024
_PyRuntimeState *runtime = &_PyRuntime;
10241025
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
1025-
return pyinit_main(runtime, tstate);
1026+
return pyinit_main(tstate);
10261027
}
10271028

10281029

@@ -1049,7 +1050,7 @@ Py_InitializeFromConfig(const PyConfig *config)
10491050
config = &tstate->interp->config;
10501051

10511052
if (config->_init_main) {
1052-
status = pyinit_main(runtime, tstate);
1053+
status = pyinit_main(tstate);
10531054
if (_PyStatus_EXCEPTION(status)) {
10541055
return status;
10551056
}
@@ -1454,7 +1455,7 @@ new_interpreter(PyThreadState **tstate_p)
14541455
}
14551456
config = &interp->config;
14561457

1457-
status = pycore_init_types(runtime);
1458+
status = pycore_init_types(tstate);
14581459

14591460
/* XXX The following is lax in error checking */
14601461
PyObject *modules = PyDict_New();
@@ -1471,7 +1472,7 @@ new_interpreter(PyThreadState **tstate_p)
14711472
}
14721473
Py_INCREF(interp->sysdict);
14731474
PyDict_SetItemString(interp->sysdict, "modules", modules);
1474-
if (_PySys_InitMain(runtime, tstate) < 0) {
1475+
if (_PySys_InitMain(tstate) < 0) {
14751476
return _PyStatus_ERR("can't finish initializing sys");
14761477
}
14771478
}

0 commit comments

Comments
 (0)