aio / timers: Rearrange timer.h & make legacy functions call non-legacy

Rearrange timer.h so it is in order by function type.

Make legacy functions call non-legacy functions rather than vice-versa.

Convert cpus.c to use new API.

Signed-off-by: Alex Bligh <alex@alex.org.uk>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Alex Bligh 2013-08-21 16:03:02 +01:00 committed by Stefan Hajnoczi
parent 55a197dab4
commit 40daca54cd
11 changed files with 490 additions and 390 deletions

112
cpus.c
View File

@ -207,7 +207,7 @@ static void icount_adjust(void)
return; return;
} }
cur_time = cpu_get_clock(); cur_time = cpu_get_clock();
cur_icount = qemu_get_clock_ns(vm_clock); cur_icount = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
delta = cur_icount - cur_time; delta = cur_icount - cur_time;
/* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
if (delta > 0 if (delta > 0
@ -228,15 +228,16 @@ static void icount_adjust(void)
static void icount_adjust_rt(void *opaque) static void icount_adjust_rt(void *opaque)
{ {
qemu_mod_timer(icount_rt_timer, timer_mod(icount_rt_timer,
qemu_get_clock_ms(rt_clock) + 1000); qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
icount_adjust(); icount_adjust();
} }
static void icount_adjust_vm(void *opaque) static void icount_adjust_vm(void *opaque)
{ {
qemu_mod_timer(icount_vm_timer, timer_mod(icount_vm_timer,
qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10); qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() / 10);
icount_adjust(); icount_adjust();
} }
@ -252,22 +253,22 @@ static void icount_warp_rt(void *opaque)
} }
if (runstate_is_running()) { if (runstate_is_running()) {
int64_t clock = qemu_get_clock_ns(rt_clock); int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
int64_t warp_delta = clock - vm_clock_warp_start; int64_t warp_delta = clock - vm_clock_warp_start;
if (use_icount == 1) { if (use_icount == 1) {
qemu_icount_bias += warp_delta; qemu_icount_bias += warp_delta;
} else { } else {
/* /*
* In adaptive mode, do not let the vm_clock run too * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
* far ahead of real time. * far ahead of real time.
*/ */
int64_t cur_time = cpu_get_clock(); int64_t cur_time = cpu_get_clock();
int64_t cur_icount = qemu_get_clock_ns(vm_clock); int64_t cur_icount = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t delta = cur_time - cur_icount; int64_t delta = cur_time - cur_icount;
qemu_icount_bias += MIN(warp_delta, delta); qemu_icount_bias += MIN(warp_delta, delta);
} }
if (qemu_clock_expired(vm_clock)) { if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
qemu_clock_notify(vm_clock); qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
} }
} }
vm_clock_warp_start = -1; vm_clock_warp_start = -1;
@ -275,19 +276,19 @@ static void icount_warp_rt(void *opaque)
void qtest_clock_warp(int64_t dest) void qtest_clock_warp(int64_t dest)
{ {
int64_t clock = qemu_get_clock_ns(vm_clock); int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
assert(qtest_enabled()); assert(qtest_enabled());
while (clock < dest) { while (clock < dest) {
int64_t deadline = qemu_clock_deadline_ns_all(vm_clock); int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
int64_t warp = MIN(dest - clock, deadline); int64_t warp = MIN(dest - clock, deadline);
qemu_icount_bias += warp; qemu_icount_bias += warp;
qemu_run_timers(vm_clock); qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
clock = qemu_get_clock_ns(vm_clock); clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
} }
qemu_clock_notify(vm_clock); qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
} }
void qemu_clock_warp(QEMUClock *clock) void qemu_clock_warp(QEMUClockType type)
{ {
int64_t deadline; int64_t deadline;
@ -296,20 +297,20 @@ void qemu_clock_warp(QEMUClock *clock)
* applicable to other clocks. But a clock argument removes the * applicable to other clocks. But a clock argument removes the
* need for if statements all over the place. * need for if statements all over the place.
*/ */
if (clock != vm_clock || !use_icount) { if (type != QEMU_CLOCK_VIRTUAL || !use_icount) {
return; return;
} }
/* /*
* If the CPUs have been sleeping, advance the vm_clock timer now. This * If the CPUs have been sleeping, advance QEMU_CLOCK_VIRTUAL timer now.
* ensures that the deadline for the timer is computed correctly below. * This ensures that the deadline for the timer is computed correctly below.
* This also makes sure that the insn counter is synchronized before the * This also makes sure that the insn counter is synchronized before the
* CPU starts running, in case the CPU is woken by an event other than * CPU starts running, in case the CPU is woken by an event other than
* the earliest vm_clock timer. * the earliest QEMU_CLOCK_VIRTUAL timer.
*/ */
icount_warp_rt(NULL); icount_warp_rt(NULL);
if (!all_cpu_threads_idle() || !qemu_clock_has_timers(vm_clock)) { if (!all_cpu_threads_idle() || !qemu_clock_has_timers(QEMU_CLOCK_VIRTUAL)) {
qemu_del_timer(icount_warp_timer); timer_del(icount_warp_timer);
return; return;
} }
@ -318,12 +319,12 @@ void qemu_clock_warp(QEMUClock *clock)
return; return;
} }
vm_clock_warp_start = qemu_get_clock_ns(rt_clock); vm_clock_warp_start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
/* We want to use the earliest deadline from ALL vm_clocks */ /* We want to use the earliest deadline from ALL vm_clocks */
deadline = qemu_clock_deadline_ns_all(vm_clock); deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
/* Maintain prior (possibly buggy) behaviour where if no deadline /* Maintain prior (possibly buggy) behaviour where if no deadline
* was set (as there is no vm_clock timer) or it is more than * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
* INT32_MAX nanoseconds ahead, we still use INT32_MAX * INT32_MAX nanoseconds ahead, we still use INT32_MAX
* nanoseconds. * nanoseconds.
*/ */
@ -333,24 +334,25 @@ void qemu_clock_warp(QEMUClock *clock)
if (deadline > 0) { if (deadline > 0) {
/* /*
* Ensure the vm_clock proceeds even when the virtual CPU goes to * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to
* sleep. Otherwise, the CPU might be waiting for a future timer * sleep. Otherwise, the CPU might be waiting for a future timer
* interrupt to wake it up, but the interrupt never comes because * interrupt to wake it up, but the interrupt never comes because
* the vCPU isn't running any insns and thus doesn't advance the * the vCPU isn't running any insns and thus doesn't advance the
* vm_clock. * QEMU_CLOCK_VIRTUAL.
* *
* An extreme solution for this problem would be to never let VCPUs * An extreme solution for this problem would be to never let VCPUs
* sleep in icount mode if there is a pending vm_clock timer; rather * sleep in icount mode if there is a pending QEMU_CLOCK_VIRTUAL
* time could just advance to the next vm_clock event. Instead, we * timer; rather time could just advance to the next QEMU_CLOCK_VIRTUAL
* do stop VCPUs and only advance vm_clock after some "real" time, * event. Instead, we do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL
* (related to the time left until the next event) has passed. This * after some e"real" time, (related to the time left until the next
* rt_clock timer will do this. This avoids that the warps are too * event) has passed. The QEMU_CLOCK_REALTIME timer will do this.
* visible externally---for example, you will not be sending network * This avoids that the warps are visible externally; for example,
* packets continuously instead of every 100ms. * you will not be sending network packets continuously instead of
* every 100ms.
*/ */
qemu_mod_timer(icount_warp_timer, vm_clock_warp_start + deadline); timer_mod(icount_warp_timer, vm_clock_warp_start + deadline);
} else if (deadline == 0) { } else if (deadline == 0) {
qemu_clock_notify(vm_clock); qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
} }
} }
@ -374,7 +376,8 @@ void configure_icount(const char *option)
return; return;
} }
icount_warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL); icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
icount_warp_rt, NULL);
if (strcmp(option, "auto") != 0) { if (strcmp(option, "auto") != 0) {
icount_time_shift = strtol(option, NULL, 0); icount_time_shift = strtol(option, NULL, 0);
use_icount = 1; use_icount = 1;
@ -392,12 +395,15 @@ void configure_icount(const char *option)
the virtual time trigger catches emulated time passing too fast. the virtual time trigger catches emulated time passing too fast.
Realtime triggers occur even when idle, so use them less frequently Realtime triggers occur even when idle, so use them less frequently
than VM triggers. */ than VM triggers. */
icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL); icount_rt_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
qemu_mod_timer(icount_rt_timer, icount_adjust_rt, NULL);
qemu_get_clock_ms(rt_clock) + 1000); timer_mod(icount_rt_timer,
icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL); qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
qemu_mod_timer(icount_vm_timer, icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10); icount_adjust_vm, NULL);
timer_mod(icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() / 10);
} }
/***********************************************************/ /***********************************************************/
@ -746,7 +752,7 @@ static void qemu_tcg_wait_io_event(void)
while (all_cpu_threads_idle()) { while (all_cpu_threads_idle()) {
/* Start accounting real time to the virtual clock if the CPUs /* Start accounting real time to the virtual clock if the CPUs
are idle. */ are idle. */
qemu_clock_warp(vm_clock); qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
} }
@ -879,10 +885,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
tcg_exec_all(); tcg_exec_all();
if (use_icount) { if (use_icount) {
int64_t deadline = qemu_clock_deadline_ns_all(vm_clock); int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
if (deadline == 0) { if (deadline == 0) {
qemu_clock_notify(vm_clock); qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
} }
} }
qemu_tcg_wait_io_event(); qemu_tcg_wait_io_event();
@ -1001,7 +1007,7 @@ void pause_all_vcpus(void)
{ {
CPUState *cpu = first_cpu; CPUState *cpu = first_cpu;
qemu_clock_enable(vm_clock, false); qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
while (cpu) { while (cpu) {
cpu->stop = true; cpu->stop = true;
qemu_cpu_kick(cpu); qemu_cpu_kick(cpu);
@ -1042,7 +1048,7 @@ void resume_all_vcpus(void)
{ {
CPUState *cpu = first_cpu; CPUState *cpu = first_cpu;
qemu_clock_enable(vm_clock, true); qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
while (cpu) { while (cpu) {
cpu_resume(cpu); cpu_resume(cpu);
cpu = cpu->next_cpu; cpu = cpu->next_cpu;
@ -1166,10 +1172,10 @@ static int tcg_cpu_exec(CPUArchState *env)
qemu_icount -= (env->icount_decr.u16.low + env->icount_extra); qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
env->icount_decr.u16.low = 0; env->icount_decr.u16.low = 0;
env->icount_extra = 0; env->icount_extra = 0;
deadline = qemu_clock_deadline_ns_all(vm_clock); deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
/* Maintain prior (possibly buggy) behaviour where if no deadline /* Maintain prior (possibly buggy) behaviour where if no deadline
* was set (as there is no vm_clock timer) or it is more than * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
* INT32_MAX nanoseconds ahead, we still use INT32_MAX * INT32_MAX nanoseconds ahead, we still use INT32_MAX
* nanoseconds. * nanoseconds.
*/ */
@ -1203,8 +1209,8 @@ static void tcg_exec_all(void)
{ {
int r; int r;
/* Account partial waits to the vm_clock. */ /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
qemu_clock_warp(vm_clock); qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
if (next_cpu == NULL) { if (next_cpu == NULL) {
next_cpu = first_cpu; next_cpu = first_cpu;
@ -1213,7 +1219,7 @@ static void tcg_exec_all(void)
CPUState *cpu = next_cpu; CPUState *cpu = next_cpu;
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
qemu_clock_enable(vm_clock, qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
(cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
if (cpu_can_run(cpu)) { if (cpu_can_run(cpu)) {

View File

@ -263,7 +263,7 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
return ret; return ret;
} }
qemu_get_timer(f, s->ar.tmr.timer); timer_get(f, s->ar.tmr.timer);
qemu_get_sbe64s(f, &s->ar.tmr.overflow_time); qemu_get_sbe64s(f, &s->ar.tmr.overflow_time);
qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts); qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts);

View File

@ -449,7 +449,7 @@ static void tsc2005_save(QEMUFile *f, void *opaque)
qemu_put_be16s(f, &s->dav); qemu_put_be16s(f, &s->dav);
qemu_put_be16s(f, &s->data); qemu_put_be16s(f, &s->data);
qemu_put_timer(f, s->timer); timer_put(f, s->timer);
qemu_put_byte(f, s->enabled); qemu_put_byte(f, s->enabled);
qemu_put_byte(f, s->host_mode); qemu_put_byte(f, s->host_mode);
qemu_put_byte(f, s->function); qemu_put_byte(f, s->function);
@ -490,7 +490,7 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_be16s(f, &s->dav); qemu_get_be16s(f, &s->dav);
qemu_get_be16s(f, &s->data); qemu_get_be16s(f, &s->data);
qemu_get_timer(f, s->timer); timer_get(f, s->timer);
s->enabled = qemu_get_byte(f); s->enabled = qemu_get_byte(f);
s->host_mode = qemu_get_byte(f); s->host_mode = qemu_get_byte(f);
s->function = qemu_get_byte(f); s->function = qemu_get_byte(f);

View File

@ -1020,7 +1020,7 @@ static void tsc210x_save(QEMUFile *f, void *opaque)
qemu_put_byte(f, s->irq); qemu_put_byte(f, s->irq);
qemu_put_be16s(f, &s->dav); qemu_put_be16s(f, &s->dav);
qemu_put_timer(f, s->timer); timer_put(f, s->timer);
qemu_put_byte(f, s->enabled); qemu_put_byte(f, s->enabled);
qemu_put_byte(f, s->host_mode); qemu_put_byte(f, s->host_mode);
qemu_put_byte(f, s->function); qemu_put_byte(f, s->function);
@ -1066,7 +1066,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
s->irq = qemu_get_byte(f); s->irq = qemu_get_byte(f);
qemu_get_be16s(f, &s->dav); qemu_get_be16s(f, &s->dav);
qemu_get_timer(f, s->timer); timer_get(f, s->timer);
s->enabled = qemu_get_byte(f); s->enabled = qemu_get_byte(f);
s->host_mode = qemu_get_byte(f); s->host_mode = qemu_get_byte(f);
s->function = qemu_get_byte(f); s->function = qemu_get_byte(f);

View File

@ -363,7 +363,7 @@ void cpu_put_timer(QEMUFile *f, CPUTimer *s)
qemu_put_be64s(f, &s->disabled_mask); qemu_put_be64s(f, &s->disabled_mask);
qemu_put_sbe64s(f, &s->clock_offset); qemu_put_sbe64s(f, &s->clock_offset);
qemu_put_timer(f, s->qtimer); timer_put(f, s->qtimer);
} }
void cpu_get_timer(QEMUFile *f, CPUTimer *s) void cpu_get_timer(QEMUFile *f, CPUTimer *s)
@ -373,7 +373,7 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
qemu_get_be64s(f, &s->disabled_mask); qemu_get_be64s(f, &s->disabled_mask);
qemu_get_sbe64s(f, &s->clock_offset); qemu_get_sbe64s(f, &s->clock_offset);
qemu_get_timer(f, s->qtimer); timer_get(f, s->qtimer);
} }
static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu, static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,

View File

@ -23,16 +23,12 @@
* machine is stopped. The real time clock has a frequency of 1000 * machine is stopped. The real time clock has a frequency of 1000
* Hz. * Hz.
* *
* Formerly rt_clock
*
* @QEMU_CLOCK_VIRTUAL: virtual clock * @QEMU_CLOCK_VIRTUAL: virtual clock
* *
* The virtual clock is only run during the emulation. It is stopped * The virtual clock is only run during the emulation. It is stopped
* when the virtual machine is stopped. Virtual timers use a high * when the virtual machine is stopped. Virtual timers use a high
* precision clock, usually cpu cycles (use ticks_per_sec). * precision clock, usually cpu cycles (use ticks_per_sec).
* *
* Formerly vm_clock
*
* @QEMU_CLOCK_HOST: host clock * @QEMU_CLOCK_HOST: host clock
* *
* The host clock should be use for device models that emulate accurate * The host clock should be use for device models that emulate accurate
@ -40,8 +36,6 @@
* is suspended, and it will reflect system time changes the host may * is suspended, and it will reflect system time changes the host may
* undergo (e.g. due to NTP). The host clock has the same precision as * undergo (e.g. due to NTP). The host clock has the same precision as
* the virtual clock. * the virtual clock.
*
* Formerly host_clock
*/ */
typedef enum { typedef enum {
@ -73,6 +67,10 @@ struct QEMUTimer {
extern QEMUTimerListGroup main_loop_tlg; extern QEMUTimerListGroup main_loop_tlg;
extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX]; extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
/*
* QEMUClock & QEMUClockType
*/
/** /**
* qemu_clock_ptr: * qemu_clock_ptr:
* @type: type of clock * @type: type of clock
@ -86,23 +84,6 @@ static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
return qemu_clocks[type]; return qemu_clocks[type];
} }
/* These three clocks are maintained here with separate variable
* names for compatibility only.
*/
#define rt_clock (qemu_clock_ptr(QEMU_CLOCK_REALTIME))
#define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
#define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
/**
* qemu_get_clock_ns:
* @clock: the clock to operate on
*
* Get the nanosecond value of a clock
*
* Returns: the clock value in nanoseconds
*/
int64_t qemu_get_clock_ns(QEMUClock *clock);
/** /**
* qemu_clock_get_ns; * qemu_clock_get_ns;
* @type: the clock type * @type: the clock type
@ -112,10 +93,7 @@ int64_t qemu_get_clock_ns(QEMUClock *clock);
* *
* Returns: the clock value in nanoseconds * Returns: the clock value in nanoseconds
*/ */
static inline int64_t qemu_clock_get_ns(QEMUClockType type) int64_t qemu_clock_get_ns(QEMUClockType type);
{
return qemu_get_clock_ns(qemu_clock_ptr(type));
}
/** /**
* qemu_clock_get_ms; * qemu_clock_get_ms;
@ -147,7 +125,7 @@ static inline int64_t qemu_clock_get_us(QEMUClockType type)
/** /**
* qemu_clock_has_timers: * qemu_clock_has_timers:
* @clock: the clock to operate on * @type: the clock type
* *
* Determines whether a clock's default timer list * Determines whether a clock's default timer list
* has timers attached * has timers attached
@ -155,11 +133,11 @@ static inline int64_t qemu_clock_get_us(QEMUClockType type)
* Returns: true if the clock's default timer list * Returns: true if the clock's default timer list
* has timers attached * has timers attached
*/ */
bool qemu_clock_has_timers(QEMUClock *clock); bool qemu_clock_has_timers(QEMUClockType type);
/** /**
* qemu_clock_expired: * qemu_clock_expired:
* @clock: the clock to operate on * @type: the clock type
* *
* Determines whether a clock's default timer list * Determines whether a clock's default timer list
* has an expired clock. * has an expired clock.
@ -167,23 +145,11 @@ bool qemu_clock_has_timers(QEMUClock *clock);
* Returns: true if the clock's default timer list has * Returns: true if the clock's default timer list has
* an expired timer * an expired timer
*/ */
bool qemu_clock_expired(QEMUClock *clock); bool qemu_clock_expired(QEMUClockType type);
/**
* qemu_clock_deadline_ns:
* @clock: the clock to operate on
*
* Calculate the timeout of the earliest expiring timer
* on the default timer list associated with the clock
* 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_clock_use_for_deadline: * qemu_clock_use_for_deadline:
* @clock: the clock to operate on * @type: the clock type
* *
* Determine whether a clock should be used for deadline * Determine whether a clock should be used for deadline
* calculations. Some clocks, for instance vm_clock with * calculations. Some clocks, for instance vm_clock with
@ -195,11 +161,11 @@ int64_t qemu_clock_deadline_ns(QEMUClock *clock);
* Returns: true if the clock runs in nanoseconds and * Returns: true if the clock runs in nanoseconds and
* should be used for a deadline. * should be used for a deadline.
*/ */
bool qemu_clock_use_for_deadline(QEMUClock *clock); bool qemu_clock_use_for_deadline(QEMUClockType type);
/** /**
* qemu_clock_use_for_deadline: * qemu_clock_deadline_ns_all:
* @clock: the clock to operate on * @type: the clock type
* *
* Calculate the deadline across all timer lists associated * Calculate the deadline across all timer lists associated
* with a clock (as opposed to just the default one) * with a clock (as opposed to just the default one)
@ -207,26 +173,90 @@ bool qemu_clock_use_for_deadline(QEMUClock *clock);
* *
* Returns: time until expiry in nanoseconds or -1 * Returns: time until expiry in nanoseconds or -1
*/ */
int64_t qemu_clock_deadline_ns_all(QEMUClock *clock); int64_t qemu_clock_deadline_ns_all(QEMUClockType type);
/** /**
* qemu_clock_get_main_loop_timerlist: * qemu_clock_get_main_loop_timerlist:
* @clock: the clock to operate on * @type: the clock type
* *
* Return the default timer list assocatiated with a clock. * Return the default timer list assocatiated with a clock.
* *
* Returns: the default timer list * Returns: the default timer list
*/ */
QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock); QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type);
/** /**
* qemu_clock_nofify: * qemu_clock_nofify:
* @clock: the clock to operate on * @type: the clock type
* *
* Call the notifier callback connected with the default timer * Call the notifier callback connected with the default timer
* list linked to the clock, or qemu_notify() if none. * list linked to the clock, or qemu_notify() if none.
*/ */
void qemu_clock_notify(QEMUClock *clock); void qemu_clock_notify(QEMUClockType type);
/**
* qemu_clock_enable:
* @type: the clock type
* @enabled: true to enable, false to disable
*
* Enable or disable a clock
*/
void qemu_clock_enable(QEMUClockType type, bool enabled);
/**
* qemu_clock_warp:
* @type: the clock type
*
* Warp a clock to a new value
*/
void qemu_clock_warp(QEMUClockType type);
/**
* qemu_clock_register_reset_notifier:
* @type: the clock type
* @notifier: the notifier function
*
* Register a notifier function to call when the clock
* concerned is reset.
*/
void qemu_clock_register_reset_notifier(QEMUClockType type,
Notifier *notifier);
/**
* qemu_clock_unregister_reset_notifier:
* @type: the clock type
* @notifier: the notifier function
*
* Unregister a notifier function to call when the clock
* concerned is reset.
*/
void qemu_clock_unregister_reset_notifier(QEMUClockType type,
Notifier *notifier);
/**
* qemu_clock_run_timers:
* @type: clock on which to operate
*
* Run all the timers associated with the default timer list
* of a clock.
*
* Returns: true if any timer ran.
*/
bool qemu_clock_run_timers(QEMUClockType type);
/**
* qemu_clock_run_all_timers:
*
* Run all the timers associated with the default timer list
* of every clock.
*
* Returns: true if any timer ran.
*/
bool qemu_clock_run_all_timers(void);
/*
* QEMUTimerList
*/
/** /**
* timerlist_new: * timerlist_new:
@ -286,14 +316,15 @@ bool timerlist_expired(QEMUTimerList *timer_list);
int64_t timerlist_deadline_ns(QEMUTimerList *timer_list); int64_t timerlist_deadline_ns(QEMUTimerList *timer_list);
/** /**
* timerlist_getclock: * timerlist_get_clock:
* @timer_list: the timer list to operate on * @timer_list: the timer list to operate on
* *
* Determine the clock associated with a timer list. * Determine the clock type associated with a timer list.
* *
* Returns: the clock associated with the timer list. * Returns: the clock type associated with the
* timer list.
*/ */
QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list); QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list);
/** /**
* timerlist_run_timers: * timerlist_run_timers:
@ -313,6 +344,10 @@ bool timerlist_run_timers(QEMUTimerList *timer_list);
*/ */
void timerlist_notify(QEMUTimerList *timer_list); void timerlist_notify(QEMUTimerList *timer_list);
/*
* QEMUTimerListGroup
*/
/** /**
* timerlistgroup_init: * timerlistgroup_init:
* @tlg: the timer list group * @tlg: the timer list group
@ -363,82 +398,9 @@ bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
*/ */
int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg); int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
/** /*
* qemu_timeout_ns_to_ms: * QEMUTimer
* @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);
/**
* qemu_poll_ns:
* @fds: Array of file descriptors
* @nfds: number of file descriptors
* @timeout: timeout in nanoseconds
*
* Perform a poll like g_poll but with a timeout in nanoseconds.
* See g_poll documentation for further details.
*
* Returns: number of fds ready
*/
int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
/**
* qemu_clock_enable:
* @clock: the clock to operate on
* @enabled: true to enable, false to disable
*
* Enable or disable a clock
*/
void qemu_clock_enable(QEMUClock *clock, bool enabled);
/**
* qemu_clock_warp:
* @clock: the clock to operate on
*
* Warp a clock to a new value
*/
void qemu_clock_warp(QEMUClock *clock);
/**
* qemu_register_clock_reset_notifier:
* @clock: the clock to operate on
* @notifier: the notifier function
*
* Register a notifier function to call when the clock
* concerned is reset.
*/
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
/**
* qemu_unregister_clock_reset_notifier:
* @clock: the clock to operate on
* @notifier: the notifier function
*
* Unregister a notifier function to call when the clock
* concerned is reset.
*/
void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
Notifier *notifier);
/**
* qemu_new_timer:
* @clock: the clock to operate on
* @scale: the scale of the clock
* @cb: the callback function to call when the timer expires
* @opaque: an opaque pointer to pass to the callback
*
* Produce a new timer attached to clock @clock. This is a legacy
* function. Use timer_new instead.
*
* Returns: a pointer to the new timer allocated.
*/
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
QEMUTimerCB *cb, void *opaque);
/** /**
* timer_init: * timer_init:
@ -502,102 +464,94 @@ static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
} }
/** /**
* qemu_free_timer: * timer_new_ns:
* @ts: the timer to operate on * @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
* *
* free the timer @ts. @ts must not be active. * Create a new timer with nanosecond scale on the default timer list
* associated with the clock.
* *
* This is a legacy function. Use timer_free instead. * Returns: a pointer to the newly created timer
*/ */
void qemu_free_timer(QEMUTimer *ts); static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
void *opaque)
{
return timer_new(type, SCALE_NS, cb, opaque);
}
/**
* timer_new_us:
* @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
* Create a new timer with microsecond scale on the default timer list
* associated with the clock.
*
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
void *opaque)
{
return timer_new(type, SCALE_US, cb, opaque);
}
/**
* timer_new_ms:
* @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
* Create a new timer with millisecond scale on the default timer list
* associated with the clock.
*
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
void *opaque)
{
return timer_new(type, SCALE_MS, cb, opaque);
}
/** /**
* timer_free: * timer_free:
* @ts: the timer to operate on * @ts: the timer
* *
* free the timer @ts. @ts must not be active. * Free a timer (it must not be on the active list)
*/ */
static inline void timer_free(QEMUTimer *ts) void timer_free(QEMUTimer *ts);
{
qemu_free_timer(ts);
}
/**
* qemu_del_timer:
* @ts: the timer to operate on
*
* Delete a timer. This makes it inactive. It does not free
* memory.
*
* This is a legacy function. Use timer_del instead.
*/
void qemu_del_timer(QEMUTimer *ts);
/** /**
* timer_del: * timer_del:
* @ts: the timer to operate on * @ts: the timer
* *
* Delete a timer. This makes it inactive. It does not free * Delete a timer from the active list.
* memory.
*/ */
static inline void timer_del(QEMUTimer *ts) void timer_del(QEMUTimer *ts);
{
qemu_del_timer(ts);
}
/**
* qemu_mod_timer_ns:
* @ts: the timer to operate on
* @expire_time: the expiry time in nanoseconds
*
* Modify a timer such that the expiry time is @expire_time
* as measured in nanoseconds
*
* This is a legacy function. Use timer_mod_ns.
*/
void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
/** /**
* timer_mod_ns: * timer_mod_ns:
* @ts: the timer to operate on * @ts: the timer
* @expire_time: the expiry time in nanoseconds * @expire_time: the expiry time in nanoseconds
* *
* Modify a timer such that the expiry time is @expire_time * Modify a timer to expire at @expire_time
* as measured in nanoseconds
*/ */
static inline void timer_mod_ns(QEMUTimer *ts, int64_t expire_time) void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
{
qemu_mod_timer_ns(ts, expire_time);
}
/**
* qemu_mod_timer:
* @ts: the timer to operate on
* @expire_time: the expiry time
*
* Modify a timer such that the expiry time is @expire_time
* as measured in the timer's scale
*
* This is a legacy function. Use timer_mod.
*/
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
/** /**
* timer_mod: * timer_mod:
* @ts: the timer to operate on * @ts: the timer
* @expire_time: the expiry time in nanoseconds * @expire_time: the expire time in the units associated with the timer
* *
* Modify a timer such that the expiry time is @expire_time * Modify a timer to expiry at @expire_time, taking into
* as measured in the timer's scale * account the scale associated with the timer.
*/ */
static inline void timer_mod(QEMUTimer *ts, int64_t expire_time) void timer_mod(QEMUTimer *ts, int64_t expire_timer);
{
qemu_mod_timer(ts, expire_time);
}
/** /**
* timer_pending: * timer_pending:
* @ts: the timer to operate on * @ts: the timer
* *
* Determines whether a timer is pending (i.e. is on the * Determines whether a timer is pending (i.e. is on the
* active list of timers, whether or not it has not yet expired). * active list of timers, whether or not it has not yet expired).
@ -608,7 +562,7 @@ bool timer_pending(QEMUTimer *ts);
/** /**
* timer_expired: * timer_expired:
* @ts: the timer to operate on * @ts: the timer
* *
* Determines whether a timer has expired. * Determines whether a timer has expired.
* *
@ -618,45 +572,57 @@ bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
/** /**
* timer_expire_time_ns: * timer_expire_time_ns:
* @ts: the timer to operate on * @ts: the timer
* *
* Determines the time until a timer expires * Determine the expiry time of a timer
* *
* Returns: the time (in nanoseonds) until a timer expires * Returns: the expiry time in nanoseconds
*/ */
uint64_t timer_expire_time_ns(QEMUTimer *ts); uint64_t timer_expire_time_ns(QEMUTimer *ts);
/** /**
* qemu_run_timers: * timer_get:
* @clock: clock on which to operate * @f: the file
* @ts: the timer
* *
* Run all the timers associated with the default timer list * Read a timer @ts from a file @f
* of a clock.
*
* Returns: true if any timer ran.
*/ */
bool qemu_run_timers(QEMUClock *clock); void timer_get(QEMUFile *f, QEMUTimer *ts);
/** /**
* qemu_run_all_timers: * timer_put:
* * @f: the file
* Run all the timers associated with the default timer list * @ts: the timer
* of every clock. */
* void timer_put(QEMUFile *f, QEMUTimer *ts);
* Returns: true if any timer ran.
/*
* General utility functions
*/ */
bool qemu_run_all_timers(void);
/** /**
* initclocks: * qemu_timeout_ns_to_ms:
* @ns: nanosecond timeout value
* *
* Initialise the clock & timer infrastructure * Convert a nanosecond timeout value (or -1) to
* a millisecond value (or -1), always rounding up.
*
* Returns: millisecond timeout value
*/ */
void init_clocks(void); int qemu_timeout_ns_to_ms(int64_t ns);
int64_t cpu_get_ticks(void); /**
void cpu_enable_ticks(void); * qemu_poll_ns:
void cpu_disable_ticks(void); * @fds: Array of file descriptors
* @nfds: number of file descriptors
* @timeout: timeout in nanoseconds
*
* Perform a poll like g_poll but with a timeout in nanoseconds.
* See g_poll documentation for further details.
*
* Returns: number of fds ready
*/
int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
/** /**
* qemu_soonest_timeout: * qemu_soonest_timeout:
@ -678,6 +644,163 @@ static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
} }
/** /**
* initclocks:
*
* Initialise the clock & timer infrastructure
*/
void init_clocks(void);
int64_t cpu_get_ticks(void);
void cpu_enable_ticks(void);
void cpu_disable_ticks(void);
static inline int64_t get_ticks_per_sec(void)
{
return 1000000000LL;
}
/**************************************************
* LEGACY API SECTION
*
* All these calls will be deleted in due course
*/
/* These three clocks are maintained here with separate variable
* names for compatibility only.
*/
#define rt_clock (qemu_clock_ptr(QEMU_CLOCK_REALTIME))
#define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
#define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
/** LEGACY
* qemu_get_clock_ns:
* @clock: the clock to operate on
*
* Get the nanosecond value of a clock
*
* Returns: the clock value in nanoseconds
*/
int64_t qemu_get_clock_ns(QEMUClock *clock);
/** LEGACY
* qemu_get_clock_ms:
* @clock: the clock to operate on
*
* Get the millisecond value of a clock
*
* Returns: the clock value in milliseconds
*/
static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
{
return qemu_get_clock_ns(clock) / SCALE_MS;
}
/** LEGACY
* qemu_register_clock_reset_notifier:
* @clock: the clock to operate on
* @notifier: the notifier function
*
* Register a notifier function to call when the clock
* concerned is reset.
*/
void qemu_register_clock_reset_notifier(QEMUClock *clock,
Notifier *notifier);
/** LEGACY
* qemu_unregister_clock_reset_notifier:
* @clock: the clock to operate on
* @notifier: the notifier function
*
* Unregister a notifier function to call when the clock
* concerned is reset.
*/
void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
Notifier *notifier);
/** LEGACY
* qemu_new_timer:
* @clock: the clock to operate on
* @scale: the scale of the clock
* @cb: the callback function to call when the timer expires
* @opaque: an opaque pointer to pass to the callback
*
* Produce a new timer attached to clock @clock. This is a legacy
* function. Use timer_new instead.
*
* Returns: a pointer to the new timer allocated.
*/
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
QEMUTimerCB *cb, void *opaque);
/** LEGACY
* qemu_free_timer:
* @ts: the timer to operate on
*
* free the timer @ts. @ts must not be active.
*
* This is a legacy function. Use timer_free instead.
*/
static inline void qemu_free_timer(QEMUTimer *ts)
{
timer_free(ts);
}
/** LEGACY
* qemu_del_timer:
* @ts: the timer to operate on
*
* Delete a timer. This makes it inactive. It does not free
* memory.
*
* This is a legacy function. Use timer_del instead.
*/
static inline void qemu_del_timer(QEMUTimer *ts)
{
timer_del(ts);
}
/** LEGACY
* qemu_mod_timer_ns:
* @ts: the timer to operate on
* @expire_time: the expiry time in nanoseconds
*
* Modify a timer such that the expiry time is @expire_time
* as measured in nanoseconds
*
* This is a legacy function. Use timer_mod_ns.
*/
static inline void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
{
timer_mod_ns(ts, expire_time);
}
/** LEGACY
* qemu_mod_timer:
* @ts: the timer to operate on
* @expire_time: the expiry time
*
* Modify a timer such that the expiry time is @expire_time
* as measured in the timer's scale
*
* This is a legacy function. Use timer_mod.
*/
static inline void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
{
timer_mod(ts, expire_time);
}
/** LEGACY
* qemu_run_timers:
* @clock: clock on which to operate
*
* Run all the timers associated with the default timer list
* of a clock.
*
* Returns: true if any timer ran.
*/
bool qemu_run_timers(QEMUClock *clock);
/** LEGACY
* qemu_new_timer_ns: * qemu_new_timer_ns:
* @clock: the clock to associate with the timer * @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires * @callback: the callback to call when the timer expires
@ -694,24 +817,7 @@ static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
return qemu_new_timer(clock, SCALE_NS, cb, opaque); return qemu_new_timer(clock, SCALE_NS, cb, opaque);
} }
/** /** LEGACY
* timer_new_ns:
* @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
* Create a new timer with nanosecond scale on the default timer list
* associated with the clock.
*
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
void *opaque)
{
return timer_new(type, SCALE_NS, cb, opaque);
}
/**
* qemu_new_timer_us: * qemu_new_timer_us:
* @clock: the clock to associate with the timer * @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires * @callback: the callback to call when the timer expires
@ -729,24 +835,7 @@ static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
return qemu_new_timer(clock, SCALE_US, cb, opaque); return qemu_new_timer(clock, SCALE_US, cb, opaque);
} }
/** /** LEGACY
* timer_new_us:
* @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
* Create a new timer with microsecond scale on the default timer list
* associated with the clock.
*
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
void *opaque)
{
return timer_new(type, SCALE_US, cb, opaque);
}
/**
* qemu_new_timer_ms: * qemu_new_timer_ms:
* @clock: the clock to associate with the timer * @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires * @callback: the callback to call when the timer expires
@ -764,32 +853,14 @@ static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock,
return qemu_new_timer(clock, SCALE_MS, cb, opaque); return qemu_new_timer(clock, SCALE_MS, cb, opaque);
} }
/** /****************************************************
* timer_new_ms: * END OF LEGACY API SECTION
* @clock: the clock to associate with the timer
* @callback: the callback to call when the timer expires
* @opaque: the opaque pointer to pass to the callback
*
* Create a new timer with millisecond scale on the default timer list
* associated with the clock.
*
* Returns: a pointer to the newly created timer
*/ */
static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
void *opaque)
{
return timer_new(type, SCALE_MS, cb, opaque);
}
static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
{
return qemu_get_clock_ns(clock) / SCALE_MS;
}
static inline int64_t get_ticks_per_sec(void) /*
{ * Low level clock functions
return 1000000000LL; */
}
/* real time host monotonic timer */ /* real time host monotonic timer */
static inline int64_t get_clock_realtime(void) static inline int64_t get_clock_realtime(void)
@ -834,9 +905,6 @@ static inline int64_t get_clock(void)
} }
#endif #endif
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
/* icount */ /* icount */
int64_t cpu_get_icount(void); int64_t cpu_get_icount(void);
int64_t cpu_get_clock(void); int64_t cpu_get_clock(void);

