diff options
author | Sam Gross <colesbury@gmail.com> | 2025-03-26 18:38:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-26 18:38:47 (GMT) |
commit | 67fbfb42bd5dfe861d0c58d9e6c48d8eef033d24 (patch) | |
tree | 282178fa55571c055c8327dc3d77fa6a882a404b /Python/bltinmodule.c | |
parent | 3d4ac1a2c2b610f35a9e164878d67185e4a3546f (diff) | |
download | cpython-67fbfb42bd5dfe861d0c58d9e6c48d8eef033d24.zip cpython-67fbfb42bd5dfe861d0c58d9e6c48d8eef033d24.tar.gz cpython-67fbfb42bd5dfe861d0c58d9e6c48d8eef033d24.tar.bz2 |
gh-131586: Avoid refcount contention in some "special" calls (#131588)
In the free threaded build, the `_PyObject_LookupSpecial()` call can lead to
reference count contention on the returned function object becuase it
doesn't use stackrefs. Refactor some of the callers to use
`_PyObject_MaybeCallSpecialNoArgs`, which uses stackrefs internally.
This fixes the scaling bottleneck in the "lookup_special" microbenchmark
in `ftscalingbench.py`. However, the are still some uses of
`_PyObject_LookupSpecial()` that need to be addressed in future PRs.
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r-- | Python/bltinmodule.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index f776120..7a12a86 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2537,22 +2537,19 @@ static PyObject * builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) /*[clinic end generated code: output=ff0d9dd176c02ede input=275678471d7aca15]*/ { - PyObject *round, *result; - - round = _PyObject_LookupSpecial(number, &_Py_ID(__round__)); - if (round == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_TypeError, - "type %.100s doesn't define __round__ method", - Py_TYPE(number)->tp_name); - return NULL; + PyObject *result; + if (ndigits == Py_None) { + result = _PyObject_MaybeCallSpecialNoArgs(number, &_Py_ID(__round__)); + } + else { + result = _PyObject_MaybeCallSpecialOneArg(number, &_Py_ID(__round__), + ndigits); + } + if (result == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "type %.100s doesn't define __round__ method", + Py_TYPE(number)->tp_name); } - - if (ndigits == Py_None) - result = _PyObject_CallNoArgs(round); - else - result = PyObject_CallOneArg(round, ndigits); - Py_DECREF(round); return result; } |