FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-159558: Avoid un-needed nested locks in set operations by johng · Pull Request #159559 · python/cpython · GitHub

Repository navigation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Speed up ``set >= set``, ``set > set``, :meth:`set.issuperset`, :meth:`set.discard`
and :meth:`set.remove` on the free-threaded build by not re-entering a critical
section already held on the set.
25 changes: 20 additions & 5 deletions Objects/setobject.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -411,27 +411,39 @@ set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
/* ======================================================================== */

static int
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash, setentry **epp)
set_lookkey_lock_held(PySetObject *so, PyObject *key, Py_hash_t hash,
setentry **epp)
{
int status;
if (PyFrozenSet_CheckExact(so)) {
status = set_do_lookup(so, so->table, so->mask, key, hash, epp,
set_compare_frozenset);
}
else {
Py_BEGIN_CRITICAL_SECTION(so);
do {
status = set_do_lookup(so, so->table, so->mask, key, hash, epp,
set_compare_entry_lock_held);
} while (status == SET_LOOKKEY_CHANGED);
Py_END_CRITICAL_SECTION();
}
assert(status == SET_LOOKKEY_FOUND ||
status == SET_LOOKKEY_NO_MATCH ||
status == SET_LOOKKEY_ERROR);
return status;
}

static int
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash, setentry **epp)
{
if (PyFrozenSet_CheckExact(so)) {
return set_lookkey_lock_held(so, key, hash, epp);
}
int status;
Py_BEGIN_CRITICAL_SECTION(so);
status = set_lookkey_lock_held(so, key, hash, epp);
Py_END_CRITICAL_SECTION();
return status;
}

#ifdef Py_GIL_DISABLED
static int
set_lookkey_threadsafe(PySetObject *so, PyObject *key, Py_hash_t hash)
Expand Down Expand Up @@ -581,7 +593,7 @@ set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
setentry *entry;
PyObject *old_key;
int status = set_lookkey(so, key, hash, &entry);
int status = set_lookkey_lock_held(so, key, hash, &entry);
if (status < 0) {
return -1;
}
Expand Down Expand Up @@ -2418,6 +2430,9 @@ set_issubset_impl(PySetObject *so, PyObject *other)
Py_ssize_t pos = 0;
int rv;

_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

if (!PyAnySet_Check(other)) {
PyObject *tmp = set_intersection(so, other);
if (tmp == NULL) {
Expand Down Expand Up @@ -2460,7 +2475,7 @@ set_issuperset_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=ecf00ce552c09461 input=5f2e1f262e6e4ccc]*/
{
if (PyAnySet_Check(other)) {
return set_issubset(other, (PyObject *)so);
return set_issubset_impl((PySetObject *)other, (PyObject *)so);
}

PyObject *key, *it = PyObject_GetIter(other);
Expand Down
Loading

Back | FazBrowse Home | New Git URL