diff options
author | Victor Stinner <vstinner@python.org> | 2020-06-05 00:56:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-05 00:56:37 (GMT) |
commit | e005ead49b1ee2b1507ceea94e6f89c28ecf1f81 (patch) | |
tree | f2846eec88f5539825acc200c3b8a3d91a3b7d0f /Python | |
parent | 78a02c2568714562e23e885b6dc5730601f35226 (diff) | |
download | cpython-e005ead49b1ee2b1507ceea94e6f89c28ecf1f81.zip cpython-e005ead49b1ee2b1507ceea94e6f89c28ecf1f81.tar.gz cpython-e005ead49b1ee2b1507ceea94e6f89c28ecf1f81.tar.bz2 |
bpo-40521: Make context free list per-interpreter (GH-20644)
Each interpreter now has its own context free list:
* Move context free list into PyInterpreterState.
* Add _Py_context_state structure.
* Add tstate parameter to _PyContext_ClearFreeList()
and _PyContext_Fini().
* Pass tstate to clear_freelists().
Diffstat (limited to 'Python')
-rw-r--r-- | Python/context.c | 35 | ||||
-rw-r--r-- | Python/pylifecycle.c | 5 |
2 files changed, 20 insertions, 20 deletions
diff --git a/Python/context.c b/Python/context.c index bacc701..3cf8db4 100644 --- a/Python/context.c +++ b/Python/context.c @@ -10,8 +10,6 @@ #define CONTEXT_FREELIST_MAXLEN 255 -static PyContext *ctx_freelist = NULL; -static int ctx_freelist_len = 0; #include "clinic/context.c.h" @@ -334,11 +332,13 @@ class _contextvars.Context "PyContext *" "&PyContext_Type" static inline PyContext * _context_alloc(void) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_context_state *state = &interp->context; PyContext *ctx; - if (ctx_freelist_len) { - ctx_freelist_len--; - ctx = ctx_freelist; - ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + if (state->numfree) { + state->numfree--; + ctx = state->freelist; + state->freelist = (PyContext *)ctx->ctx_weakreflist; ctx->ctx_weakreflist = NULL; _Py_NewReference((PyObject *)ctx); } @@ -458,10 +458,12 @@ context_tp_dealloc(PyContext *self) } (void)context_tp_clear(self); - if (ctx_freelist_len < CONTEXT_FREELIST_MAXLEN) { - ctx_freelist_len++; - self->ctx_weakreflist = (PyObject *)ctx_freelist; - ctx_freelist = self; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_context_state *state = &interp->context; + if (state->numfree < CONTEXT_FREELIST_MAXLEN) { + state->numfree++; + self->ctx_weakreflist = (PyObject *)state->freelist; + state->freelist = self; } else { Py_TYPE(self)->tp_free(self); @@ -1271,11 +1273,12 @@ get_token_missing(void) void -_PyContext_ClearFreeList(void) +_PyContext_ClearFreeList(PyThreadState *tstate) { - for (; ctx_freelist_len; ctx_freelist_len--) { - PyContext *ctx = ctx_freelist; - ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + struct _Py_context_state *state = &tstate->interp->context; + for (; state->numfree; state->numfree--) { + PyContext *ctx = state->freelist; + state->freelist = (PyContext *)ctx->ctx_weakreflist; ctx->ctx_weakreflist = NULL; PyObject_GC_Del(ctx); } @@ -1283,10 +1286,10 @@ _PyContext_ClearFreeList(void) void -_PyContext_Fini(void) +_PyContext_Fini(PyThreadState *tstate) { Py_CLEAR(_token_missing); - _PyContext_ClearFreeList(); + _PyContext_ClearFreeList(tstate); _PyHamt_Fini(); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 073973e..6d2eb1d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1273,10 +1273,7 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) } _PyAsyncGen_Fini(tstate); - - if (is_main_interp) { - _PyContext_Fini(); - } + _PyContext_Fini(tstate); /* Cleanup Unicode implementation */ _PyUnicode_Fini(tstate); |