Skip to content

Commit 0c13e1f

Browse files
authored
bpo-40241: Add pycore_interp.h header (GH-19499)
Move PyInterpreterState and related functions to a new internal pycore_interp.h header file.
1 parent 1c4cbdf commit 0c13e1f

File tree

5 files changed

+189
-165
lines changed

5 files changed

+189
-165
lines changed

Include/internal/pycore_interp.h

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#ifndef Py_INTERNAL_INTERP_H
2+
#define Py_INTERNAL_INTERP_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
#include "pycore_atomic.h" /* _Py_atomic_address */
12+
#include "pycore_gil.h" /* struct _gil_runtime_state */
13+
#include "pycore_pymem.h" /* struct _gc_runtime_state */
14+
#include "pycore_warnings.h" /* struct _warnings_runtime_state */
15+
16+
/* ceval state */
17+
18+
struct _pending_calls {
19+
PyThread_type_lock lock;
20+
/* Request for running pending calls. */
21+
_Py_atomic_int calls_to_do;
22+
/* Request for looking at the `async_exc` field of the current
23+
thread state.
24+
Guarded by the GIL. */
25+
int async_exc;
26+
#define NPENDINGCALLS 32
27+
struct {
28+
int (*func)(void *);
29+
void *arg;
30+
} calls[NPENDINGCALLS];
31+
int first;
32+
int last;
33+
};
34+
35+
struct _ceval_state {
36+
/* Records whether tracing is on for any thread. Counts the number
37+
of threads for which tstate->c_tracefunc is non-NULL, so if the
38+
value is 0, we know we don't have to check this thread's
39+
c_tracefunc. This speeds up the if statement in
40+
_PyEval_EvalFrameDefault() after fast_next_opcode. */
41+
int tracing_possible;
42+
/* This single variable consolidates all requests to break out of
43+
the fast path in the eval loop. */
44+
_Py_atomic_int eval_breaker;
45+
struct _pending_calls pending;
46+
};
47+
48+
49+
/* interpreter state */
50+
51+
#define _PY_NSMALLPOSINTS 257
52+
#define _PY_NSMALLNEGINTS 5
53+
54+
// The PyInterpreterState typedef is in Include/pystate.h.
55+
struct _is {
56+
57+
struct _is *next;
58+
struct _ts *tstate_head;
59+
60+
/* Reference to the _PyRuntime global variable. This field exists
61+
to not have to pass runtime in addition to tstate to a function.
62+
Get runtime from tstate: tstate->interp->runtime. */
63+
struct pyruntimestate *runtime;
64+
65+
int64_t id;
66+
int64_t id_refcount;
67+
int requires_idref;
68+
PyThread_type_lock id_mutex;
69+
70+
int finalizing;
71+
72+
struct _ceval_state ceval;
73+
struct _gc_runtime_state gc;
74+
75+
PyObject *modules;
76+
PyObject *modules_by_index;
77+
PyObject *sysdict;
78+
PyObject *builtins;
79+
PyObject *importlib;
80+
81+
/* Used in Modules/_threadmodule.c. */
82+
long num_threads;
83+
/* Support for runtime thread stack size tuning.
84+
A value of 0 means using the platform's default stack size
85+
or the size specified by the THREAD_STACK_SIZE macro. */
86+
/* Used in Python/thread.c. */
87+
size_t pythread_stacksize;
88+
89+
PyObject *codec_search_path;
90+
PyObject *codec_search_cache;
91+
PyObject *codec_error_registry;
92+
int codecs_initialized;
93+
94+
/* fs_codec.encoding is initialized to NULL.
95+
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
96+
struct {
97+
char *encoding; /* Filesystem encoding (encoded to UTF-8) */
98+
int utf8; /* encoding=="utf-8"? */
99+
char *errors; /* Filesystem errors (encoded to UTF-8) */
100+
_Py_error_handler error_handler;
101+
} fs_codec;
102+
103+
PyConfig config;
104+
#ifdef HAVE_DLOPEN
105+
int dlopenflags;
106+
#endif
107+
108+
PyObject *dict; /* Stores per-interpreter state */
109+
110+
PyObject *builtins_copy;
111+
PyObject *import_func;
112+
/* Initialized to PyEval_EvalFrameDefault(). */
113+
_PyFrameEvalFunction eval_frame;
114+
115+
Py_ssize_t co_extra_user_count;
116+
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
117+
118+
#ifdef HAVE_FORK
119+
PyObject *before_forkers;
120+
PyObject *after_forkers_parent;
121+
PyObject *after_forkers_child;
122+
#endif
123+
/* AtExit module */
124+
void (*pyexitfunc)(PyObject *);
125+
PyObject *pyexitmodule;
126+
127+
uint64_t tstate_next_unique_id;
128+
129+
struct _warnings_runtime_state warnings;
130+
131+
PyObject *audit_hooks;
132+
133+
struct {
134+
struct {
135+
int level;
136+
int atbol;
137+
} listnode;
138+
} parser;
139+
140+
#if _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS > 0
141+
/* Small integers are preallocated in this array so that they
142+
can be shared.
143+
The integers that are preallocated are those in the range
144+
-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
145+
*/
146+
PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
147+
#endif
148+
};
149+
150+
/* Used by _PyImport_Cleanup() */
151+
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
152+
153+
extern PyStatus _PyInterpreterState_SetConfig(
154+
PyInterpreterState *interp,
155+
const PyConfig *config);
156+
157+
158+
159+
/* cross-interpreter data registry */
160+
161+
/* For now we use a global registry of shareable classes. An
162+
alternative would be to add a tp_* slot for a class's
163+
crossinterpdatafunc. It would be simpler and more efficient. */
164+
165+
struct _xidregitem;
166+
167+
struct _xidregitem {
168+
PyTypeObject *cls;
169+
crossinterpdatafunc getdata;
170+
struct _xidregitem *next;
171+
};
172+
173+
PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T);
174+
175+
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *);
176+
PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *);
177+
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *);
178+
179+
#ifdef __cplusplus
180+
}
181+
#endif
182+
#endif /* !Py_INTERNAL_INTERP_H */
183+

Include/internal/pycore_pystate.h

Lines changed: 1 addition & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -8,167 +8,10 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11-
#include "pycore_gil.h" /* struct _gil_runtime_state */
12-
#include "pycore_pymem.h" /* struct _gc_runtime_state */
13-
#include "pycore_warnings.h" /* struct _warnings_runtime_state */
11+
#include "pycore_interp.h" /* PyInterpreterState */
1412
#include "pycore_runtime.h" /* PyRuntimestate */
1513

1614

17-
/* ceval state */
18-
19-
struct _pending_calls {
20-
PyThread_type_lock lock;
21-
/* Request for running pending calls. */
22-
_Py_atomic_int calls_to_do;
23-
/* Request for looking at the `async_exc` field of the current
24-
thread state.
25-
Guarded by the GIL. */
26-
int async_exc;
27-
#define NPENDINGCALLS 32
28-
struct {
29-
int (*func)(void *);
30-
void *arg;
31-
} calls[NPENDINGCALLS];
32-
int first;
33-
int last;
34-
};
35-
36-
struct _ceval_state {
37-
/* Records whether tracing is on for any thread. Counts the number
38-
of threads for which tstate->c_tracefunc is non-NULL, so if the
39-
value is 0, we know we don't have to check this thread's
40-
c_tracefunc. This speeds up the if statement in
41-
_PyEval_EvalFrameDefault() after fast_next_opcode. */
42-
int tracing_possible;
43-
/* This single variable consolidates all requests to break out of
44-
the fast path in the eval loop. */
45-
_Py_atomic_int eval_breaker;
46-
struct _pending_calls pending;
47-
};
48-
49-
/* interpreter state */
50-
51-
#define _PY_NSMALLPOSINTS 257
52-
#define _PY_NSMALLNEGINTS 5
53-
54-
// The PyInterpreterState typedef is in Include/pystate.h.
55-
struct _is {
56-
57-
struct _is *next;
58-
struct _ts *tstate_head;
59-
60-
/* Reference to the _PyRuntime global variable. This field exists
61-
to not have to pass runtime in addition to tstate to a function.
62-
Get runtime from tstate: tstate->interp->runtime. */
63-
struct pyruntimestate *runtime;
64-
65-
int64_t id;
66-
int64_t id_refcount;
67-
int requires_idref;
68-
PyThread_type_lock id_mutex;
69-
70-
int finalizing;
71-
72-
struct _ceval_state ceval;
73-
struct _gc_runtime_state gc;
74-
75-
PyObject *modules;
76-
PyObject *modules_by_index;
77-
PyObject *sysdict;
78-
PyObject *builtins;
79-
PyObject *importlib;
80-
81-
/* Used in Modules/_threadmodule.c. */
82-
long num_threads;
83-
/* Support for runtime thread stack size tuning.
84-
A value of 0 means using the platform's default stack size
85-
or the size specified by the THREAD_STACK_SIZE macro. */
86-
/* Used in Python/thread.c. */
87-
size_t pythread_stacksize;
88-
89-
PyObject *codec_search_path;
90-
PyObject *codec_search_cache;
91-
PyObject *codec_error_registry;
92-
int codecs_initialized;
93-
94-
/* fs_codec.encoding is initialized to NULL.
95-
Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
96-
struct {
97-
char *encoding; /* Filesystem encoding (encoded to UTF-8) */
98-
int utf8; /* encoding=="utf-8"? */
99-
char *errors; /* Filesystem errors (encoded to UTF-8) */
100-
_Py_error_handler error_handler;
101-
} fs_codec;
102-
103-
PyConfig config;
104-
#ifdef HAVE_DLOPEN
105-
int dlopenflags;
106-
#endif
107-
108-
PyObject *dict; /* Stores per-interpreter state */
109-
110-
PyObject *builtins_copy;
111-
PyObject *import_func;
112-
/* Initialized to PyEval_EvalFrameDefault(). */
113-
_PyFrameEvalFunction eval_frame;
114-
115-
Py_ssize_t co_extra_user_count;
116-
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
117-
118-
#ifdef HAVE_FORK
119-
PyObject *before_forkers;
120-
PyObject *after_forkers_parent;
121-
PyObject *after_forkers_child;
122-
#endif
123-
/* AtExit module */
124-
void (*pyexitfunc)(PyObject *);
125-
PyObject *pyexitmodule;
126-
127-
uint64_t tstate_next_unique_id;
128-
129-
struct _warnings_runtime_state warnings;
130-
131-
PyObject *audit_hooks;
132-
133-
struct {
134-
struct {
135-
int level;
136-
int atbol;
137-
} listnode;
138-
} parser;
139-
140-
#if _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS > 0
141-
/* Small integers are preallocated in this array so that they
142-
can be shared.
143-
The integers that are preallocated are those in the range
144-
-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
145-
*/
146-
PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
147-
#endif
148-
};
149-
150-
PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T);
151-
152-
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *);
153-
PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *);
154-
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *);
155-
156-
157-
/* cross-interpreter data registry */
158-
159-
/* For now we use a global registry of shareable classes. An
160-
alternative would be to add a tp_* slot for a class's
161-
crossinterpdatafunc. It would be simpler and more efficient. */
162-
163-
struct _xidregitem;
164-
165-
struct _xidregitem {
166-
PyTypeObject *cls;
167-
crossinterpdatafunc getdata;
168-
struct _xidregitem *next;
169-
};
170-
171-
17215
/* Check if the current thread is the main thread.
17316
Use _Py_IsMainInterpreter() to check if it's the main interpreter. */
17417
static inline int
@@ -257,13 +100,6 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
257100
PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
258101
PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
259102

260-
/* Used by _PyImport_Cleanup() */
261-
extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp);
262-
263-
extern PyStatus _PyInterpreterState_SetConfig(
264-
PyInterpreterState *interp,
265-
const PyConfig *config);
266-
267103
PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime);
268104

269105

Makefile.pre.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,7 @@ PYTHON_HEADERS= \
10961096
$(srcdir)/Include/internal/pycore_hamt.h \
10971097
$(srcdir)/Include/internal/pycore_import.h \
10981098
$(srcdir)/Include/internal/pycore_initconfig.h \
1099+
$(srcdir)/Include/internal/pycore_interp.h \
10991100
$(srcdir)/Include/internal/pycore_object.h \
11001101
$(srcdir)/Include/internal/pycore_pathconfig.h \
11011102
$(srcdir)/Include/internal/pycore_pyerrors.h \

PCbuild/pythoncore.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
<ClInclude Include="..\Include\internal\pycore_hamt.h" />
178178
<ClInclude Include="..\Include\internal\pycore_import.h" />
179179
<ClInclude Include="..\Include\internal\pycore_initconfig.h" />
180+
<ClInclude Include="..\Include\internal\pycore_interp.h" />
180181
<ClInclude Include="..\Include\internal\pycore_object.h" />
181182
<ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
182183
<ClInclude Include="..\Include\internal\pycore_pyerrors.h" />

PCbuild/pythoncore.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@
234234
<ClInclude Include="..\Include\internal\pycore_initconfig.h">
235235
<Filter>Include</Filter>
236236
</ClInclude>
237+
<ClInclude Include="..\Include\internal\pycore_interp.h">
238+
<Filter>Include</Filter>
239+
</ClInclude>
237240
<ClInclude Include="..\Include\internal\pycore_object.h">
238241
<Filter>Include</Filter>
239242
</ClInclude>

0 commit comments

Comments
 (0)