#define SETNOW(a) (*a=now)
extern unsigned int curr_sec_ms; /* millisecond of current second (0..999) */
+extern unsigned int ms_left_scaled; /* milliseconds left for current second (0..2^32-1) */
extern unsigned int curr_sec_ms_scaled; /* millisecond of current second (0..2^32-1) */
extern unsigned int now_ms; /* internal date in milliseconds (may wrap) */
extern unsigned int samp_time; /* total elapsed time over current sample */
if (past <= 1 && !curr)
return past; /* very low rate, avoid flapping */
- return curr + mul32hi(past, ~curr_sec_ms_scaled);
+ return curr + mul32hi(past, ms_left_scaled);
}
/* returns the number of remaining events that can occur on this freq counter
unsigned int curr, past;
unsigned int age;
- past = 0;
curr = 0;
age = now.tv_sec - ctr->curr_sec;
curr = past;
past = ctr->prev_ctr;
}
- curr += mul32hi(past, ~curr_sec_ms_scaled);
+ curr += mul32hi(past, ms_left_scaled);
}
curr += pend;
curr = past;
past = ctr->prev_ctr;
}
- curr += mul32hi(past, ~curr_sec_ms_scaled);
+ curr += mul32hi(past, ms_left_scaled);
}
curr += pend;
#include <common/standard.h>
#include <common/time.h>
-unsigned int curr_sec_ms; /* millisecond of current second (0..999) */
-unsigned int curr_sec_ms_scaled; /* millisecond of current second (0..2^32-1) */
+unsigned int curr_sec_ms; /* millisecond of current second (0..999) */
+unsigned int ms_left_scaled; /* milliseconds left for current second (0..2^32-1) */
unsigned int now_ms; /* internal date in milliseconds (may wrap) */
unsigned int samp_time; /* total elapsed time over current sample */
unsigned int idle_time; /* total idle time over current sample */
to_ms:
now = adjusted;
curr_sec_ms = now.tv_usec / 1000; /* ms of current second */
- curr_sec_ms_scaled = curr_sec_ms * 4294971; /* ms * 2^32 / 1000 */
+
+ /* For frequency counters, we'll need to know the ratio of the previous
+ * value to add to current value depending on the current millisecond.
+ * The principle is that during the first millisecond, we use 999/1000
+ * of the past value and that during the last millisecond we use 0/1000
+ * of the past value. In summary, we only use the past value during the
+ * first 999 ms of a second, and the last ms is used to complete the
+ * current measure. The value is scaled to (2^32-1) so that a simple
+ * multiply followed by a shift gives us the final value.
+ */
+ ms_left_scaled = (999U - curr_sec_ms) * 4294967U;
now_ms = now.tv_sec * 1000 + curr_sec_ms;
return;
}