View File

@ -487,7 +487,7 @@ int main_loop_wait(int nonblocking)
slirp_pollfds_poll(gpollfds, (ret < 0)); slirp_pollfds_poll(gpollfds, (ret < 0));
#endif #endif
qemu_run_all_timers(); qemu_clock_run_all_timers();
return ret; return ret;
} }

View File

@ -132,25 +132,27 @@ static QEMUClock *qemu_clock_new(QEMUClockType type)
return clock; return clock;
} }
bool qemu_clock_use_for_deadline(QEMUClock *clock) bool qemu_clock_use_for_deadline(QEMUClockType type)
{ {
return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL)); return !(use_icount && (type == QEMU_CLOCK_VIRTUAL));
} }
void qemu_clock_notify(QEMUClock *clock) void qemu_clock_notify(QEMUClockType type)
{ {
QEMUTimerList *timer_list; QEMUTimerList *timer_list;
QEMUClock *clock = qemu_clock_ptr(type);
QLIST_FOREACH(timer_list, &clock->timerlists, list) { QLIST_FOREACH(timer_list, &clock->timerlists, list) {
timerlist_notify(timer_list); timerlist_notify(timer_list);
} }
} }
void qemu_clock_enable(QEMUClock *clock, bool enabled) void qemu_clock_enable(QEMUClockType type, bool enabled)
{ {
QEMUClock *clock = qemu_clock_ptr(type);
bool old = clock->enabled; bool old = clock->enabled;
clock->enabled = enabled; clock->enabled = enabled;
if (enabled && !old) { if (enabled && !old) {
qemu_clock_notify(clock); qemu_clock_notify(type);
} }
} }
@ -159,21 +161,23 @@ bool timerlist_has_timers(QEMUTimerList *timer_list)
return !!timer_list->active_timers; return !!timer_list->active_timers;
} }
bool qemu_clock_has_timers(QEMUClock *clock) bool qemu_clock_has_timers(QEMUClockType type)
{ {
return timerlist_has_timers(clock->main_loop_timerlist); return timerlist_has_timers(
qemu_clock_ptr(type)->main_loop_timerlist);
} }
bool timerlist_expired(QEMUTimerList *timer_list) bool timerlist_expired(QEMUTimerList *timer_list)
{ {
return (timer_list->active_timers && return (timer_list->active_timers &&
timer_list->active_timers->expire_time < timer_list->active_timers->expire_time <
qemu_get_clock_ns(timer_list->clock)); qemu_clock_get_ns(timer_list->clock->type));
} }
bool qemu_clock_expired(QEMUClock *clock) bool qemu_clock_expired(QEMUClockType type)
{ {
return timerlist_expired(clock->main_loop_timerlist); return timerlist_expired(
qemu_clock_ptr(type)->main_loop_timerlist);
} }
/* /*
@ -190,7 +194,7 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
} }
delta = timer_list->active_timers->expire_time - delta = timer_list->active_timers->expire_time -
qemu_get_clock_ns(timer_list->clock); qemu_clock_get_ns(timer_list->clock->type);
if (delta <= 0) { if (delta <= 0) {
return 0; return 0;
@ -199,20 +203,16 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
return delta; return delta;
} }
int64_t qemu_clock_deadline_ns(QEMUClock *clock)
{
return timerlist_deadline_ns(clock->main_loop_timerlist);
}
/* Calculate the soonest deadline across all timerlists attached /* Calculate the soonest deadline across all timerlists attached
* to the clock. This is used for the icount timeout so we * to the clock. This is used for the icount timeout so we
* ignore whether or not the clock should be used in deadline * ignore whether or not the clock should be used in deadline
* calculations. * calculations.
*/ */
int64_t qemu_clock_deadline_ns_all(QEMUClock *clock) int64_t qemu_clock_deadline_ns_all(QEMUClockType type)
{ {
int64_t deadline = -1; int64_t deadline = -1;
QEMUTimerList *timer_list; QEMUTimerList *timer_list;
QEMUClock *clock = qemu_clock_ptr(type);
QLIST_FOREACH(timer_list, &clock->timerlists, list) { QLIST_FOREACH(timer_list, &clock->timerlists, list) {
deadline = qemu_soonest_timeout(deadline, deadline = qemu_soonest_timeout(deadline,
timerlist_deadline_ns(timer_list)); timerlist_deadline_ns(timer_list));
@ -220,14 +220,14 @@ int64_t qemu_clock_deadline_ns_all(QEMUClock *clock)
return deadline; return deadline;
} }
QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list) QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list)
{ {
return timer_list->clock; return timer_list->clock->type;
} }
QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock) QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type)
{ {
return clock->main_loop_timerlist; return qemu_clock_ptr(type)->main_loop_timerlist;
} }
void timerlist_notify(QEMUTimerList *timer_list) void timerlist_notify(QEMUTimerList *timer_list)
@ -304,13 +304,13 @@ QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
scale, cb, opaque); scale, cb, opaque);
} }
void qemu_free_timer(QEMUTimer *ts) void timer_free(QEMUTimer *ts)
{ {
g_free(ts); g_free(ts);
} }
/* stop a timer, but do not dealloc it */ /* stop a timer, but do not dealloc it */
void qemu_del_timer(QEMUTimer *ts) void timer_del(QEMUTimer *ts)
{ {
QEMUTimer **pt, *t; QEMUTimer **pt, *t;
@ -331,11 +331,11 @@ void qemu_del_timer(QEMUTimer *ts)
/* modify the current timer so that it will be fired when current_time /* modify the current timer so that it will be fired when current_time
>= expire_time. The corresponding callback will be called. */ >= expire_time. The corresponding callback will be called. */
void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time) void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
{ {
QEMUTimer **pt, *t; QEMUTimer **pt, *t;
qemu_del_timer(ts); timer_del(ts);
/* add the timer in the sorted list */ /* add the timer in the sorted list */
/* NOTE: this code must be signal safe because /* NOTE: this code must be signal safe because
@ -355,14 +355,14 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
/* Rearm if necessary */ /* Rearm if necessary */
if (pt == &ts->timer_list->active_timers) { if (pt == &ts->timer_list->active_timers) {
/* Interrupt execution to force deadline recalculation. */ /* Interrupt execution to force deadline recalculation. */
qemu_clock_warp(ts->timer_list->clock); qemu_clock_warp(ts->timer_list->clock->type);
timerlist_notify(ts->timer_list); timerlist_notify(ts->timer_list);
} }
} }
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) void timer_mod(QEMUTimer *ts, int64_t expire_time)
{ {
qemu_mod_timer_ns(ts, expire_time * ts->scale); timer_mod_ns(ts, expire_time * ts->scale);
} }
bool timer_pending(QEMUTimer *ts) bool timer_pending(QEMUTimer *ts)
@ -391,7 +391,7 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
return progress; return progress;
} }
current_time = qemu_get_clock_ns(timer_list->clock); current_time = qemu_clock_get_ns(timer_list->clock->type);
for(;;) { for(;;) {
ts = timer_list->active_timers; ts = timer_list->active_timers;
if (!timer_expired_ns(ts, current_time)) { if (!timer_expired_ns(ts, current_time)) {
@ -408,9 +408,14 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
return progress; return progress;
} }
bool qemu_clock_run_timers(QEMUClockType type)
{
return timerlist_run_timers(qemu_clock_ptr(type)->main_loop_timerlist);
}
bool qemu_run_timers(QEMUClock *clock) bool qemu_run_timers(QEMUClock *clock)
{ {
return timerlist_run_timers(clock->main_loop_timerlist); return qemu_clock_run_timers(clock->type);
} }
void timerlistgroup_init(QEMUTimerListGroup *tlg, void timerlistgroup_init(QEMUTimerListGroup *tlg,
@ -445,7 +450,7 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
int64_t deadline = -1; int64_t deadline = -1;
QEMUClockType type; QEMUClockType type;
for (type = 0; type < QEMU_CLOCK_MAX; type++) { for (type = 0; type < QEMU_CLOCK_MAX; type++) {
if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) { if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) {
deadline = qemu_soonest_timeout(deadline, deadline = qemu_soonest_timeout(deadline,
timerlist_deadline_ns( timerlist_deadline_ns(
tlg->tl[type])); tlg->tl[type]));
@ -454,11 +459,12 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
return deadline; return deadline;
} }
int64_t qemu_get_clock_ns(QEMUClock *clock) int64_t qemu_clock_get_ns(QEMUClockType type)
{ {
int64_t now, last; int64_t now, last;
QEMUClock *clock = qemu_clock_ptr(type);
switch(clock->type) { switch (type) {
case QEMU_CLOCK_REALTIME: case QEMU_CLOCK_REALTIME:
return get_clock(); return get_clock();
default: default:
@ -479,16 +485,36 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
} }
} }
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) int64_t qemu_get_clock_ns(QEMUClock *clock)
{ {
return qemu_clock_get_ns(clock->type);
}
void qemu_clock_register_reset_notifier(QEMUClockType type,
Notifier *notifier)
{
QEMUClock *clock = qemu_clock_ptr(type);
notifier_list_add(&clock->reset_notifiers, notifier); notifier_list_add(&clock->reset_notifiers, notifier);
} }
void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier) void qemu_clock_unregister_reset_notifier(QEMUClockType type,
Notifier *notifier)
{ {
notifier_remove(notifier); notifier_remove(notifier);
} }
void qemu_register_clock_reset_notifier(QEMUClock *clock,
Notifier *notifier)
{
qemu_clock_register_reset_notifier(clock->type, notifier);
}
void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
Notifier *notifier)
{
qemu_clock_unregister_reset_notifier(clock->type, notifier);
}
void init_clocks(void) void init_clocks(void)
{ {
QEMUClockType type; QEMUClockType type;
@ -509,13 +535,13 @@ uint64_t timer_expire_time_ns(QEMUTimer *ts)
return timer_pending(ts) ? ts->expire_time : -1; return timer_pending(ts) ? ts->expire_time : -1;
} }
bool qemu_run_all_timers(void) bool qemu_clock_run_all_timers(void)
{ {
bool progress = false; bool progress = false;
QEMUClockType type; QEMUClockType type;
for (type = 0; type < QEMU_CLOCK_MAX; type++) { for (type = 0; type < QEMU_CLOCK_MAX; type++) {
progress |= qemu_run_timers(qemu_clock_ptr(type)); progress |= qemu_clock_run_timers(type);
} }
return progress; return progress;

View File

@ -412,7 +412,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
if (words[1]) { if (words[1]) {
ns = strtoll(words[1], NULL, 0); ns = strtoll(words[1], NULL, 0);
} else { } else {
ns = qemu_clock_deadline_ns_all(vm_clock); ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
} }
qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns); qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
qtest_send_prefix(chr); qtest_send_prefix(chr);

View File

@ -979,7 +979,7 @@ uint64_t qemu_get_be64(QEMUFile *f)
/* timer */ /* timer */
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts) void timer_put(QEMUFile *f, QEMUTimer *ts)
{ {
uint64_t expire_time; uint64_t expire_time;
@ -987,7 +987,7 @@ void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
qemu_put_be64(f, expire_time); qemu_put_be64(f, expire_time);
} }
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts) void timer_get(QEMUFile *f, QEMUTimer *ts)
{ {
uint64_t expire_time; uint64_t expire_time;
@ -1339,14 +1339,14 @@ const VMStateInfo vmstate_info_float64 = {
static int get_timer(QEMUFile *f, void *pv, size_t size) static int get_timer(QEMUFile *f, void *pv, size_t size)
{ {
QEMUTimer *v = pv; QEMUTimer *v = pv;
qemu_get_timer(f, v); timer_get(f, v);
return 0; return 0;
} }
static void put_timer(QEMUFile *f, void *pv, size_t size) static void put_timer(QEMUFile *f, void *pv, size_t size)
{ {
QEMUTimer *v = pv; QEMUTimer *v = pv;
qemu_put_timer(f, v); timer_put(f, v);
} }
const VMStateInfo vmstate_info_timer = { const VMStateInfo vmstate_info_timer = {

View File

@ -1,7 +1,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu/timer.h" #include "qemu/timer.h"
void qemu_clock_warp(QEMUClock *clock) void qemu_clock_warp(QEMUClockType type)
{ {
} }