From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49164) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4rfO-0006rB-L4 for qemu-devel@nongnu.org; Thu, 01 Aug 2013 08:07:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V4rfJ-0004eQ-KG for qemu-devel@nongnu.org; Thu, 01 Aug 2013 08:07:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40269) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4rfJ-0004eI-DJ for qemu-devel@nongnu.org; Thu, 01 Aug 2013 08:07:33 -0400 Date: Thu, 1 Aug 2013 14:07:19 +0200 From: Paolo Bonzini Message-ID: <20130801120718.GE5245@mail.corp.redhat.com> References: <34B083D4DB6D2988A571E420@nimrod.local> <1374863862-32517-1-git-send-email-alex@alex.org.uk> <1374863862-32517-2-git-send-email-alex@alex.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <1374863862-32517-2-git-send-email-alex@alex.org.uk> Subject: Re: [Qemu-devel] [RFC] [PATCHv4 01/13] aio / timers: add qemu-timer.c utility functions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alex Bligh Cc: Kevin Wolf , Anthony Liguori , qemu-devel@nongnu.org, Stefan Hajnoczi , rth@twiddle.net On Jul 26 2013, Alex Bligh wrote: > Add qemu_free_clock and expose qemu_new_clock and clock types. > > 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 > --- > include/qemu/timer.h | 17 ++++++++++++++ > qemu-timer.c | 63 +++++++++++++++++++++++++++++++++++++++++++++----- > 2 files changed, 74 insertions(+), 6 deletions(-) > > diff --git a/include/qemu/timer.h b/include/qemu/timer.h > index 9dd206c..6171db3 100644 > --- a/include/qemu/timer.h > +++ b/include/qemu/timer.h > @@ -11,6 +11,10 @@ > #define SCALE_US 1000 > #define SCALE_NS 1 > > +#define QEMU_CLOCK_REALTIME 0 > +#define QEMU_CLOCK_VIRTUAL 1 > +#define QEMU_CLOCK_HOST 2 > + > typedef struct QEMUClock QEMUClock; > typedef void QEMUTimerCB(void *opaque); > > @@ -32,10 +36,14 @@ extern QEMUClock *vm_clock; > the virtual clock. */ > extern QEMUClock *host_clock; > > +QEMUClock *qemu_new_clock(int type); > +void qemu_free_clock(QEMUClock *clock); > 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); > +int64_t qemu_clock_deadline_ns(QEMUClock *clock); > +int qemu_timeout_ns_to_ms(int64_t ns); > void qemu_clock_enable(QEMUClock *clock, bool enabled); > void qemu_clock_warp(QEMUClock *clock); > > @@ -63,6 +71,15 @@ int64_t cpu_get_ticks(void); > void cpu_enable_ticks(void); > void cpu_disable_ticks(void); > > +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; > +} > + It becomes much less disgusting if timeouts are made unsigned. I agree we can do it later. > static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb, > void *opaque) > { > diff --git a/qemu-timer.c b/qemu-timer.c > index b2d95e2..3dfbdbf 100644 > --- a/qemu-timer.c > +++ b/qemu-timer.c > @@ -40,10 +40,6 @@ > /***********************************************************/ > /* timers */ > > -#define QEMU_CLOCK_REALTIME 0 > -#define QEMU_CLOCK_VIRTUAL 1 > -#define QEMU_CLOCK_HOST 2 > - > struct QEMUClock { > QEMUTimer *active_timers; > > @@ -231,7 +227,7 @@ QEMUClock *rt_clock; > QEMUClock *vm_clock; > QEMUClock *host_clock; > > -static QEMUClock *qemu_new_clock(int type) > +QEMUClock *qemu_new_clock(int type) > { > QEMUClock *clock; > > @@ -243,6 +239,11 @@ static QEMUClock *qemu_new_clock(int type) > return clock; > } > > +void qemu_free_clock(QEMUClock *clock) > +{ > + g_free(clock); > +} > + > void qemu_clock_enable(QEMUClock *clock, bool enabled) > { > bool old = clock->enabled; > @@ -268,7 +269,7 @@ int64_t qemu_clock_deadline(QEMUClock *clock) > /* To avoid problems with overflow limit this to 2^32. */ > int64_t delta = INT32_MAX; > > - if (clock->active_timers) { > + if (clock->enabled && clock->active_timers) { > delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock); > } > if (delta < 0) { > @@ -277,6 +278,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) > { > -- > 1.7.9.5 >