Skip to content

[3.13] gh-117398: Use Per-Interpreter State for the _datetime Static Types (gh-119929) #120009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
if (PyType_Check(op) &&
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
static_builtin_state *state = _PyStaticType_GetState(
managed_static_type_state *state = _PyStaticType_GetState(
interp, (PyTypeObject *)op);
return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
}
Expand Down
48 changes: 38 additions & 10 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ struct type_cache {

/* For now we hard-code this to a value for which we are confident
all the static builtin types will fit (for all builds). */
#define _Py_MAX_STATIC_BUILTIN_TYPES 200
#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 200
#define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10

typedef struct {
PyTypeObject *type;
int isbuiltin;
int readying;
int ready;
// XXX tp_dict can probably be statically allocated,
Expand All @@ -59,7 +61,7 @@ typedef struct {
are also some diagnostic uses for the list of weakrefs,
so we still keep it. */
PyObject *tp_weaklist;
} static_builtin_state;
} managed_static_type_state;

struct types_state {
/* Used to set PyTypeObject.tp_version_tag.
Expand Down Expand Up @@ -105,8 +107,16 @@ struct types_state {
num_builtins_initialized is incremented once for each static
builtin type. Once initialization is over for a subinterpreter,
the value will be the same as for all other interpreters. */
size_t num_builtins_initialized;
static_builtin_state builtins[_Py_MAX_STATIC_BUILTIN_TYPES];
struct {
size_t num_initialized;
managed_static_type_state initialized[_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES];
} builtins;
/* We apply a similar strategy for managed extension modules. */
struct {
size_t num_initialized;
size_t next_index;
managed_static_type_state initialized[_Py_MAX_MANAGED_STATIC_EXT_TYPES];
} for_extensions;
PyMutex mutex;
};

Expand All @@ -130,12 +140,35 @@ typedef struct wrapperbase pytype_slotdef;


static inline PyObject **
_PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state)
_PyStaticType_GET_WEAKREFS_LISTPTR(managed_static_type_state *state)
{
assert(state != NULL);
return &state->tp_weaklist;
}

extern int _PyStaticType_InitBuiltin(
PyInterpreterState *interp,
PyTypeObject *type);
extern void _PyStaticType_FiniBuiltin(
PyInterpreterState *interp,
PyTypeObject *type);
extern void _PyStaticType_ClearWeakRefs(
PyInterpreterState *interp,
PyTypeObject *type);
extern managed_static_type_state * _PyStaticType_GetState(
PyInterpreterState *interp,
PyTypeObject *type);

// Export for '_datetime' shared extension.
PyAPI_FUNC(int) _PyStaticType_InitForExtension(
PyInterpreterState *interp,
PyTypeObject *self);
PyAPI_FUNC(void) _PyStaticType_FiniForExtension(
PyInterpreterState *interp,
PyTypeObject *self,
int final);


/* Like PyType_GetModuleState, but skips verification
* that type is a heap type with an associated module */
static inline void *
Expand All @@ -151,11 +184,6 @@ _PyType_GetModuleState(PyTypeObject *type)
}


extern int _PyStaticType_InitBuiltin(PyInterpreterState *, PyTypeObject *type);
extern static_builtin_state * _PyStaticType_GetState(PyInterpreterState *, PyTypeObject *);
extern void _PyStaticType_ClearWeakRefs(PyInterpreterState *, PyTypeObject *type);
extern void _PyStaticType_Dealloc(PyInterpreterState *, PyTypeObject *);

// Export for 'math' shared extension, used via _PyType_IsReady() static inline
// function
PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The ``_datetime`` module (C implementation for :mod:`datetime`) now supports
being imported in multiple interpreters.
Loading
Loading