VNC-151 Add time utilities

This commit is contained in:
El 2026-03-09 18:55:14 +00:00
parent 06e826a9be
commit 1923de6780
No known key found for this signature in database
GPG key ID: EB3F4C9EA29CDE59
2 changed files with 127 additions and 17 deletions

View file

@ -550,28 +550,57 @@ namespace rfb {
return buffer;
}
unsigned msBetween(const struct timeval *first,
const struct timeval *second)
template <TimeType T>
unsigned msBetween(const T *first, const T *second)
{
unsigned diff;
unsigned diff = (second->tv_sec - first->tv_sec) * 1000;
diff = (second->tv_sec - first->tv_sec) * 1000;
if constexpr (std::is_same_v<T, timeval>) {
diff += second->tv_usec / 1000;
diff -= first->tv_usec / 1000;
} else {
diff += (second->tv_nsec - first->tv_nsec) / 1000000;
}
diff += second->tv_usec / 1000;
diff -= first->tv_usec / 1000;
return diff;
return diff;
}
unsigned msSince(const struct timeval *then)
{
struct timeval now;
template <TimeType T>
uint64_t usBetween(const T *first, const T *second) {
int64_t diff = (second->tv_sec - first->tv_sec) * 1000000;
gettimeofday(&now, NULL);
if constexpr (std::is_same_v<T, timeval>) {
diff += second->tv_usec - first->tv_usec;
} else {
diff += (second->tv_nsec - first->tv_nsec) / 1000;
}
return diff;
}
template <TimeType T>
unsigned msSince(const T *then)
{
T now;
if constexpr (std::is_same_v<T, timeval>)
gettimeofday(&now, NULL);
else
clock_gettime(CLOCK_MONOTONIC, &now);
return msBetween(then, &now);
}
template <TimeType T>
uint64_t usSince(const T *then) {
T now;
if constexpr (std::is_same_v<T, timeval>)
gettimeofday(&now, nullptr);
else
clock_gettime(CLOCK_MONOTONIC, &now);
return usBetween(then, &now);
}
uint64_t elapsedMs(std::chrono::high_resolution_clock::time_point start)
{
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count();
@ -682,5 +711,15 @@ namespace rfb {
usersList = "{\"users\": " + usersList + "} ";
return usersList;
}
template unsigned msBetween<timeval>(const timeval *first, const timeval *second);
template unsigned msBetween<timespec>(const timespec *first, const timespec *second);
template uint64_t usBetween<timeval>(const timeval *first, const timeval *second);
template uint64_t usBetween<timespec>(const timespec *first, const timespec *second);
template unsigned msSince<timeval>(const timeval *then);
template unsigned msSince<timespec>(const timespec *then);
template uint64_t usSince<timeval>(const timeval *then);
template uint64_t usSince<timespec>(const timespec *then);
};

View file

@ -134,12 +134,26 @@ namespace rfb {
return (secs < 0 || secs > (INT_MAX/1000) ? INT_MAX : secs * 1000);
}
// Returns time elapsed between two moments in milliseconds.
unsigned msBetween(const struct timeval *first,
const struct timeval *second);
template<typename T>
concept TimeType = std::is_same_v<T, timeval> || std::is_same_v<T, timespec>;
// Returns time elapsed since given moment in milliseconds.
unsigned msSince(const struct timeval *then);
// Returns time elapsed between two moments in milliseconds.
template <TimeType T>
unsigned msBetween(const T *first,
const T *second);
// Returns time elapsed between two moments in microseconds.
template <TimeType T>
uint64_t usBetween(const T *first,
const T *second);
// Returns time elapsed since the given moment in milliseconds.
template <TimeType T>
unsigned msSince(const T *then);
// Returns time elapsed since the given moment in microseconds
template <TimeType T>
uint64_t usSince(const T *then);
/**
* Calculates the number of milliseconds elapsed since a given starting point.
@ -176,4 +190,61 @@ namespace rfb {
#define __rfbmin(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define STOPWATCH_END_US(name, result) \
const auto result = usSince(&name)
#define STOPWATCH_END_MS(name, result) \
const auto result = msSince(&name)
#define STOPWATCH_PRINT_US(log, name) \
STOPWATCH_END_US(name, name##_end); \
log.debug("Time "#name": %lu us", name##_end)
#define STOPWATCH_PRINT_MS(log, name) \
STOPWATCH_END_MS(name, name##_end); \
log.debug("Time "#name": %u ms", name##_end)
#define COARSE_STOPWATCH(name) \
timespec name; \
clock_gettime(CLOCK_MONOTONIC_COARSE, &name)
#define COARSE_STOPWATCH_PRINT_MS(log, name) STOPWATCH_PRINT_MS(log, name)
#define MONOTONIC_STOPWATCH(name) \
timespec name; \
clock_gettime(CLOCK_MONOTONIC, &name)
#define MONOTONIC_STOPWATCH_PRINT_US(log, name) STOPWATCH_PRINT_US(log, name)
#define MONOTONIC_STOPWATCH_PRINT_MS(log, name) STOPWATCH_PRINT_MS(log, name)
#define TIMEOFDAY_STOPWATCH(name) \
timeval name; \
gettimeofday(&name, nullptr)
#define TIMEOFDAY_STOPWATCH_PRINT_MS(log, name) STOPWATCH_PRINT_MS(log, name)
#define TRACE_STOPWATCH(name) COARSE_STOPWATCH(name)
#define TRACE_STOPWATCH_PRINT_MS(log, name) COARSE_STOPWATCH_PRINT_MS(log, name)
#define TRACE_STOPWATCH_END_MS(name, result) STOPWATCH_END_MS(name, result)
#ifndef NDEBUG
#define DEBUG_STOPWATCH(name) MONOTONIC_STOPWATCH(name)
#else
#define DEBUG_STOPWATCH(name)
#endif
#ifndef NDEBUG
#define DEBUG_STOPWATCH_PRINT_US(log, name) MONOTONIC_STOPWATCH_PRINT_US(log, name)
#define DEBUG_STOPWATCH_PRINT_MS(log, name) MONOTONIC_STOPWATCH_PRINT_MS(log, name)
#else
#define DEBUG_STOPWATCH_PRINT_US(log, name)
#define DEBUG_STOPWATCH_PRINT_MS(log, name)
#endif
#endif