From: Willy Tarreau Date: Sun, 11 Apr 2021 08:42:28 +0000 (+0200) Subject: MEDIUM: freq_ctr: reimplement freq_ctr_remain_period() from freq_ctr_total() X-Git-Tag: v2.4-dev17~147 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=607be24a85f8c21c1d1528727e2e68f96f7d859b;p=thirdparty%2Fhaproxy.git MEDIUM: freq_ctr: reimplement freq_ctr_remain_period() from freq_ctr_total() Now the function becomes an inline one and only contains a divide and a max. The divide will automatically go away with constant periods. --- diff --git a/include/haproxy/freq_ctr.h b/include/haproxy/freq_ctr.h index 6016614745..3060f2a12d 100644 --- a/include/haproxy/freq_ctr.h +++ b/include/haproxy/freq_ctr.h @@ -148,6 +148,20 @@ static inline uint read_freq_ctr_period(struct freq_ctr_period *ctr, uint period */ unsigned int freq_ctr_remain(struct freq_ctr *ctr, unsigned int freq, unsigned int pend); +/* Returns the number of remaining events that can occur on this freq counter + * while respecting events per period, and taking into account that + * events are already known to be pending. Returns 0 if limit was reached. + */ +static inline uint freq_ctr_remain_period(struct freq_ctr_period *ctr, uint period, uint freq, uint pend) +{ + ullong total = freq_ctr_total(ctr, period, pend); + uint avg = div64_32(total, period); + + if (avg > freq) + avg = freq; + return freq - avg; +} + /* return the expected wait time in ms before the next event may occur, * respecting frequency , and assuming there may already be some pending * events. It returns zero if we can proceed immediately, otherwise the wait @@ -158,8 +172,6 @@ unsigned int next_event_delay(struct freq_ctr *ctr, unsigned int freq, unsigned /* process freq counters over configurable periods */ unsigned int read_freq_ctr_period(struct freq_ctr_period *ctr, unsigned int period); -unsigned int freq_ctr_remain_period(struct freq_ctr_period *ctr, unsigned int period, - unsigned int freq, unsigned int pend); /* While the functions above report average event counts per period, we are * also interested in average values per event. For this we use a different diff --git a/src/freq_ctr.c b/src/freq_ctr.c index a2ca040acd..d68a7841d9 100644 --- a/src/freq_ctr.c +++ b/src/freq_ctr.c @@ -166,56 +166,6 @@ unsigned int next_event_delay(struct freq_ctr *ctr, unsigned int freq, unsigned return MAX(wait, 1); } -/* Returns the number of remaining events that can occur on this freq counter - * while respecting events per period, and taking into account that - * events are already known to be pending. Returns 0 if limit was reached. - */ -unsigned int freq_ctr_remain_period(struct freq_ctr_period *ctr, unsigned int period, - unsigned int freq, unsigned int pend) -{ - unsigned int _curr, _past, curr, past; - unsigned int remain, _curr_tick, curr_tick; - - while (1) { - _curr = ctr->curr_ctr; - __ha_compiler_barrier(); - _past = ctr->prev_ctr; - __ha_compiler_barrier(); - _curr_tick = ctr->curr_tick; - __ha_compiler_barrier(); - if (_curr_tick & 0x1) - continue; - curr = ctr->curr_ctr; - __ha_compiler_barrier(); - past = ctr->prev_ctr; - __ha_compiler_barrier(); - curr_tick = ctr->curr_tick; - __ha_compiler_barrier(); - if (_curr == curr && _past == past && _curr_tick == curr_tick) - break; - }; - - remain = curr_tick + period - global_now_ms; - if (likely((int)remain < 0)) { - /* We're past the first period, check if we can still report a - * part of last period or if we're too far away. - */ - past = curr; - curr = 0; - remain += period; - if ((int)remain < 0) - past = 0; - } - if (likely(past)) - curr += div64_32((unsigned long long)past * remain, period); - - curr += pend; - freq -= curr; - if ((int)freq < 0) - freq = 0; - return freq; -} - /* Returns the total number of events over the current + last period, including * a number of already pending events . The average frequency will be * obtained by dividing the output by . This is essentially made to