From 5cfdbab1175aec596e16eeafe418eba21e29c768 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 25 May 2020 18:33:09 +0200 Subject: [PATCH] [WIP] bpo-39465: Mark _Py_Identifier.object as atomic This PR is basically a test to check if C compilers used by CPython support C11 _Atomic specifier. --- Include/cpython/object.h | 5 ++++- Objects/unicodeobject.c | 28 +++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 444f832f5bd8d3..255b31210874ea 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -45,7 +45,10 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); typedef struct _Py_Identifier { struct _Py_Identifier *next; const char* string; - PyObject *object; + // bpo-39465: _PyUnicode_FromId() can be called by multiple threads + // running in different interpreters. Use an atomic variable rather + // than a lock for better parallelism. + _Atomic PyObject *object; } _Py_Identifier; #define _Py_static_string_init(value) { .next = NULL, .string = value, .object = NULL } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ea46a44bf5faac..c8421a3a53e7fa 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2275,18 +2275,24 @@ PyUnicode_FromString(const char *u) PyObject * _PyUnicode_FromId(_Py_Identifier *id) { - if (!id->object) { - id->object = PyUnicode_DecodeUTF8Stateful(id->string, - strlen(id->string), - NULL, NULL); - if (!id->object) - return NULL; - PyUnicode_InternInPlace(&id->object); - assert(!id->next); - id->next = static_strings; - static_strings = id; + if (id->object) { + return (PyObject *)id->object; } - return id->object; + + PyObject *object; + object = PyUnicode_DecodeUTF8Stateful(id->string, + strlen(id->string), + NULL, NULL); + if (!object) { + return NULL; + } + + PyUnicode_InternInPlace(&object); + id->object = (_Atomic PyObject *)object; + assert(!id->next); + id->next = static_strings; + static_strings = id; + return object; } static void