From e327b4a73e3ac5fce223aa34d1ed293ad8a57cf4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 19 Dec 2022 17:19:45 +0100 Subject: [PATCH] MINOR: freq_ctr: add opportunistic versions of swrate_add() Some uses of swrate_add() only consist in getting a rough estimate of a frequency. There are cases where speed matters more than accuracy (e.g. pools). For such use cases, let's just stop looping on the CAS, if the update fails, another thread is already providing input, and it's not dramatic to lose the race. All these functions are now suffixed with "_opportunistic". --- include/haproxy/freq_ctr.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/haproxy/freq_ctr.h b/include/haproxy/freq_ctr.h index fbb78520a..956061177 100644 --- a/include/haproxy/freq_ctr.h +++ b/include/haproxy/freq_ctr.h @@ -348,6 +348,41 @@ static inline unsigned int swrate_add_scaled(unsigned int *sum, unsigned int n, return new_sum; } +/* opportunistic versions of the functions above: an attempt is made to update + * the value, but in case of contention, it's not retried. This is fine when + * rough estimates are needed and speed is preferred over accuracy. + */ + +static inline uint swrate_add_opportunistic(uint *sum, uint n, uint v) +{ + uint new_sum, old_sum; + + old_sum = *sum; + new_sum = old_sum - (old_sum + n - 1) / n + v; + HA_ATOMIC_CAS(sum, &old_sum, new_sum); + return new_sum; +} + +static inline uint swrate_add_dynamic_opportunistic(uint *sum, uint n, uint v) +{ + uint new_sum, old_sum; + + old_sum = *sum; + new_sum = old_sum - (n ? (old_sum + n - 1) / n : 0) + v; + HA_ATOMIC_CAS(sum, &old_sum, new_sum); + return new_sum; +} + +static inline uint swrate_add_scaled_opportunistic(uint *sum, uint n, uint v, uint s) +{ + uint new_sum, old_sum; + + old_sum = *sum; + new_sum = old_sum + v * s - div64_32((unsigned long long)(old_sum + n) * s, n); + HA_ATOMIC_CAS(sum, &old_sum, new_sum); + return new_sum; +} + /* Returns the average sample value for the sum over a sliding window of * samples. Better if is a power of two. It must be the same as the * one used above in all additions.