Skip to content

Commit 6510577

Browse files
committed
gh-155628: Use relaxed adds for the lru_cache hit/miss counters
Add an FT_ATOMIC_ADD_SSIZE_RELAXED wrapper and use it for the lru_cache hits and misses counters, which are updated on every cached call in the free-threaded build. The counters are pure statistics: their only readers are cache_info() and cache_clear(), which already use relaxed loads, so the adds need atomicity but no ordering.
1 parent 28495f2 commit 6510577

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ extern "C" {
137137
_Py_atomic_load_ullong_relaxed(&value)
138138
#define FT_ATOMIC_ADD_SSIZE(value, new_value) \
139139
(void)_Py_atomic_add_ssize(&value, new_value)
140+
#define FT_ATOMIC_ADD_SSIZE_RELAXED(value, new_value) \
141+
(void)_Py_atomic_add_ssize_relaxed(&value, new_value)
140142
#define FT_MUTEX_LOCK(lock) PyMutex_Lock(lock)
141143
#define FT_MUTEX_LOCK_FLAGS(lock, flags) PyMutex_LockFlags(lock, flags)
142144
#define FT_MUTEX_UNLOCK(lock) PyMutex_Unlock(lock)
@@ -201,6 +203,7 @@ extern "C" {
201203
#define FT_ATOMIC_LOAD_ULLONG_RELAXED(value) value
202204
#define FT_ATOMIC_STORE_ULLONG_RELAXED(value, new_value) value = new_value
203205
#define FT_ATOMIC_ADD_SSIZE(value, new_value) (void)(value += new_value)
206+
#define FT_ATOMIC_ADD_SSIZE_RELAXED(value, new_value) (void)(value += new_value)
204207
#define FT_MUTEX_LOCK(lock) do {} while (0)
205208
#define FT_MUTEX_LOCK_FLAGS(lock, flags) do {} while (0)
206209
#define FT_MUTEX_UNLOCK(lock) do {} while (0)

Modules/_functoolsmodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
12991299
{
13001300
PyObject *result;
13011301

1302-
FT_ATOMIC_ADD_SSIZE(self->misses, 1);
1302+
FT_ATOMIC_ADD_SSIZE_RELAXED(self->misses, 1);
13031303
result = PyObject_Call(self->func, args, kwds);
13041304
if (!result)
13051305
return NULL;
@@ -1321,15 +1321,15 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
13211321
}
13221322
int res = _PyDict_GetItemRef_KnownHash((PyDictObject *)self->cache, key, hash, &result);
13231323
if (res > 0) {
1324-
FT_ATOMIC_ADD_SSIZE(self->hits, 1);
1324+
FT_ATOMIC_ADD_SSIZE_RELAXED(self->hits, 1);
13251325
Py_DECREF(key);
13261326
return result;
13271327
}
13281328
if (res < 0) {
13291329
Py_DECREF(key);
13301330
return NULL;
13311331
}
1332-
FT_ATOMIC_ADD_SSIZE(self->misses, 1);
1332+
FT_ATOMIC_ADD_SSIZE_RELAXED(self->misses, 1);
13331333
result = PyObject_Call(self->func, args, kwds);
13341334
if (!result) {
13351335
Py_DECREF(key);
@@ -1425,7 +1425,7 @@ bounded_lru_cache_get_lock_held(lru_cache_object *self, PyObject *args, PyObject
14251425
lru_cache_extract_link(link);
14261426
lru_cache_append_link(self, link);
14271427
*result = link->result;
1428-
FT_ATOMIC_ADD_SSIZE(self->hits, 1);
1428+
FT_ATOMIC_ADD_SSIZE_RELAXED(self->hits, 1);
14291429
Py_INCREF(link->result);
14301430
Py_DECREF(link);
14311431
Py_DECREF(key_);
@@ -1435,7 +1435,7 @@ bounded_lru_cache_get_lock_held(lru_cache_object *self, PyObject *args, PyObject
14351435
Py_DECREF(key_);
14361436
return -1;
14371437
}
1438-
FT_ATOMIC_ADD_SSIZE(self->misses, 1);
1438+
FT_ATOMIC_ADD_SSIZE_RELAXED(self->misses, 1);
14391439
return 0;
14401440
}
14411441

0 commit comments

Comments
 (0)