From: Quentin Young Date: Wed, 2 Sep 2020 20:02:55 +0000 (-0400) Subject: lib: remove overflow arithmetic from hash stats X-Git-Tag: base_7.5~10^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=e6464fdc184e4b0a4032286c8fae245dcdb03d8f;p=matthieu%2Ffrr.git lib: remove overflow arithmetic from hash stats Signed values get converted to unsigned for addition, so when the value to adjust a stats variable for hash tables was negative this resulted in overflow arithmetic, which we generally don't want. Signed-off-by: Quentin Young --- diff --git a/lib/hash.c b/lib/hash.c index 7f8a237047..85982774ac 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -77,9 +77,20 @@ void *hash_alloc_intern(void *arg) return arg; } +/* + * ssq = ssq + (new^2 - old^2) + * = ssq + ((new + old) * (new - old)) + */ #define hash_update_ssq(hz, old, new) \ - atomic_fetch_add_explicit(&hz->stats.ssq, (new + old) * (new - old), \ - memory_order_relaxed); + do { \ + int _adjust = (new + old) * (new - old); \ + if (_adjust < 0) \ + atomic_fetch_sub_explicit(&hz->stats.ssq, -_adjust, \ + memory_order_relaxed); \ + else \ + atomic_fetch_add_explicit(&hz->stats.ssq, _adjust, \ + memory_order_relaxed); \ + } while (0) /* Expand hash if the chain length exceeds the threshold. */ static void hash_expand(struct hash *hash)