From: Willy Tarreau Date: Mon, 19 Dec 2022 16:19:45 +0000 (+0100) Subject: MINOR: freq_ctr: add opportunistic versions of swrate_add() X-Git-Tag: v2.8-dev1~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e327b4a73e3ac5fce223aa34d1ed293ad8a57cf4;p=thirdparty%2Fhaproxy.git 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". --- diff --git a/include/haproxy/freq_ctr.h b/include/haproxy/freq_ctr.h index fbb78520a9..9560611776 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.