[OPTIM] rate-limit: cleaner behaviour on low rates and reduce consumption

The rate-limit was applied to the smoothed value which does a special
case for frequencies below 2 events per period. This caused irregular
limitations when set to 1 session per second.

The proper way to handle this is to compute the number of remaining
events that can occur without reaching the limit. This is what has
been added. It also has the benefit that the frequency calculation
is now done once when entering event_accept(), before the accept()
loop, and not once per accept() loop anymore, thus saving a few CPU
cycles during very high loads.

With this fix, rate limits of 1/s are perfectly respected.
diff --git a/src/freq_ctr.c b/src/freq_ctr.c
index 4522ff3..ce1ca6c 100644
--- a/src/freq_ctr.c
+++ b/src/freq_ctr.c
@@ -13,6 +13,7 @@
 #include <common/config.h>
 #include <common/standard.h>
 #include <common/time.h>
+#include <common/tools.h>
 #include <proto/freq_ctr.h>
 
 /* Read a frequency counter taking history into account for missing time in
@@ -22,6 +23,10 @@
  * will be inaccurate still appropriate for max checking. One trick we use for
  * low values is to specially handle the case where the rate is between 0 and 1
  * in order to avoid flapping while waiting for the next event.
+ *
+ * For immediate limit checking, it's recommended to use freq_ctr_remain() and
+ * next_event_delay() instead which do not have the flapping correction, so
+ * that even frequencies as low as one event/period are properly handled.
  */
 unsigned int read_freq_ctr(struct freq_ctr *ctr)
 {
@@ -36,6 +41,47 @@
 	return cur + mul32hi(ctr->prev_ctr, ~curr_sec_ms_scaled);
 }
 
+/* returns the number of remaining events that can occur on this freq counter
+ * while respecting <freq> and taking into account that <pend> events are
+ * already known to be pending. Returns 0 if limit was reached.
+ */
+unsigned int freq_ctr_remain(struct freq_ctr *ctr, unsigned int freq, unsigned int pend)
+{
+	unsigned int cur;
+	if (unlikely(ctr->curr_sec != now.tv_sec))
+		rotate_freq_ctr(ctr);
+
+	cur = mul32hi(ctr->prev_ctr, ~curr_sec_ms_scaled);
+	cur += ctr->curr_ctr + pend;
+
+	if (cur >= freq)
+		return 0;
+	return freq - cur;
+}
+
+/* return the expected wait time in ms before the next event may occur,
+ * respecting frequency <freq>, and assuming there may already be some pending
+ * events. It returns zero if we can proceed immediately, otherwise the wait
+ * time, which will be rounded down 1ms for better accuracy, with a minimum
+ * of one ms.
+ */
+unsigned int next_event_delay(struct freq_ctr *ctr, unsigned int freq, unsigned int pend)
+{
+	unsigned int cur, wait;
+
+	if (unlikely(ctr->curr_sec != now.tv_sec))
+		rotate_freq_ctr(ctr);
+
+	cur = mul32hi(ctr->prev_ctr, ~curr_sec_ms_scaled);
+	cur += ctr->curr_ctr + pend;
+
+	if (cur < freq)
+		return 0;
+
+	wait = 999 / cur;
+	return MAX(wait, 1);
+}
+
 
 /*
  * Local variables: