All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 02a03a9f authored by Alex Bligh's avatar Alex Bligh Committed by Stefan Hajnoczi

aio / timers: add qemu-timer.c utility functions

Add utility functions to qemu-timer.c for nanosecond timing.

Add qemu_clock_deadline_ns to calculate deadlines to
nanosecond accuracy.

Add utility function qemu_soonest_timeout to calculate soonest deadline.

Add qemu_timeout_ns_to_ms to convert a timeout in nanoseconds back to
milliseconds for when ppoll is not used.
Signed-off-by: default avatarAlex Bligh <alex@alex.org.uk>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 58ac56b9
......@@ -40,6 +40,29 @@ int64_t qemu_get_clock_ns(QEMUClock *clock);
int64_t qemu_clock_has_timers(QEMUClock *clock);
int64_t qemu_clock_expired(QEMUClock *clock);
int64_t qemu_clock_deadline(QEMUClock *clock);
/**
* qemu_clock_deadline_ns:
* @clock: the clock to operate on
*
* Calculate the timeout of the earliest expiring timer
* in nanoseconds, or -1 if no timer is set to expire.
*
* Returns: time until expiry in nanoseconds or -1
*/
int64_t qemu_clock_deadline_ns(QEMUClock *clock);
/**
* qemu_timeout_ns_to_ms:
* @ns: nanosecond timeout value
*
* Convert a nanosecond timeout value (or -1) to
* a millisecond value (or -1), always rounding up.
*
* Returns: millisecond timeout value
*/
int qemu_timeout_ns_to_ms(int64_t ns);
void qemu_clock_enable(QEMUClock *clock, bool enabled);
void qemu_clock_warp(QEMUClock *clock);
......@@ -67,6 +90,25 @@ int64_t cpu_get_ticks(void);
void cpu_enable_ticks(void);
void cpu_disable_ticks(void);
/**
* qemu_soonest_timeout:
* @timeout1: first timeout in nanoseconds (or -1 for infinite)
* @timeout2: second timeout in nanoseconds (or -1 for infinite)
*
* Calculates the soonest of two timeout values. -1 means infinite, which
* is later than any other value.
*
* Returns: soonest timeout value in nanoseconds (or -1 for infinite)
*/
static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
{
/* we can abuse the fact that -1 (which means infinite) is a maximal
* value when cast to unsigned. As this is disgusting, it's kept in
* one inline function.
*/
return ((uint64_t) timeout1 < (uint64_t) timeout2) ? timeout1 : timeout2;
}
static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
void *opaque)
{
......
......@@ -273,6 +273,56 @@ int64_t qemu_clock_deadline(QEMUClock *clock)
return delta;
}
/*
* As above, but return -1 for no deadline, and do not cap to 2^32
* as we know the result is always positive.
*/
int64_t qemu_clock_deadline_ns(QEMUClock *clock)
{
int64_t delta;
if (!clock->enabled || !clock->active_timers) {
return -1;
}
delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
if (delta <= 0) {
return 0;
}
return delta;
}
/* Transition function to convert a nanosecond timeout to ms
* This is used where a system does not support ppoll
*/
int qemu_timeout_ns_to_ms(int64_t ns)
{
int64_t ms;
if (ns < 0) {
return -1;
}
if (!ns) {
return 0;
}
/* Always round up, because it's better to wait too long than to wait too
* little and effectively busy-wait
*/
ms = (ns + SCALE_MS - 1) / SCALE_MS;
/* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */
if (ms > (int64_t) INT32_MAX) {
ms = INT32_MAX;
}
return (int) ms;
}
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
QEMUTimerCB *cb, void *opaque)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment