aboutsummaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-12-26 00:41:46 +0100
committerGitHub <noreply@github.com>2020-12-26 00:41:46 +0100
commitba3d67c2fb04a7842741b1b6da5d67f22c579f33 (patch)
treed5d8f09c94f413f54ce6014e253ad1de59548bba /Python
parentSync what's new in 3.9 with 3.9 branch (GH-23943) (diff)
downloadcpython-ba3d67c2fb04a7842741b1b6da5d67f22c579f33.tar.gz
cpython-ba3d67c2fb04a7842741b1b6da5d67f22c579f33.tar.bz2
cpython-ba3d67c2fb04a7842741b1b6da5d67f22c579f33.zip
bpo-39465: Fix _PyUnicode_FromId() for subinterpreters (GH-20058)
Make _PyUnicode_FromId() function compatible with subinterpreters. Each interpreter now has an array of identifier objects (interned strings decoded from UTF-8). * Add PyInterpreterState.unicode.identifiers: array of identifiers objects. * Add _PyRuntimeState.unicode_ids used to allocate unique indexes to _Py_Identifier. * Rewrite the _Py_Identifier structure. Microbenchmark on _PyUnicode_FromId(&PyId_a) with _Py_IDENTIFIER(a): [ref] 2.42 ns +- 0.00 ns -> [atomic] 3.39 ns +- 0.00 ns: 1.40x slower This change adds 1 ns per _PyUnicode_FromId() call in average.
Diffstat (limited to 'Python')
-rw-r--r--Python/pystate.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index ead25b08d7..231144b082 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -73,18 +73,24 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime)
runtime->interpreters.mutex = PyThread_allocate_lock();
if (runtime->interpreters.mutex == NULL) {
- return _PyStatus_ERR("Can't initialize threads for interpreter");
+ return _PyStatus_NO_MEMORY();
}
runtime->interpreters.next_id = -1;
runtime->xidregistry.mutex = PyThread_allocate_lock();
if (runtime->xidregistry.mutex == NULL) {
- return _PyStatus_ERR("Can't initialize threads for cross-interpreter data registry");
+ return _PyStatus_NO_MEMORY();
}
// Set it to the ID of the main thread of the main interpreter.
runtime->main_thread = PyThread_get_thread_ident();
+ runtime->unicode_ids.lock = PyThread_allocate_lock();
+ if (runtime->unicode_ids.lock == NULL) {
+ return _PyStatus_NO_MEMORY();
+ }
+ runtime->unicode_ids.next_index = 0;
+
return _PyStatus_OK();
}
@@ -108,17 +114,17 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
/* Force the allocator used by _PyRuntimeState_Init(). */
PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-
- if (runtime->interpreters.mutex != NULL) {
- PyThread_free_lock(runtime->interpreters.mutex);
- runtime->interpreters.mutex = NULL;
+#define FREE_LOCK(LOCK) \
+ if (LOCK != NULL) { \
+ PyThread_free_lock(LOCK); \
+ LOCK = NULL; \
}
- if (runtime->xidregistry.mutex != NULL) {
- PyThread_free_lock(runtime->xidregistry.mutex);
- runtime->xidregistry.mutex = NULL;
- }
+ FREE_LOCK(runtime->interpreters.mutex);
+ FREE_LOCK(runtime->xidregistry.mutex);
+ FREE_LOCK(runtime->unicode_ids.lock);
+#undef FREE_LOCK
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
}
@@ -139,12 +145,14 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex);
int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex);
int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex);
+ int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (reinit_interp < 0
|| reinit_main_id < 0
- || reinit_xidregistry < 0)
+ || reinit_xidregistry < 0
+ || reinit_unicode_ids < 0)
{
return _PyStatus_ERR("Failed to reinitialize runtime locks");