summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-06-05 00:56:37 (GMT)
committerGitHub <noreply@github.com>2020-06-05 00:56:37 (GMT)
commite005ead49b1ee2b1507ceea94e6f89c28ecf1f81 (patch)
treef2846eec88f5539825acc200c3b8a3d91a3b7d0f /Python
parent78a02c2568714562e23e885b6dc5730601f35226 (diff)
downloadcpython-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.c35
-rw-r--r--Python/pylifecycle.c5
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);