summaryrefslogtreecommitdiffstats
path: root/Python/pystate.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-08-06 18:36:57 (GMT)
committerGitHub <noreply@github.com>2024-08-06 18:36:57 (GMT)
commitdc093010672207176857a747c61da9c046ad9d3e (patch)
tree3eeff2ad72faa7781255016cc0f54c45aecd41d7 /Python/pystate.c
parent1429651a06611a9dbcb1928b746faf52934c12e2 (diff)
downloadcpython-dc093010672207176857a747c61da9c046ad9d3e.zip
cpython-dc093010672207176857a747c61da9c046ad9d3e.tar.gz
cpython-dc093010672207176857a747c61da9c046ad9d3e.tar.bz2
gh-122417: Implement per-thread heap type refcounts (#122418)
The free-threaded build partially stores heap type reference counts in distributed manner in per-thread arrays. This avoids reference count contention when creating or destroying instances. Co-authored-by: Ken Jin <kenjin@python.org>
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 6fbd17f..8f4818c 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -20,6 +20,7 @@
#include "pycore_runtime_init.h" // _PyRuntimeState_INIT
#include "pycore_sysmodule.h" // _PySys_Audit()
#include "pycore_obmalloc.h" // _PyMem_obmalloc_state_on_heap()
+#include "pycore_typeid.h" // _PyType_FinalizeIdPool
/* --------------------------------------------------------------------------
CAUTION
@@ -1584,13 +1585,6 @@ new_threadstate(PyInterpreterState *interp, int whence)
PyMem_RawFree(new_tstate);
}
else {
-#ifdef Py_GIL_DISABLED
- if (_Py_atomic_load_int(&interp->gc.immortalize) == 0) {
- // Immortalize objects marked as using deferred reference counting
- // the first time a non-main thread is created.
- _PyGC_ImmortalizeDeferredObjects(interp);
- }
-#endif
}
#ifdef Py_GIL_DISABLED
@@ -1741,6 +1735,10 @@ PyThreadState_Clear(PyThreadState *tstate)
struct _Py_freelists *freelists = _Py_freelists_GET();
_PyObject_ClearFreeLists(freelists, 1);
+ // Merge our thread-local refcounts into the type's own refcount and
+ // free our local refcount array.
+ _PyType_FinalizeThreadLocalRefcounts((_PyThreadStateImpl *)tstate);
+
// Remove ourself from the biased reference counting table of threads.
_Py_brc_remove_thread(tstate);
#endif
@@ -1799,6 +1797,7 @@ tstate_delete_common(PyThreadState *tstate, int release_gil)
_PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)tstate;
tstate->interp->object_state.reftotal += tstate_impl->reftotal;
tstate_impl->reftotal = 0;
+ assert(tstate_impl->types.refcounts == NULL);
#endif
HEAD_UNLOCK(runtime);