mirror of https://github.com/xqemu/xqemu.git
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: Alex Bligh <alex@alex.org.uk> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
58ac56b9ad
commit
02a03a9f12
|
@ -40,6 +40,29 @@ int64_t qemu_get_clock_ns(QEMUClock *clock);
|
||||||
int64_t qemu_clock_has_timers(QEMUClock *clock);
|
int64_t qemu_clock_has_timers(QEMUClock *clock);
|
||||||
int64_t qemu_clock_expired(QEMUClock *clock);
|
int64_t qemu_clock_expired(QEMUClock *clock);
|
||||||
int64_t qemu_clock_deadline(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_enable(QEMUClock *clock, bool enabled);
|
||||||
void qemu_clock_warp(QEMUClock *clock);
|
void qemu_clock_warp(QEMUClock *clock);
|
||||||
|
|
||||||
|
@ -67,6 +90,25 @@ int64_t cpu_get_ticks(void);
|
||||||
void cpu_enable_ticks(void);
|
void cpu_enable_ticks(void);
|
||||||
void cpu_disable_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,
|
static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
|
|
50
qemu-timer.c
50
qemu-timer.c
|
@ -273,6 +273,56 @@ int64_t qemu_clock_deadline(QEMUClock *clock)
|
||||||
return delta;
|
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,
|
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
|
||||||
QEMUTimerCB *cb, void *opaque)
|
QEMUTimerCB *cb, void *opaque)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue