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/context.c | |
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/context.c')
-rw-r--r-- | Python/context.c | 35 |
1 files changed, 19 insertions, 16 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(); } |