mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-140476: optimize PySet_Add for frozenset in free-threading (#140440)
Avoids critical section in `PySet_Add` when adding items to newly created frozensets. Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
parent
b5196fa15a
commit
298e9074cd
2 changed files with 18 additions and 9 deletions
|
|
@ -0,0 +1,2 @@
|
|||
Optimize :c:func:`PySet_Add` for :class:`frozenset` in :term:`free threaded
|
||||
<free threading>` build.
|
||||
|
|
@ -2775,12 +2775,7 @@ PySet_Discard(PyObject *set, PyObject *key)
|
|||
int
|
||||
PySet_Add(PyObject *anyset, PyObject *key)
|
||||
{
|
||||
if (!PySet_Check(anyset) &&
|
||||
(!PyFrozenSet_Check(anyset) || !_PyObject_IsUniquelyReferenced(anyset))) {
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PySet_Check(anyset)) {
|
||||
int rv;
|
||||
Py_BEGIN_CRITICAL_SECTION(anyset);
|
||||
rv = set_add_key((PySetObject *)anyset, key);
|
||||
|
|
@ -2788,6 +2783,18 @@ PySet_Add(PyObject *anyset, PyObject *key)
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (PyFrozenSet_Check(anyset) && _PyObject_IsUniquelyReferenced(anyset)) {
|
||||
// We can only change frozensets if they are uniquely referenced. The
|
||||
// API limits the usage of `PySet_Add` to "fill in the values of brand
|
||||
// new frozensets before they are exposed to other code". In this case,
|
||||
// this can be done without a lock.
|
||||
return set_add_key((PySetObject *)anyset, key);
|
||||
}
|
||||
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue