mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
c01e94a431
Update adds a general source for retrieving a monotonic time. In addition, AE has been updated to utilize the new monotonic clock for timer processing. This performance improvement is **not** enabled in a default build due to various H/W compatibility concerns, see README.md for details. It does however change the default use of gettimeofday with clock_gettime and somewhat improves performance. This update provides the following 1. An interface for retrieving a monotonic clock. getMonotonicUs returns a uint64_t (aka monotime) with the number of micro-seconds from an arbitrary point. No more messing with tv_sec/tv_usec. Simple routines are provided for measuring elapsed milli-seconds or elapsed micro-seconds (the most common use case for a monotonic timer). No worries about time moving backwards. 2. High-speed assembler implementation for x86 and ARM. The standard method for retrieving the monotonic clock is POSIX.1b (1993): clock_gettime(CLOCK_MONOTONIC, timespec*). However, most modern processors provide a constant speed instruction clock which can be retrieved in a fraction of the time that it takes to call clock_gettime. For x86, this is provided by the RDTSC instruction. For ARM, this is provided by the CNTVCT_EL0 instruction. As a compile-time option, these high-speed timers can be chosen. (Default is POSIX clock_gettime.) 3. Refactor of event loop timers. The timer processing in ae.c has been refactored to use the new monotonic clock interface. This results in simpler/cleaner logic and improved performance.
53 lines
1.9 KiB
C
53 lines
1.9 KiB
C
#ifndef __MONOTONIC_H
|
|
#define __MONOTONIC_H
|
|
/* The monotonic clock is an always increasing clock source. It is unrelated to
|
|
* the actual time of day and should only be used for relative timings. The
|
|
* monotonic clock is also not guaranteed to be chronologically precise; there
|
|
* may be slight skew/shift from a precise clock.
|
|
*
|
|
* Depending on system architecture, the monotonic time may be able to be
|
|
* retrieved much faster than a normal clock source by using an instruction
|
|
* counter on the CPU. On x86 architectures (for example), the RDTSC
|
|
* instruction is a very fast clock source for this purpose.
|
|
*/
|
|
|
|
#include "fmacros.h"
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
|
|
/* A counter in micro-seconds. The 'monotime' type is provided for variables
|
|
* holding a monotonic time. This will help distinguish & document that the
|
|
* variable is associated with the monotonic clock and should not be confused
|
|
* with other types of time.*/
|
|
typedef uint64_t monotime;
|
|
|
|
/* Retrieve counter of micro-seconds relative to an arbitrary point in time. */
|
|
extern monotime (*getMonotonicUs)(void);
|
|
|
|
|
|
/* Call once at startup to initialize the monotonic clock. Though this only
|
|
* needs to be called once, it may be called additional times without impact.
|
|
* Returns a printable string indicating the type of clock initialized.
|
|
* (The returned string is static and doesn't need to be freed.) */
|
|
const char * monotonicInit();
|
|
|
|
|
|
/* Functions to measure elapsed time. Example:
|
|
* monotime myTimer;
|
|
* elapsedStart(&myTimer);
|
|
* while (elapsedMs(myTimer) < 10) {} // loops for 10ms
|
|
*/
|
|
static inline void elapsedStart(monotime *start_time) {
|
|
*start_time = getMonotonicUs();
|
|
}
|
|
|
|
static inline uint64_t elapsedUs(monotime start_time) {
|
|
return getMonotonicUs() - start_time;
|
|
}
|
|
|
|
static inline uint64_t elapsedMs(monotime start_time) {
|
|
return elapsedUs(start_time) / 1000;
|
|
}
|
|
|
|
#endif
|