qemu-monitor.texi
vscclient
QMP/qmp-commands.txt
+test-bitops
test-coroutine
+test-int128
+test-opts-visitor
test-qmp-input-visitor
test-qmp-output-visitor
test-string-input-visitor
Stable 0.15
L: qemu-stable@nongnu.org
+M: Andreas Färber <afaerber@suse.de>
T: git git://git.qemu.org/qemu-stable-0.15.git
-S: Orphan
+S: Supported
Stable 0.14
L: qemu-stable@nongnu.org
g_free(tmp);
}
}
+
+ /* Run our timers */
+ progress |= timerlistgroup_run_timers(&ctx->tlg);
+
return progress;
}
}
/* wait until next event */
- ret = g_poll((GPollFD *)ctx->pollfds->data,
- ctx->pollfds->len,
- blocking ? -1 : 0);
+ ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
+ ctx->pollfds->len,
+ blocking ? timerlistgroup_deadline_ns(&ctx->tlg) : 0);
/* if we have any readable fds, dispatch event */
if (ret > 0) {
node->pfd.revents = pfd->revents;
}
}
- if (aio_dispatch(ctx)) {
- progress = true;
- }
+ }
+
+ /* Run dispatch even if there were no readable fds to run timers */
+ if (aio_dispatch(ctx)) {
+ progress = true;
}
return progress;
HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
bool progress;
int count;
+ int timeout;
progress = false;
progress = true;
}
+ /* Run timers */
+ progress |= timerlistgroup_run_timers(&ctx->tlg);
+
/*
* Then dispatch any pending callbacks from the GSource.
*
node->io_notify(node->e);
/* aio_notify() does not count as progress */
- if (node->opaque != &ctx->notifier) {
+ if (node->e != &ctx->notifier) {
progress = true;
}
}
/* wait until next event */
while (count > 0) {
- int timeout = blocking ? INFINITE : 0;
- int ret = WaitForMultipleObjects(count, events, FALSE, timeout);
+ int ret;
+
+ timeout = blocking ?
+ qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg)) : 0;
+ ret = WaitForMultipleObjects(count, events, FALSE, timeout);
/* if we have any signaled events, dispatch event */
if ((DWORD) (ret - WAIT_OBJECT_0) >= count) {
node->io_notify(node->e);
/* aio_notify() does not count as progress */
- if (node->opaque != &ctx->notifier) {
+ if (node->e != &ctx->notifier) {
progress = true;
}
}
events[ret - WAIT_OBJECT_0] = events[--count];
}
+ if (blocking) {
+ /* Run the timers a second time. We do this because otherwise aio_wait
+ * will not note progress - and will stop a drain early - if we have
+ * a timer that was not ready to run entering g_poll but is ready
+ * after g_poll. This will only do anything if a timer has expired.
+ */
+ progress |= timerlistgroup_run_timers(&ctx->tlg);
+ }
+
return progress;
}
}
if (!start_time) {
- start_time = qemu_get_clock_ms(rt_clock);
+ start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
}
trace_migration_bitmap_sync_start();
trace_migration_bitmap_sync_end(migration_dirty_pages
- num_dirty_pages_init);
num_dirty_pages_period += migration_dirty_pages - num_dirty_pages_init;
- end_time = qemu_get_clock_ms(rt_clock);
+ end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
/* more than 1 second = 1000 millisecons */
if (end_time > start_time + 1000) {
ram_control_before_iterate(f, RAM_CONTROL_ROUND);
- t0 = qemu_get_clock_ns(rt_clock);
+ t0 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
i = 0;
while ((ret = qemu_file_rate_limit(f)) == 0) {
int bytes_sent;
iterations
*/
if ((i & 63) == 0) {
- uint64_t t1 = (qemu_get_clock_ns(rt_clock) - t0) / 1000000;
+ uint64_t t1 = (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - t0) / 1000000;
if (t1 > MAX_WAIT) {
DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
t1, i);
acpi_table_add(opts, &err);
if (err) {
- fprintf(stderr, "Wrong acpi table provided: %s\n",
- error_get_pretty(err));
+ error_report("Wrong acpi table provided: %s",
+ error_get_pretty(err));
error_free(err);
exit(1);
}
}
if (!t0) {
- t0 = qemu_get_clock_ns(rt_clock);
+ t0 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
return;
}
- t1 = qemu_get_clock_ns(rt_clock);
+ t1 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
/* If it has been more than 40 ms since the last time the guest
* was throttled then do it again.
{
AioContext *ctx = (AioContext *) source;
QEMUBH *bh;
+ int deadline;
+ /* We assume there is no timeout already supplied */
+ *timeout = -1;
for (bh = ctx->first_bh; bh; bh = bh->next) {
if (!bh->deleted && bh->scheduled) {
if (bh->idle) {
}
}
+ deadline = qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg));
+ if (deadline == 0) {
+ *timeout = 0;
+ return true;
+ } else {
+ *timeout = qemu_soonest_timeout(*timeout, deadline);
+ }
+
return false;
}
return true;
}
}
- return aio_pending(ctx);
+ return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0);
}
static gboolean
event_notifier_cleanup(&ctx->notifier);
qemu_mutex_destroy(&ctx->bh_lock);
g_array_free(ctx->pollfds, TRUE);
+ timerlistgroup_deinit(&ctx->tlg);
}
static GSourceFuncs aio_source_funcs = {
event_notifier_set(&ctx->notifier);
}
+static void aio_timerlist_notify(void *opaque)
+{
+ aio_notify(opaque);
+}
+
AioContext *aio_context_new(void)
{
AioContext *ctx;
aio_set_event_notifier(ctx, &ctx->notifier,
(EventNotifierHandler *)
event_notifier_test_and_clear);
+ timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
return ctx;
}
static void audio_reset_timer (AudioState *s)
{
if (audio_is_timer_needed ()) {
- qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
+ timer_mod (s->ts, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1);
}
else {
- qemu_del_timer (s->ts);
+ timer_del (s->ts);
}
}
QLIST_INIT (&s->cap_head);
atexit (audio_atexit);
- s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s);
+ s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
if (!s->ts) {
hw_error("Could not create audio timer\n");
}
int64_t ticks;
int64_t bytes;
- now = qemu_get_clock_ns (vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ticks = now - no->old_ticks;
bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
bytes = audio_MIN (bytes, INT_MAX);
int samples = 0;
if (dead) {
- int64_t now = qemu_get_clock_ns (vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t ticks = now - no->old_ticks;
int64_t bytes =
muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
static void rate_start (SpiceRateCtl *rate)
{
memset (rate, 0, sizeof (*rate));
- rate->start_ticks = qemu_get_clock_ns (vm_clock);
+ rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
int64_t bytes;
int64_t samples;
- now = qemu_get_clock_ns (vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ticks = now - rate->start_ticks;
bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ());
samples = (bytes - rate->bytes_sent) >> info->shift;
int rpos, decr, samples;
uint8_t *dst;
struct st_sample *src;
- int64_t now = qemu_get_clock_ns (vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int64_t ticks = now - wav->old_ticks;
int64_t bytes =
muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
return 0; \
if (*cur++ != ESC) { \
DPRINTF("Broken packet %#2x, tossing\n", req); \
- if (qemu_timer_pending(baum->cellCount_timer)) { \
- qemu_del_timer(baum->cellCount_timer); \
- baum_cellCount_timer_cb(baum); \
+ if (timer_pending(baum->cellCount_timer)) { \
+ timer_del(baum->cellCount_timer); \
+ baum_cellCount_timer_cb(baum); \
} \
return (cur - 2 - buf); \
} \
int i;
/* Allow 100ms to complete the DisplayData packet */
- qemu_mod_timer(baum->cellCount_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(baum->cellCount_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() / 10);
for (i = 0; i < baum->x * baum->y ; i++) {
EAT(c);
c = '?';
text[i] = c;
}
- qemu_del_timer(baum->cellCount_timer);
+ timer_del(baum->cellCount_timer);
memset(zero, 0, sizeof(zero));
{
BaumDriverState *baum = chr->opaque;
- qemu_free_timer(baum->cellCount_timer);
+ timer_free(baum->cellCount_timer);
if (baum->brlapi) {
brlapi__closeConnection(baum->brlapi);
g_free(baum->brlapi);
goto fail_handle;
}
- baum->cellCount_timer = qemu_new_timer_ns(vm_clock, baum_cellCount_timer_cb, baum);
+ baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);
if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
brlapi_perror("baum_init: brlapi_getDisplaySize");
return chr;
fail:
- qemu_free_timer(baum->cellCount_timer);
+ timer_free(baum->cellCount_timer);
brlapi__closeConnection(handle);
fail_handle:
g_free(handle);
do {} while (qemu_co_enter_next(&bs->throttled_reqs));
if (bs->block_timer) {
- qemu_del_timer(bs->block_timer);
- qemu_free_timer(bs->block_timer);
+ timer_del(bs->block_timer);
+ timer_free(bs->block_timer);
bs->block_timer = NULL;
}
void bdrv_io_limits_enable(BlockDriverState *bs)
{
- bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
+ bs->block_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, bdrv_block_timer, bs);
bs->io_limits_enabled = true;
}
*/
while (bdrv_exceed_io_limits(bs, nb_sectors, is_write, &wait_time)) {
- qemu_mod_timer(bs->block_timer,
- wait_time + qemu_get_clock_ns(vm_clock));
+ timer_mod(bs->block_timer,
+ wait_time + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
qemu_co_queue_wait_insert_head(&bs->throttled_reqs);
}
bs->open_flags = flags;
bs->buffer_alignment = 512;
+ bs->zero_beyond_eof = true;
open_flags = bdrv_open_flags(bs, flags);
bs->read_only = !(open_flags & BDRV_O_RDWR);
bs->valid_key = 0;
bs->sg = 0;
bs->growable = 0;
+ bs->zero_beyond_eof = false;
QDECREF(bs->options);
bs->options = NULL;
}
}
- ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+ if (!(bs->zero_beyond_eof && bs->growable)) {
+ ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+ } else {
+ /* Read zeros after EOF of growable BDSes */
+ int64_t len, total_sectors, max_nb_sectors;
+
+ len = bdrv_getlength(bs);
+ if (len < 0) {
+ ret = len;
+ goto out;
+ }
+
+ total_sectors = len >> BDRV_SECTOR_BITS;
+ max_nb_sectors = MAX(0, total_sectors - sector_num);
+ if (max_nb_sectors > 0) {
+ ret = drv->bdrv_co_readv(bs, sector_num,
+ MIN(nb_sectors, max_nb_sectors), qiov);
+ } else {
+ ret = 0;
+ }
+
+ /* Reading beyond end of file is supposed to produce zeroes */
+ if (ret == 0 && total_sectors < sector_num + nb_sectors) {
+ uint64_t offset = MAX(0, total_sectors - sector_num);
+ uint64_t bytes = (sector_num + nb_sectors - offset) *
+ BDRV_SECTOR_SIZE;
+ qemu_iovec_memset(qiov, offset * BDRV_SECTOR_SIZE, 0, bytes);
+ }
+ }
out:
tracked_request_end(&req);
double elapsed_time;
int bps_ret, iops_ret;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (now > bs->slice_end) {
bs->slice_start = now;
bs->slice_end = now + BLOCK_IO_SLICE_TIME;
*wait = max_wait;
}
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (bs->slice_end < now + max_wait) {
bs->slice_end = now + max_wait;
}
uint64_t delay_ns = ratelimit_calculate_delay(
&job->limit, job->sectors_read);
job->sectors_read = 0;
- block_job_sleep_ns(&job->common, rt_clock, delay_ns);
+ block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
} else {
- block_job_sleep_ns(&job->common, rt_clock, 0);
+ block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
}
if (block_job_is_cancelled(&job->common)) {
/* Note that even when no rate limit is applied we need to yield
* with no pending I/O here so that bdrv_drain_all() returns.
*/
- block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+ block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
if (block_job_is_cancelled(&s->common)) {
break;
}
return;
}
- qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL);
+ timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
iscsi_set_events(iscsilun);
}
#endif
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
/* Set up a timer for sending out iSCSI NOPs */
- iscsilun->nop_timer = qemu_new_timer_ms(rt_clock, iscsi_nop_timed_event, iscsilun);
- qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL);
+ iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
+ timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
#endif
out:
struct iscsi_context *iscsi = iscsilun->iscsi;
if (iscsilun->nop_timer) {
- qemu_del_timer(iscsilun->nop_timer);
- qemu_free_timer(iscsilun->nop_timer);
+ timer_del(iscsilun->nop_timer);
+ timer_free(iscsilun->nop_timer);
}
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
iscsi_destroy_context(iscsi);
goto out;
}
if (iscsilun->nop_timer) {
- qemu_del_timer(iscsilun->nop_timer);
- qemu_free_timer(iscsilun->nop_timer);
+ timer_del(iscsilun->nop_timer);
+ timer_free(iscsilun->nop_timer);
}
if (iscsilun->type != TYPE_DISK) {
ret = -ENODEV;
}
bdrv_dirty_iter_init(bs, &s->hbi);
- last_pause_ns = qemu_get_clock_ns(rt_clock);
+ last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
for (;;) {
uint64_t delay_ns;
int64_t cnt;
* We do so every SLICE_TIME nanoseconds, or when there is an error,
* or when the source is clean, whichever comes first.
*/
- if (qemu_get_clock_ns(rt_clock) - last_pause_ns < SLICE_TIME &&
+ if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - last_pause_ns < SLICE_TIME &&
s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
(cnt == 0 && s->in_flight > 0)) {
delay_ns = 0;
}
- block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+ block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
if (block_job_is_cancelled(&s->common)) {
break;
}
} else if (!should_complete) {
delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0);
- block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+ block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
} else if (cnt == 0) {
/* The two disks are in sync. Exit and report successful
* completion.
s->common.cancelled = false;
break;
}
- last_pause_ns = qemu_get_clock_ns(rt_clock);
+ last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
}
immediate_exit:
int flags = 0;
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
int prealloc = 0;
- int version = 2;
+ int version = 3;
/* Read out options */
while (options && options->name) {
{
BDRVQcowState *s = bs->opaque;
int growable = bs->growable;
+ bool zero_beyond_eof = bs->zero_beyond_eof;
int ret;
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
bs->growable = 1;
+ bs->zero_beyond_eof = false;
ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size);
bs->growable = growable;
+ bs->zero_beyond_eof = zero_beyond_eof;
return ret;
}
{
trace_qed_start_need_check_timer(s);
- /* Use vm_clock so we don't alter the image file while suspended for
+ /* Use QEMU_CLOCK_VIRTUAL so we don't alter the image file while suspended for
* migration.
*/
- qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->need_check_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
}
static void qed_cancel_need_check_timer(BDRVQEDState *s)
{
trace_qed_cancel_need_check_timer(s);
- qemu_del_timer(s->need_check_timer);
+ timer_del(s->need_check_timer);
}
static void bdrv_qed_rebind(BlockDriverState *bs)
}
}
- s->need_check_timer = qemu_new_timer_ns(vm_clock,
+ s->need_check_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
qed_need_check_timer_cb, s);
out:
BDRVQEDState *s = bs->opaque;
qed_cancel_need_check_timer(s);
- qemu_free_timer(s->need_check_timer);
+ timer_free(s->need_check_timer);
/* Ensure writes reach stable storage */
bdrv_flush(bs->file);
/* Note that even when no rate limit is applied we need to yield
* with no pending I/O here so that bdrv_drain_all() returns.
*/
- block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+ block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
if (block_job_is_cancelled(&s->common)) {
break;
}
error_report("invalid granularity, image may be corrupt");
return -EINVAL;
}
+ if (l1_size > 512 * 1024 * 1024) {
+ /* Although with big capacity and small l1_entry_sectors, we can get a
+ * big l1_size, we don't want unbounded value to allocate the table.
+ * Limit it to 512M, which is 16PB for default cluster and L2 table
+ * size */
+ error_report("L1 size too big");
+ return -EFBIG;
+ }
s->extents = g_realloc(s->extents,
(s->num_extents + 1) * sizeof(VmdkExtent));
return ret;
}
-static int vmdk_open_vmdk3(BlockDriverState *bs,
- BlockDriverState *file,
- int flags)
+static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
+ BlockDriverState *file,
+ int flags)
{
int ret;
uint32_t magic;
if (ret < 0) {
return ret;
}
-
- ret = vmdk_add_extent(bs,
- bs->file, false,
- le32_to_cpu(header.disk_sectors),
- le32_to_cpu(header.l1dir_offset) << 9,
- 0, 1 << 6, 1 << 9,
- le32_to_cpu(header.granularity),
- &extent);
+ ret = vmdk_add_extent(bs, file, false,
+ le32_to_cpu(header.disk_sectors),
+ le32_to_cpu(header.l1dir_offset) << 9,
+ 0,
+ le32_to_cpu(header.l1dir_size),
+ 4096,
+ le32_to_cpu(header.granularity),
+ &extent);
if (ret < 0) {
return ret;
}
}
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
/ l1_entry_sectors;
- if (l1_size > 512 * 1024 * 1024) {
- /* although with big capacity and small l1_entry_sectors, we can get a
- * big l1_size, we don't want unbounded value to allocate the table.
- * Limit it to 512M, which is 16PB for default cluster and L2 table
- * size */
- error_report("L1 size too big");
- return -EFBIG;
- }
if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
}
magic = be32_to_cpu(magic);
switch (magic) {
case VMDK3_MAGIC:
- return vmdk_open_vmdk3(bs, file, flags);
+ return vmdk_open_vmfs_sparse(bs, file, flags);
break;
case VMDK4_MAGIC:
return vmdk_open_vmdk4(bs, file, flags);
}
if (sectors <= 0 ||
- (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
+ (strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
+ strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE")) ||
(strcmp(access, "RW"))) {
goto next_line;
}
}
/* save to extents array */
- if (!strcmp(type, "FLAT")) {
+ if (!strcmp(type, "FLAT") || !strcmp(type, "VMFS")) {
/* FLAT extent */
VmdkExtent *extent;
return ret;
}
extent->flat_start_offset = flat_offset << 9;
- } else if (!strcmp(type, "SPARSE")) {
- /* SPARSE extent */
+ } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
+ /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags);
if (ret) {
bdrv_delete(extent_file);
goto exit;
}
if (strcmp(ct, "monolithicFlat") &&
+ strcmp(ct, "vmfs") &&
+ strcmp(ct, "vmfsSparse") &&
strcmp(ct, "twoGbMaxExtentSparse") &&
strcmp(ct, "twoGbMaxExtentFlat")) {
fprintf(stderr,
return ret;
}
-
static int vmdk_create_extent(const char *filename, int64_t filesize,
bool flat, bool compress, bool zeroed_grain)
{
}
}
-static int win32_aio_flush_cb(EventNotifier *e)
-{
- QEMUWin32AIOState *s = container_of(e, QEMUWin32AIOState, e);
-
- return (s->count > 0) ? 1 : 0;
-}
-
static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
{
QEMUWin32AIOCB *waiocb = (QEMUWin32AIOCB *)blockacb;
goto out_close_efd;
}
- qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb,
- win32_aio_flush_cb);
+ qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb);
return s;
drv = bdrv_find_whitelisted_format(buf, ro);
if (!drv) {
- error_report("'%s' invalid format", buf);
+ if (!ro && bdrv_find_whitelisted_format(buf, !ro)) {
+ error_report("'%s' can be only used as read-only device.", buf);
+ } else {
+ error_report("'%s' invalid format", buf);
+ }
return NULL;
}
}
bdrv_io_limits_disable(bs);
} else {
if (bs->block_timer) {
- qemu_mod_timer(bs->block_timer, qemu_get_clock_ns(vm_clock));
+ timer_mod(bs->block_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}
}
}
return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
}
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns)
+void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
{
assert(job->busy);
if (block_job_is_paused(job)) {
qemu_coroutine_yield();
} else {
- co_sleep_ns(clock, ns);
+ co_sleep_ns(type, ns);
}
job->busy = true;
}
dup3=yes
fi
+# check for ppoll support
+ppoll=no
+cat > $TMPC << EOF
+#include <poll.h>
+
+int main(void)
+{
+ struct pollfd pfd = { .fd = 0, .events = 0, .revents = 0 };
+ ppoll(&pfd, 1, 0, 0);
+ return 0;
+}
+EOF
+if compile_prog "" "" ; then
+ ppoll=yes
+fi
+
+# check for prctl(PR_SET_TIMERSLACK , ... ) support
+prctl_pr_set_timerslack=no
+cat > $TMPC << EOF
+#include <sys/prctl.h>
+
+int main(void)
+{
+ prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
+ return 0;
+}
+EOF
+if compile_prog "" "" ; then
+ prctl_pr_set_timerslack=yes
+fi
+
# check for epoll support
epoll=no
cat > $TMPC << EOF
if test "$dup3" = "yes" ; then
echo "CONFIG_DUP3=y" >> $config_host_mak
fi
+if test "$ppoll" = "yes" ; then
+ echo "CONFIG_PPOLL=y" >> $config_host_mak
+fi
+if test "$prctl_pr_set_timerslack" = "yes" ; then
+ echo "CONFIG_PRCTL_PR_SET_TIMERSLACK=y" >> $config_host_mak
+fi
if test "$epoll" = "yes" ; then
echo "CONFIG_EPOLL=y" >> $config_host_mak
fi
return;
}
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;
/* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
if (delta > 0
static void icount_adjust_rt(void *opaque)
{
- qemu_mod_timer(icount_rt_timer,
- qemu_get_clock_ms(rt_clock) + 1000);
+ timer_mod(icount_rt_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
icount_adjust();
}
static void icount_adjust_vm(void *opaque)
{
- qemu_mod_timer(icount_vm_timer,
- qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
+ timer_mod(icount_vm_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+ get_ticks_per_sec() / 10);
icount_adjust();
}
}
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;
if (use_icount == 1) {
qemu_icount_bias += warp_delta;
} 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.
*/
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;
qemu_icount_bias += MIN(warp_delta, delta);
}
- if (qemu_clock_expired(vm_clock)) {
- qemu_notify_event();
+ if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
}
}
vm_clock_warp_start = -1;
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());
while (clock < dest) {
- int64_t deadline = qemu_clock_deadline(vm_clock);
+ int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
int64_t warp = MIN(dest - clock, deadline);
qemu_icount_bias += warp;
- qemu_run_timers(vm_clock);
- clock = qemu_get_clock_ns(vm_clock);
+ qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
+ clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
- qemu_notify_event();
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
}
-void qemu_clock_warp(QEMUClock *clock)
+void qemu_clock_warp(QEMUClockType type)
{
int64_t deadline;
* applicable to other clocks. But a clock argument removes the
* need for if statements all over the place.
*/
- if (clock != vm_clock || !use_icount) {
+ if (type != QEMU_CLOCK_VIRTUAL || !use_icount) {
return;
}
/*
- * If the CPUs have been sleeping, advance the vm_clock timer now. This
- * ensures that the deadline for the timer is computed correctly below.
+ * If the CPUs have been sleeping, advance QEMU_CLOCK_VIRTUAL timer now.
+ * This ensures that the deadline for the timer is computed correctly below.
* 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
- * the earliest vm_clock timer.
+ * the earliest QEMU_CLOCK_VIRTUAL timer.
*/
icount_warp_rt(NULL);
- if (!all_cpu_threads_idle() || !qemu_clock_has_timers(vm_clock)) {
- qemu_del_timer(icount_warp_timer);
+ if (!all_cpu_threads_idle() || !qemu_clock_has_timers(QEMU_CLOCK_VIRTUAL)) {
+ timer_del(icount_warp_timer);
return;
}
return;
}
- vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
- deadline = qemu_clock_deadline(vm_clock);
+ vm_clock_warp_start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+ /* We want to use the earliest deadline from ALL vm_clocks */
+ deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+
+ /* Maintain prior (possibly buggy) behaviour where if no deadline
+ * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
+ * INT32_MAX nanoseconds ahead, we still use INT32_MAX
+ * nanoseconds.
+ */
+ if ((deadline < 0) || (deadline > INT32_MAX)) {
+ deadline = INT32_MAX;
+ }
+
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
* interrupt to wake it up, but the interrupt never comes because
* 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
- * sleep in icount mode if there is a pending vm_clock timer; rather
- * time could just advance to the next vm_clock event. Instead, we
- * do stop VCPUs and only advance vm_clock after some "real" time,
- * (related to the time left until the next event) has passed. This
- * rt_clock timer will do this. This avoids that the warps are too
- * visible externally---for example, you will not be sending network
- * packets continuously instead of every 100ms.
+ * sleep in icount mode if there is a pending QEMU_CLOCK_VIRTUAL
+ * timer; rather time could just advance to the next QEMU_CLOCK_VIRTUAL
+ * event. Instead, we do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL
+ * after some e"real" time, (related to the time left until the next
+ * event) has passed. The QEMU_CLOCK_REALTIME timer will do this.
+ * This avoids that the warps are visible externally; for example,
+ * you will not be sending network packets continuously instead of
+ * every 100ms.
*/
- qemu_mod_timer(icount_warp_timer, vm_clock_warp_start + deadline);
- } else {
- qemu_notify_event();
+ timer_mod(icount_warp_timer, vm_clock_warp_start + deadline);
+ } else if (deadline == 0) {
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
}
}
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) {
icount_time_shift = strtol(option, NULL, 0);
use_icount = 1;
the virtual time trigger catches emulated time passing too fast.
Realtime triggers occur even when idle, so use them less frequently
than VM triggers. */
- icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL);
- qemu_mod_timer(icount_rt_timer,
- qemu_get_clock_ms(rt_clock) + 1000);
- icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL);
- qemu_mod_timer(icount_vm_timer,
- qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
+ icount_rt_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+ icount_adjust_rt, NULL);
+ timer_mod(icount_rt_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
+ icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ icount_adjust_vm, NULL);
+ timer_mod(icount_vm_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+ get_ticks_per_sec() / 10);
}
/***********************************************************/
while (all_cpu_threads_idle()) {
/* Start accounting real time to the virtual clock if the CPUs
are idle. */
- qemu_clock_warp(vm_clock);
+ qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
}
while (1) {
tcg_exec_all();
- if (use_icount && qemu_clock_deadline(vm_clock) <= 0) {
- qemu_notify_event();
+
+ if (use_icount) {
+ int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+
+ if (deadline == 0) {
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ }
}
qemu_tcg_wait_io_event();
}
{
CPUState *cpu = first_cpu;
- qemu_clock_enable(vm_clock, false);
+ qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
while (cpu) {
cpu->stop = true;
qemu_cpu_kick(cpu);
{
CPUState *cpu = first_cpu;
- qemu_clock_enable(vm_clock, true);
+ qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
while (cpu) {
cpu_resume(cpu);
cpu = cpu->next_cpu;
#endif
if (use_icount) {
int64_t count;
+ int64_t deadline;
int decr;
qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
env->icount_decr.u16.low = 0;
env->icount_extra = 0;
- count = qemu_icount_round(qemu_clock_deadline(vm_clock));
+ deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+
+ /* Maintain prior (possibly buggy) behaviour where if no deadline
+ * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
+ * INT32_MAX nanoseconds ahead, we still use INT32_MAX
+ * nanoseconds.
+ */
+ if ((deadline < 0) || (deadline > INT32_MAX)) {
+ deadline = INT32_MAX;
+ }
+
+ count = qemu_icount_round(deadline);
qemu_icount += count;
decr = (count > 0xffff) ? 0xffff : count;
count -= decr;
{
int r;
- /* Account partial waits to the vm_clock. */
- qemu_clock_warp(vm_clock);
+ /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
+ qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
if (next_cpu == NULL) {
next_cpu = first_cpu;
CPUState *cpu = next_cpu;
CPUArchState *env = cpu->env_ptr;
- qemu_clock_enable(vm_clock,
+ qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
(cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
if (cpu_can_run(cpu)) {
}
#endif
+static int print_insn_objdump(bfd_vma pc, disassemble_info *info,
+ const char *prefix)
+{
+ int i, n = info->buffer_length;
+ uint8_t *buf = g_malloc(n);
+
+ info->read_memory_func(pc, buf, n, info);
+
+ for (i = 0; i < n; ++i) {
+ if (i % 32 == 0) {
+ info->fprintf_func(info->stream, "\n%s: ", prefix);
+ }
+ info->fprintf_func(info->stream, "%02x", buf[i]);
+ }
+
+ g_free(buf);
+ return n;
+}
+
+static int print_insn_od_host(bfd_vma pc, disassemble_info *info)
+{
+ return print_insn_objdump(pc, info, "OBJD-H");
+}
+
+static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
+{
+ return print_insn_objdump(pc, info, "OBJD-T");
+}
+
/* Disassemble this for me please... (debugging). 'flags' has the following
values:
i386 - 1 means 16 bit code, 2 means 64 bit code
target_ulong pc;
int count;
CPUDebug s;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
+ int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
#elif defined(TARGET_LM32)
s.info.mach = bfd_mach_lm32;
print_insn = print_insn_lm32;
-#else
- fprintf(out, "0x" TARGET_FMT_lx
- ": Asm output not supported on this arch\n", code);
- return;
#endif
+ if (print_insn == NULL) {
+ print_insn = print_insn_od_target;
+ }
for (pc = code; size > 0; pc += count, size -= count) {
fprintf(out, "0x" TARGET_FMT_lx ": ", pc);
uintptr_t pc;
int count;
CPUDebug s;
- int (*print_insn)(bfd_vma pc, disassemble_info *info);
+ int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
s.info.print_address_func = generic_print_host_address;
print_insn = print_insn_hppa;
#elif defined(__ia64__)
print_insn = print_insn_ia64;
-#else
- fprintf(out, "0x%lx: Asm output not supported on this arch\n",
- (long) code);
- return;
#endif
+ if (print_insn == NULL) {
+ print_insn = print_insn_od_host;
+ }
for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
fprintf(out, "0x%08" PRIxPTR ": ", pc);
count = print_insn(pc, &s.info);
#include "trace.h"
#include "qemu/range.h"
#include "qemu/thread.h"
+#include "qemu/main-loop.h"
/* #define DEBUG_IOMMU */
monitor_flush(status->mon);
}
- qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock) + 1000);
+ timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
} else {
if (status->is_block_migration) {
monitor_printf(status->mon, "\n");
}
monitor_resume(status->mon);
- qemu_del_timer(status->timer);
+ timer_del(status->timer);
g_free(status);
}
status = g_malloc0(sizeof(*status));
status->mon = mon;
status->is_block_migration = blk || inc;
- status->timer = qemu_new_timer_ms(rt_clock, hmp_migrate_status_cb,
+ status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
status);
- qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock));
+ timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
}
}
if (enable) {
expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(),
PM_TIMER_FREQUENCY);
- qemu_mod_timer(ar->tmr.timer, expire_time);
+ timer_mod(ar->tmr.timer, expire_time);
} else {
- qemu_del_timer(ar->tmr.timer);
+ timer_del(ar->tmr.timer);
}
}
MemoryRegion *parent)
{
ar->tmr.update_sci = update_sci;
- ar->tmr.timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, ar);
+ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar);
memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
&acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
memory_region_add_subregion(parent, 8, &ar->tmr.io);
void acpi_pm_tmr_reset(ACPIREGS *ar)
{
ar->tmr.overflow_time = 0;
- qemu_del_timer(ar->tmr.timer);
+ timer_del(ar->tmr.timer);
}
/* ACPI PM1aCNT */
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_be16s(f, (uint16_t *)s->ar.gpe.sts);
AlphaCPU *cpu = cpus[i];
s->cchip.cpu[i] = cpu;
if (cpu != NULL) {
- cpu->alarm_timer = qemu_new_timer_ns(vm_clock,
+ cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
typhoon_alarm_timer,
(void *)((uintptr_t)s + i));
}
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
{
- uint64_t distance = qemu_get_clock_ns(vm_clock) - timer->time;
+ uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
if (timer->st && timer->enable && timer->rate)
return timer->val - muldiv64(distance >> (timer->ptv + 1),
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
{
timer->val = omap_timer_read(timer);
- timer->time = qemu_get_clock_ns(vm_clock);
+ timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
* in a busy loop when it wants to sleep just a couple of CPU
* ticks. */
if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
- qemu_mod_timer(timer->timer, timer->time + expires);
+ timer_mod(timer->timer, timer->time + expires);
else
qemu_bh_schedule(timer->tick);
} else
- qemu_del_timer(timer->timer);
+ timer_del(timer->timer);
}
static void omap_timer_fire(void *opaque)
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
{
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
s->enable = 0;
s->reset_val = 31337;
s->val = 0;
s->irq = irq;
s->clk = clk;
- s->timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
s->tick = qemu_bh_new(omap_timer_fire, s);
omap_mpu_timer_reset(s);
omap_timer_clk_setup(s);
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
{
- qemu_del_timer(s->timer.timer);
+ timer_del(s->timer.timer);
if (!s->mode)
omap_clk_get(s->timer.clk);
s->mode = 1;
s->timer.irq = irq;
s->timer.clk = clk;
- s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
+ s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
omap_wd_timer_reset(s);
omap_timer_clk_setup(&s->timer);
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
{
- qemu_del_timer(s->timer.timer);
+ timer_del(s->timer.timer);
s->timer.enable = 0;
s->timer.it_ena = 0;
s->timer.reset_val = 0x00ffffff;
s->timer.irq = irq;
s->timer.clk = clk;
- s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
+ s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
omap_os_timer_reset(s);
omap_timer_clk_setup(&s->timer);
case 0x10: /* GAUGING_CTRL */
/* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (value & 1)
s->ulpd_gauge_start = now;
if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
s->tick += s->comp_reg * 1000 / 32768;
- qemu_mod_timer(s->clk, s->tick);
+ timer_mod(s->clk, s->tick);
}
static void omap_rtc_reset(struct omap_rtc_s *s)
s->pm_am = 0;
s->auto_comp = 0;
s->round = 0;
- s->tick = qemu_get_clock_ms(rtc_clock);
+ s->tick = qemu_clock_get_ms(rtc_clock);
memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
s->alarm_tm.tm_mday = 0x01;
s->status = 1 << 7;
s->irq = timerirq;
s->alarm = alarmirq;
- s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
+ s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
omap_rtc_reset(s);
s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
omap_mcbsp_rx_newdata(s);
- qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec());
}
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
{
- qemu_del_timer(s->source_timer);
+ timer_del(s->source_timer);
}
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
omap_mcbsp_tx_newdata(s);
- qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec());
}
{
s->tx_req = 0;
omap_mcbsp_tx_done(s);
- qemu_del_timer(s->sink_timer);
+ timer_del(s->sink_timer);
}
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
s->rx_req = 0;
s->tx_rate = 0;
s->rx_rate = 0;
- qemu_del_timer(s->source_timer);
- qemu_del_timer(s->sink_timer);
+ timer_del(s->source_timer);
+ timer_del(s->sink_timer);
}
static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
s->rxirq = rxirq;
s->txdrq = dma[0];
s->rxdrq = dma[1];
- s->sink_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_sink_tick, s);
- s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s);
+ s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
+ s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
omap_mcbsp_reset(s);
memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
struct omap_lpg_s *s = opaque;
if (s->cycle)
- qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
+ timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
else
- qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
+ timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
s->cycle = !s->cycle;
printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */
}
- qemu_del_timer(s->tm);
+ timer_del(s->tm);
if (on == period && s->on < s->period)
printf("%s: LED is on\n", __FUNCTION__);
else if (on == 0 && s->on)
struct omap_lpg_s *s = (struct omap_lpg_s *)
g_malloc0(sizeof(struct omap_lpg_s));
- s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
+ s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
omap_lpg_reset(s);
{
PXA2xxState *s = (PXA2xxState *)ri->opaque;
if (s->pmnc & 1) {
- *value = qemu_get_clock_ns(vm_clock);
+ *value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
} else {
*value = 0;
}
static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rtc_clock);
+ int64_t rt = qemu_clock_get_ms(rtc_clock);
s->last_rcnr += ((rt - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
s->last_rdcr += ((rt - s->last_hz) << 15) /
static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rtc_clock);
+ int64_t rt = qemu_clock_get_ms(rtc_clock);
if (s->rtsr & (1 << 12))
s->last_swcr += (rt - s->last_sw) / 10;
s->last_sw = rt;
static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rtc_clock);
+ int64_t rt = qemu_clock_get_ms(rtc_clock);
if (s->rtsr & (1 << 15))
s->last_swcr += rt - s->last_pi;
s->last_pi = rt;
uint32_t rtsr)
{
if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0)))
- qemu_mod_timer(s->rtc_hz, s->last_hz +
+ timer_mod(s->rtc_hz, s->last_hz +
(((s->rtar - s->last_rcnr) * 1000 *
((s->rttr & 0xffff) + 1)) >> 15));
else
- qemu_del_timer(s->rtc_hz);
+ timer_del(s->rtc_hz);
if ((rtsr & (1 << 5)) && !(rtsr & (1 << 4)))
- qemu_mod_timer(s->rtc_rdal1, s->last_hz +
+ timer_mod(s->rtc_rdal1, s->last_hz +
(((s->rdar1 - s->last_rdcr) * 1000 *
((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
else
- qemu_del_timer(s->rtc_rdal1);
+ timer_del(s->rtc_rdal1);
if ((rtsr & (1 << 7)) && !(rtsr & (1 << 6)))
- qemu_mod_timer(s->rtc_rdal2, s->last_hz +
+ timer_mod(s->rtc_rdal2, s->last_hz +
(((s->rdar2 - s->last_rdcr) * 1000 *
((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
else
- qemu_del_timer(s->rtc_rdal2);
+ timer_del(s->rtc_rdal2);
if ((rtsr & 0x1200) == 0x1200 && !(rtsr & (1 << 8)))
- qemu_mod_timer(s->rtc_swal1, s->last_sw +
+ timer_mod(s->rtc_swal1, s->last_sw +
(s->swar1 - s->last_swcr) * 10); /* TODO: fixup */
else
- qemu_del_timer(s->rtc_swal1);
+ timer_del(s->rtc_swal1);
if ((rtsr & 0x1800) == 0x1800 && !(rtsr & (1 << 10)))
- qemu_mod_timer(s->rtc_swal2, s->last_sw +
+ timer_mod(s->rtc_swal2, s->last_sw +
(s->swar2 - s->last_swcr) * 10); /* TODO: fixup */
else
- qemu_del_timer(s->rtc_swal2);
+ timer_del(s->rtc_swal2);
if ((rtsr & 0xc000) == 0xc000 && !(rtsr & (1 << 13)))
- qemu_mod_timer(s->rtc_pi, s->last_pi +
+ timer_mod(s->rtc_pi, s->last_pi +
(s->piar & 0xffff) - s->last_rtcpicr);
else
- qemu_del_timer(s->rtc_pi);
+ timer_del(s->rtc_pi);
}
static inline void pxa2xx_rtc_hz_tick(void *opaque)
case PIAR:
return s->piar;
case RCNR:
- return s->last_rcnr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
+ return s->last_rcnr +
+ ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
+ (1000 * ((s->rttr & 0xffff) + 1));
case RDCR:
- return s->last_rdcr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
+ return s->last_rdcr +
+ ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
+ (1000 * ((s->rttr & 0xffff) + 1));
case RYCR:
return s->last_rycr;
case SWCR:
if (s->rtsr & (1 << 12))
- return s->last_swcr + (qemu_get_clock_ms(rtc_clock) - s->last_sw) / 10;
+ return s->last_swcr +
+ (qemu_clock_get_ms(rtc_clock) - s->last_sw) / 10;
else
return s->last_swcr;
default:
s->last_swcr = (tm.tm_hour << 19) |
(tm.tm_min << 13) | (tm.tm_sec << 7);
s->last_rtcpicr = 0;
- s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rtc_clock);
-
- s->rtc_hz = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_hz_tick, s);
- s->rtc_rdal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
- s->rtc_rdal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
- s->rtc_swal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
- s->rtc_swal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
- s->rtc_pi = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_pi_tick, s);
+ s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
+
+ s->rtc_hz = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick, s);
+ s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
+ s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
+ s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
+ s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
+ s->rtc_pi = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick, s);
sysbus_init_irq(dev, &s->rtc_irq);
s->fifopos = 0;
}
- qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() / 32);
}
qdev_connect_gpio_out(cpu->gpio, spitz_gpio_key_strobe[i],
qdev_get_gpio_in(dev, i));
- qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock));
+ timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
qemu_add_kbd_event_handler(spitz_keyboard_handler, s);
}
spitz_keyboard_pre_map(s);
- s->kbdtimer = qemu_new_timer_ns(vm_clock, spitz_keyboard_tick, s);
+ s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
static void gptm_stop(gptm_state *s, int n)
{
- qemu_del_timer(s->timer[n]);
+ timer_del(s->timer[n]);
}
static void gptm_reload(gptm_state *s, int n, int reset)
{
int64_t tick;
if (reset)
- tick = qemu_get_clock_ns(vm_clock);
+ tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
else
tick = s->tick[n];
hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
}
s->tick[n] = tick;
- qemu_mod_timer(s->timer[n], tick);
+ timer_mod(s->timer[n], tick);
}
static void gptm_tick(void *opaque)
sysbus_init_mmio(sbd, &s->iomem);
s->opaque[0] = s->opaque[1] = s;
- s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
- s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
+ s->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[0]);
+ s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]);
vmstate_register(dev, -1, &vmstate_stellaris_gptm, s);
return 0;
}
static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rtc_clock);
+ int64_t rt = qemu_clock_get_ms(rtc_clock);
s->last_rcnr += ((rt - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
s->last_hz = rt;
static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
{
if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
- qemu_mod_timer(s->rtc_hz, s->last_hz + 1000);
+ timer_mod(s->rtc_hz, s->last_hz + 1000);
} else {
- qemu_del_timer(s->rtc_hz);
+ timer_del(s->rtc_hz);
}
if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
- qemu_mod_timer(s->rtc_alarm, s->last_hz +
+ timer_mod(s->rtc_alarm, s->last_hz +
(((s->rtar - s->last_rcnr) * 1000 *
((s->rttr & 0xffff) + 1)) >> 15));
} else {
- qemu_del_timer(s->rtc_alarm);
+ timer_del(s->rtc_alarm);
}
}
return s->rtar;
case RCNR:
return s->last_rcnr +
- ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
+ ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
default:
printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
qemu_get_timedate(&tm, 0);
s->last_rcnr = (uint32_t) mktimegm(&tm);
- s->last_hz = qemu_get_clock_ms(rtc_clock);
+ s->last_hz = qemu_clock_get_ms(rtc_clock);
- s->rtc_alarm = qemu_new_timer_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
- s->rtc_hz = qemu_new_timer_ms(rtc_clock, strongarm_rtc_hz_tick, s);
+ s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+ s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
sysbus_init_irq(dev, &s->rtc_irq);
sysbus_init_irq(dev, &s->rtc_hz_irq);
}
/* call the timeout receive callback in 3 char transmit time */
- qemu_mod_timer(s->rx_timeout_timer,
- qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+ timer_mod(s->rx_timeout_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
strongarm_uart_update_status(s);
strongarm_uart_update_int_status(s);
static void strongarm_uart_tx(void *opaque)
{
StrongARMUARTState *s = opaque;
- uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
+ uint64_t new_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
s->tx_start = (s->tx_start + 1) % 8;
s->tx_len--;
if (s->tx_len) {
- qemu_mod_timer(s->tx_timer, new_xmit_ts + s->char_transmit_time);
+ timer_mod(s->tx_timer, new_xmit_ts + s->char_transmit_time);
}
strongarm_uart_update_status(s);
strongarm_uart_update_int_status(s);
sysbus_init_mmio(dev, &s->iomem);
sysbus_init_irq(dev, &s->irq);
- s->rx_timeout_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_rx_to, s);
- s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
+ s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
+ s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
if (s->chr) {
qemu_chr_add_handlers(s->chr,
/* restart rx timeout timer */
if (s->rx_len) {
- qemu_mod_timer(s->rx_timeout_timer,
- qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+ timer_mod(s->rx_timeout_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
}
return 0;
s->ticking[n] = 1;
#ifdef DEBUG
interval = get_ticks_per_sec () * interval_Sec;
- exp = qemu_get_clock_ns (vm_clock) + interval;
+ exp = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + interval;
s->exp[n] = exp;
#endif
{
int64_t ns;
- ns = qemu_get_clock_ns(vm_clock) - d->wall_base_ns;
+ ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - d->wall_base_ns;
d->wall_clk = (uint32_t)(ns * 24 / 1000); /* 24 MHz */
}
HDACodecDevice *cdev;
intel_hda_regs_reset(d);
- d->wall_base_ns = qemu_get_clock_ns(vm_clock);
+ d->wall_base_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* reset codecs */
QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
}
else {
if (s->aux_ts) {
- qemu_mod_timer (
+ timer_mod (
s->aux_ts,
- qemu_get_clock_ns (vm_clock) + ticks
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks
);
}
}
s->csp_regs[9] = 0xf8;
reset_mixer (s);
- s->aux_ts = qemu_new_timer_ns (vm_clock, aux_timer, s);
+ s->aux_ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, aux_timer, s);
if (!s->aux_ts) {
dolog ("warning: Could not create auxiliary timer\n");
}
FDrive *cur_drv = get_cur_drv(fdctrl);
cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
- qemu_mod_timer(fdctrl->result_timer,
- qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50));
+ timer_mod(fdctrl->result_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 50));
}
static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
FLOPPY_DPRINTF("init controller\n");
fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
fdctrl->fifo_size = 512;
- fdctrl->result_timer = qemu_new_timer_ns(vm_clock,
+ fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
fdctrl_result_timer, fdctrl);
fdctrl->version = 0x90; /* Intel 82078 controller */
assert(cq->cqid == req->sq->cqid);
QTAILQ_REMOVE(&req->sq->out_req_list, req, entry);
QTAILQ_INSERT_TAIL(&cq->req_list, req, entry);
- qemu_mod_timer(cq->timer, qemu_get_clock_ns(vm_clock) + 500);
+ timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
}
static void nvme_rw_cb(void *opaque, int ret)
static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
{
n->sq[sq->sqid] = NULL;
- qemu_del_timer(sq->timer);
- qemu_free_timer(sq->timer);
+ timer_del(sq->timer);
+ timer_free(sq->timer);
g_free(sq->io_req);
if (sq->sqid) {
g_free(sq);
sq->io_req[i].sq = sq;
QTAILQ_INSERT_TAIL(&(sq->req_list), &sq->io_req[i], entry);
}
- sq->timer = qemu_new_timer_ns(vm_clock, nvme_process_sq, sq);
+ sq->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, nvme_process_sq, sq);
assert(n->cq[cqid]);
cq = n->cq[cqid];
static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
{
n->cq[cq->cqid] = NULL;
- qemu_del_timer(cq->timer);
- qemu_free_timer(cq->timer);
+ timer_del(cq->timer);
+ timer_free(cq->timer);
msix_vector_unuse(&n->parent_obj, cq->vector);
if (cq->cqid) {
g_free(cq);
QTAILQ_INIT(&cq->sq_list);
msix_vector_use(&n->parent_obj, cq->vector);
n->cq[cqid] = cq;
- cq->timer = qemu_new_timer_ns(vm_clock, nvme_post_cqes, cq);
+ cq->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, nvme_post_cqes, cq);
}
static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd)
if (start_sqs) {
NvmeSQueue *sq;
QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
- qemu_mod_timer(sq->timer, qemu_get_clock_ns(vm_clock) + 500);
+ timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
}
- qemu_mod_timer(cq->timer, qemu_get_clock_ns(vm_clock) + 500);
+ timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
}
if (cq->tail != cq->head) {
}
sq->tail = new_tail;
- qemu_mod_timer(sq->timer, qemu_get_clock_ns(vm_clock) + 500);
+ timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
}
}
pfl->ro = 0;
}
- pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl);
+ pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
pfl->wcycle = 0;
pfl->cmd = 0;
pfl->status = 0;
}
pfl->status = 0x00;
/* Let's wait 5 seconds before chip erase is done */
- qemu_mod_timer(pfl->timer,
- qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() * 5));
+ timer_mod(pfl->timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() * 5));
break;
case 0x30:
/* Sector erase */
}
pfl->status = 0x00;
/* Let's wait 1/2 second before sector erase is done */
- qemu_mod_timer(pfl->timer,
- qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 2));
+ timer_mod(pfl->timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 2));
break;
default:
DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
pfl->ro = 0;
}
- pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl);
+ pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
pfl->wcycle = 0;
pfl->cmd = 0;
pfl->status = 0;
}
if (s->out_len)
- qemu_mod_timer(s->out_tm, qemu_get_clock_ns(vm_clock) + s->baud_delay);
+ timer_mod(s->out_tm, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->baud_delay);
}
#define csrhci_out_packetz(s, len) memset(csrhci_out_packet(s, len), 0, len)
s->hci->evt_recv = csrhci_out_hci_packet_event;
s->hci->acl_recv = csrhci_out_hci_packet_acl;
- s->out_tm = qemu_new_timer_ns(vm_clock, csrhci_out_tick, s);
+ s->out_tm = timer_new_ns(QEMU_CLOCK_VIRTUAL, csrhci_out_tick, s);
s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins);
csrhci_reset(s);
static void bt_hci_mod_timer_1280ms(QEMUTimer *timer, int period)
{
- qemu_mod_timer(timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
muldiv64(period << 7, get_ticks_per_sec(), 100));
}
if (master) {
link->acl_mode = acl_active;
hci->lm.handle[hci->lm.last_handle].acl_mode_timer =
- qemu_new_timer_ns(vm_clock, bt_hci_mode_tick, link);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_mode_tick, link);
}
}
hci->lm.handle[handle].link = NULL;
if (bt_hci_role_master(hci, handle)) {
- qemu_del_timer(hci->lm.handle[handle].acl_mode_timer);
- qemu_free_timer(hci->lm.handle[handle].acl_mode_timer);
+ timer_del(hci->lm.handle[handle].acl_mode_timer);
+ timer_free(hci->lm.handle[handle].acl_mode_timer);
}
}
bt_hci_event_status(hci, HCI_SUCCESS);
- qemu_mod_timer(link->acl_mode_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(link->acl_mode_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
muldiv64(interval * 625, get_ticks_per_sec(), 1000000));
bt_hci_lmp_mode_change_master(hci, link->link, mode, interval);
bt_hci_event_status(hci, HCI_SUCCESS);
- qemu_del_timer(link->acl_mode_timer);
+ timer_del(link->acl_mode_timer);
bt_hci_lmp_mode_change_master(hci, link->link, acl_active, 0);
return 0;
hci->psb_handle = 0x000;
hci->asb_handle = 0x000;
- /* XXX: qemu_del_timer(sl->acl_mode_timer); for all links */
- qemu_del_timer(hci->lm.inquiry_done);
- qemu_del_timer(hci->lm.inquiry_next);
- qemu_del_timer(hci->conn_accept_timer);
+ /* XXX: timer_del(sl->acl_mode_timer); for all links */
+ timer_del(hci->lm.inquiry_done);
+ timer_del(hci->lm.inquiry_next);
+ timer_del(hci->conn_accept_timer);
}
static void bt_hci_read_local_version_rp(struct bt_hci_s *hci)
}
hci->lm.inquire = 0;
- qemu_del_timer(hci->lm.inquiry_done);
+ timer_del(hci->lm.inquiry_done);
bt_hci_event_complete_status(hci, HCI_SUCCESS);
break;
break;
}
hci->lm.inquire = 0;
- qemu_del_timer(hci->lm.inquiry_done);
- qemu_del_timer(hci->lm.inquiry_next);
+ timer_del(hci->lm.inquiry_done);
+ timer_del(hci->lm.inquiry_next);
bt_hci_event_complete_status(hci, HCI_SUCCESS);
break;
{
struct bt_hci_s *s = g_malloc0(sizeof(struct bt_hci_s));
- s->lm.inquiry_done = qemu_new_timer_ns(vm_clock, bt_hci_inquiry_done, s);
- s->lm.inquiry_next = qemu_new_timer_ns(vm_clock, bt_hci_inquiry_next, s);
+ s->lm.inquiry_done = timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_inquiry_done, s);
+ s->lm.inquiry_next = timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_inquiry_next, s);
s->conn_accept_timer =
- qemu_new_timer_ns(vm_clock, bt_hci_conn_accept_timeout, s);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_conn_accept_timeout, s);
s->evt_packet = bt_hci_evt_packet;
s->evt_submit = bt_hci_evt_submit;
* s->device.lmp_connection_complete to free the remaining bits once
* hci->lm.awaiting_bdaddr[] is empty. */
- qemu_free_timer(hci->lm.inquiry_done);
- qemu_free_timer(hci->lm.inquiry_next);
- qemu_free_timer(hci->conn_accept_timer);
+ timer_free(hci->lm.inquiry_done);
+ timer_free(hci->lm.inquiry_next);
+ timer_free(hci->conn_accept_timer);
g_free(hci);
}
{
#if 0
if (ch->mode != L2CAP_MODE_BASIC && ch->rexmit)
- qemu_mod_timer(ch->retransmission_timer);
+ timer_mod(ch->retransmission_timer);
else
- qemu_del_timer(ch->retransmission_timer);
+ timer_del(ch->retransmission_timer);
#endif
}
{
#if 0
if (ch->mode != L2CAP_MODE_BASIC && !ch->rexmit)
- qemu_mod_timer(ch->monitor_timer);
+ timer_mod(ch->monitor_timer);
else
- qemu_del_timer(ch->monitor_timer);
+ timer_del(ch->monitor_timer);
#endif
}
static void uart_tx_redo(UartState *s)
{
- uint64_t new_tx_time = qemu_get_clock_ns(vm_clock);
+ uint64_t new_tx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- qemu_mod_timer(s->tx_time_handle, new_tx_time + s->char_tx_time);
+ timer_mod(s->tx_time_handle, new_tx_time + s->char_tx_time);
s->r[R_SR] |= UART_SR_INTR_TEMPTY;
static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size)
{
UartState *s = (UartState *)opaque;
- uint64_t new_rx_time = qemu_get_clock_ns(vm_clock);
+ uint64_t new_rx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int i;
if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {
s->r[R_SR] |= UART_SR_INTR_RTRIG;
}
}
- qemu_mod_timer(s->fifo_trigger_handle, new_rx_time +
+ timer_mod(s->fifo_trigger_handle, new_rx_time +
(s->char_tx_time * 4));
}
uart_update_status(s);
sysbus_init_mmio(dev, &s->iomem);
sysbus_init_irq(dev, &s->irq);
- s->fifo_trigger_handle = qemu_new_timer_ns(vm_clock,
+ s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
(QEMUTimerCB *)fifo_trigger_update, s);
- s->tx_time_handle = qemu_new_timer_ns(vm_clock,
+ s->tx_time_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
(QEMUTimerCB *)uart_tx_write, s);
s->char_tx_time = (get_ticks_per_sec() / 9600) * 10;
#include "sysemu/char.h"
#include "qemu/timer.h"
#include "exec/address-spaces.h"
+#include "qemu/error-report.h"
//#define DEBUG_SERIAL
uint8_t omsr;
int flags;
- qemu_del_timer(s->modem_status_poll);
+ timer_del(s->modem_status_poll);
if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
s->poll_msl = -1;
We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
if (s->poll_msl)
- qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 100);
+ timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() / 100);
}
static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
s->tsr_retry = 0;
}
- s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
+ s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (s->lsr & UART_LSR_THRE) {
s->lsr |= UART_LSR_TEMT;
s->poll_msl = 1;
serial_update_msl(s);
} else {
- qemu_del_timer(s->modem_status_poll);
+ timer_del(s->modem_status_poll);
s->poll_msl = 0;
}
}
/* FIFO clear */
if (val & UART_FCR_RFR) {
- qemu_del_timer(s->fifo_timeout_timer);
+ timer_del(s->fifo_timeout_timer);
s->timeout_ipending=0;
fifo8_reset(&s->recv_fifo);
}
qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
/* Update the modem status after a one-character-send wait-time, since there may be a response
from the device/computer at the other end of the serial line */
- qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + s->char_transmit_time);
+ timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time);
}
}
break;
if (s->recv_fifo.num == 0) {
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
} else {
- qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
+ timer_mod(s->fifo_timeout_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 4);
}
s->timeout_ipending = 0;
} else {
}
s->lsr |= UART_LSR_DR;
/* call the timeout receive callback in 4 char transmit time */
- qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
+ timer_mod(s->fifo_timeout_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 4);
} else {
if (s->lsr & UART_LSR_DR)
s->lsr |= UART_LSR_OE;
fifo8_reset(&s->recv_fifo);
fifo8_reset(&s->xmit_fifo);
- s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
+ s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->thr_ipending = 0;
s->last_break_enable = 0;
return;
}
- s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
+ s->modem_status_poll = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) serial_update_msl, s);
- s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
+ s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) fifo_timeout_int, s);
qemu_register_reset(serial_reset, s);
qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
s->chr = chr;
serial_realize_core(s, &err);
if (err != NULL) {
- fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_report("%s", error_get_pretty(err));
error_free(err);
exit(1);
}
serial_realize_core(s, &err);
if (err != NULL) {
- fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_report("%s", error_get_pretty(err));
error_free(err);
exit(1);
}
}
}
g_free(s->post_load->connected);
- qemu_free_timer(s->post_load->timer);
+ timer_free(s->post_load->timer);
g_free(s->post_load);
s->post_load = NULL;
}
s->post_load->connected =
g_malloc0(sizeof(*s->post_load->connected) * nr_active_ports);
- s->post_load->timer = qemu_new_timer_ns(vm_clock,
+ s->post_load->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_serial_post_load_timer_cb,
s);
}
}
}
- qemu_mod_timer(s->post_load->timer, 1);
+ timer_mod(s->post_load->timer, 1);
return 0;
}
g_free(vser->ports_map);
if (vser->post_load) {
g_free(vser->post_load->connected);
- qemu_del_timer(vser->post_load->timer);
- qemu_free_timer(vser->post_load->timer);
+ timer_del(vser->post_load->timer);
+ timer_free(vser->post_load->timer);
g_free(vser->post_load);
}
virtio_cleanup(vdev);
if (s->period_frac) {
s->next_event += ((int64_t)s->period_frac * s->delta) >> 32;
}
- qemu_mod_timer(s->timer, s->next_event);
+ timer_mod(s->timer, s->next_event);
}
static void ptimer_tick(void *opaque)
uint64_t counter;
if (s->enabled) {
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Figure out the current counter value. */
if (now - s->next_event > 0
|| s->period == 0) {
{
s->delta = count;
if (s->enabled) {
- s->next_event = qemu_get_clock_ns(vm_clock);
+ s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ptimer_reload(s);
}
}
return;
}
s->enabled = oneshot ? 2 : 1;
- s->next_event = qemu_get_clock_ns(vm_clock);
+ s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ptimer_reload(s);
}
return;
s->delta = ptimer_get_count(s);
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
s->enabled = 0;
}
s->period = period;
s->period_frac = 0;
if (s->enabled) {
- s->next_event = qemu_get_clock_ns(vm_clock);
+ s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ptimer_reload(s);
}
}
s->period = 1000000000ll / freq;
s->period_frac = (1000000000ll << 32) / freq;
if (s->enabled) {
- s->next_event = qemu_get_clock_ns(vm_clock);
+ s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ptimer_reload(s);
}
}
if (reload)
s->delta = limit;
if (s->enabled && reload) {
- s->next_event = qemu_get_clock_ns(vm_clock);
+ s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ptimer_reload(s);
}
}
s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
s->bh = bh;
- s->timer = qemu_new_timer_ns(vm_clock, ptimer_tick, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
return s;
}
if (!qxl->cmdlog) {
return 0;
}
- fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_get_clock_ns(vm_clock),
+ fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
qxl->id, ring);
fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
qxl_name(qxl_type, ext->cmd.type),
trace_qxl_io_log(d->id, d->ram->log_buf);
if (d->guestdebug) {
fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id,
- qemu_get_clock_ns(vm_clock), d->ram->log_buf);
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), d->ram->log_buf);
}
break;
case QXL_IO_RESET:
int cur_line, cur_line_char, cur_char;
int64_t cur_tick;
- cur_tick = qemu_get_clock_ns(vm_clock);
+ cur_tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
cur_line = cur_char / r->htotal;
uint32_t *ch_attr_ptr;
vga_draw_glyph8_func *vga_draw_glyph8;
vga_draw_glyph9_func *vga_draw_glyph9;
- int64_t now = qemu_get_clock_ms(vm_clock);
+ int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
/* compute font data address (in plane 2) */
v = s->sr[VGA_SEQ_CHARACTER_MAP];
}
if (graphic_mode != s->graphic_mode) {
s->graphic_mode = graphic_mode;
- s->cursor_blink_time = qemu_get_clock_ms(vm_clock);
+ s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
full_update = 1;
}
switch(graphic_mode) {
if (s->periph_busy[irq] != level) {
s->periph_busy[irq] = level;
- qemu_mod_timer(s->timer, qemu_get_clock_ns(vm_clock));
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}
}
s->periph_busy[i] = 0;
}
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
static void pl330_realize(DeviceState *dev, Error **errp)
"dma", PL330_IOMEM_SIZE);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
- s->timer = qemu_new_timer_ns(vm_clock, pl330_exec_cycle_timer, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pl330_exec_cycle_timer, s);
s->cfg[0] = (s->mgr_ns_at_rst ? 0x4 : 0) |
(s->num_periph_req > 0 ? 1 : 0) |
tm_hz = 1000 / (s->itr + 1);
- qemu_mod_timer(s->periodic_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->periodic_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() / tm_hz);
}
*irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
*dmas = rc4030_allocate_dmas(s, 4);
- s->periodic_timer = qemu_new_timer_ns(vm_clock, rc4030_periodic_timer, s);
+ s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer, s);
s->timer_irq = timer;
s->jazz_bus_irq = jazz_bus;
static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes)
{
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
struct dma_s *dma = (struct dma_s *) ch->dma;
- qemu_mod_timer(ch->timer, now + delay_bytes / dma->channel_freq);
+ timer_mod(ch->timer, now + delay_bytes / dma->channel_freq);
}
static void soc_dma_ch_run(void *opaque)
ch->enable = level;
if (!ch->enable)
- qemu_del_timer(ch->timer);
+ timer_del(ch->timer);
else if (!ch->running)
soc_dma_ch_run(ch);
else
for (i = 0; i < n; i ++) {
s->ch[i].dma = &s->soc;
s->ch[i].num = i;
- s->ch[i].timer = qemu_new_timer_ns(vm_clock, soc_dma_ch_run, &s->ch[i]);
+ s->ch[i].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, soc_dma_ch_run, &s->ch[i]);
}
soc_dma_reset(&s->soc);
#include "hw/ptimer.h"
#include "qemu/log.h"
#include "qapi/qmp/qerror.h"
+#include "qemu/main-loop.h"
#include "hw/stream.h"
v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
s->count_shift = (v + 1) & 7;
- s->initial_count_load_time = qemu_get_clock_ns(vm_clock);
+ s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
apic_next_timer(s, s->initial_count_load_time);
}
/*
* Measure the delta between CLOCK_MONOTONIC, the base used for
- * kvm_pit_channel_state::count_load_time, and vm_clock. Take the
+ * kvm_pit_channel_state::count_load_time, and QEMU_CLOCK_VIRTUAL. Take the
* minimum of several samples to filter out scheduling noise.
*/
clock_offset = INT64_MAX;
for (i = 0; i < CALIBRATION_ROUNDS; i++) {
- offset = qemu_get_clock_ns(vm_clock);
+ offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
clock_gettime(CLOCK_MONOTONIC, &ts);
offset -= ts.tv_nsec;
offset -= (int64_t)ts.tv_sec * 1000000000;
case 5:
if (sc->gate < val) {
/* restart counting on rising edge */
- sc->count_load_time = qemu_get_clock_ns(vm_clock);
+ sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
break;
}
cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i),
icc_bridge, &error);
if (error) {
- fprintf(stderr, "%s\n", error_get_pretty(error));
+ error_report("%s", error_get_pretty(error));
error_free(error);
exit(1);
}
acpi_table_add(opts, &err);
if (err) {
- fprintf(stderr, "WARNING: failed to load %s: %s\n", filename,
- error_get_pretty(err));
+ error_report("WARNING: failed to load %s: %s", filename,
+ error_get_pretty(err));
error_free(err);
}
g_free(arg);
goto quit;
}
- qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000);
+ timer_mod(xen_poll, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
return;
quit:
goto err;
}
- xen_poll = qemu_new_timer_ms(rt_clock, xen_domain_poll, NULL);
- qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000);
+ xen_poll = timer_new_ms(QEMU_CLOCK_REALTIME, xen_domain_poll, NULL);
+ timer_mod(xen_poll, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
return 0;
err:
that at the expense of slower write performances. Use this
option _only_ to install Windows 2000. You must disable it
for normal use. */
- qemu_mod_timer(s->sector_write_timer,
- qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 1000));
+ timer_mod(s->sector_write_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 1000));
} else {
ide_set_irq(s->bus);
}
s->smart_selftest_data = qemu_blockalign(s->bs, 512);
memset(s->smart_selftest_data, 0, 512);
- s->sector_write_timer = qemu_new_timer_ns(vm_clock,
+ s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
ide_sector_write_timer_cb, s);
}
static void hid_del_idle_timer(HIDState *hs)
{
if (hs->idle_timer) {
- qemu_del_timer(hs->idle_timer);
- qemu_free_timer(hs->idle_timer);
+ timer_del(hs->idle_timer);
+ timer_free(hs->idle_timer);
hs->idle_timer = NULL;
}
}
void hid_set_next_idle(HIDState *hs)
{
if (hs->idle) {
- uint64_t expire_time = qemu_get_clock_ns(vm_clock) +
+ uint64_t expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
get_ticks_per_sec() * hs->idle * 4 / 1000;
if (!hs->idle_timer) {
- hs->idle_timer = qemu_new_timer_ns(vm_clock, hid_idle_timer, hs);
+ hs->idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hid_idle_timer, hs);
}
- qemu_mod_timer_ns(hs->idle_timer, expire_time);
+ timer_mod_ns(hs->idle_timer, expire_time);
} else {
hid_del_idle_timer(hs);
}
break;
}
- qemu_del_timer(s->pwm.tm[(value & 3) - 1]);
+ timer_del(s->pwm.tm[(value & 3) - 1]);
break;
case LM832x_GENERAL_ERROR:
LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
s->model = 0x8323;
- s->pwm.tm[0] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm0_tick, s);
- s->pwm.tm[1] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm1_tick, s);
- s->pwm.tm[2] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm2_tick, s);
+ s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
+ s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
+ s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
lm_kbd_reset(s);
fprintf(stderr, "%s: touchscreen sense %sabled\n",
__FUNCTION__, s->enabled ? "en" : "dis");
if (s->busy && !s->enabled)
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
s->busy &= s->enabled;
}
s->nextprecision = (data >> 13) & 1;
s->precision = s->nextprecision;
s->function = s->nextfunction;
s->pdst = !s->pnd0; /* Synchronised on internal clock */
- expires = qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() >> 7);
- qemu_mod_timer(s->timer, expires);
+ expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 7);
+ timer_mod(s->timer, expires);
}
static void tsc2005_reset(TSC2005State *s)
fprintf(stderr, "%s: touchscreen sense %sabled\n",
__FUNCTION__, s->enabled ? "en" : "dis");
if (s->busy && !s->enabled)
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
s->busy &= s->enabled;
}
tsc2005_pin_update(s);
qemu_put_be16s(f, &s->dav);
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->host_mode);
qemu_put_byte(f, s->function);
qemu_get_be16s(f, &s->dav);
qemu_get_be16s(f, &s->data);
- qemu_get_timer(f, s->timer);
+ timer_get(f, s->timer);
s->enabled = qemu_get_byte(f);
s->host_mode = qemu_get_byte(f);
s->function = qemu_get_byte(f);
for (i = 0; i < 8; i ++)
s->tr[i] = qemu_get_be32(f);
- s->busy = qemu_timer_pending(s->timer);
+ s->busy = timer_pending(s->timer);
tsc2005_pin_update(s);
return 0;
s->y = 240;
s->pressure = 0;
s->precision = s->nextprecision = 0;
- s->timer = qemu_new_timer_ns(vm_clock, tsc2005_timer_tick, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc2005_timer_tick, s);
s->pint = pintdav;
s->model = 0x2005;
l_ch = 1;
r_ch = 1;
if (s->softstep && !(s->dac_power & (1 << 10))) {
- l_ch = (qemu_get_clock_ns(vm_clock) >
+ l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
s->volume_change + TSC_SOFTSTEP_DELAY);
- r_ch = (qemu_get_clock_ns(vm_clock) >
+ r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
s->volume_change + TSC_SOFTSTEP_DELAY);
}
case 0x05: /* Stereo DAC Power Control */
return 0x2aa0 | s->dac_power |
(((s->dac_power & (1 << 10)) &&
- (qemu_get_clock_ns(vm_clock) >
+ (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
s->powerdown + TSC_POWEROFF_DELAY)) << 6);
case 0x06: /* Audio Control 3 */
s->host_mode = value >> 15;
s->enabled = !(value & 0x4000);
if (s->busy && !s->enabled)
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
s->busy &= s->enabled;
s->nextfunction = (value >> 10) & 0xf;
s->nextprecision = (value >> 8) & 3;
case 0x04: /* Reset */
if (value == 0xbb00) {
if (s->busy)
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
tsc210x_reset(s);
#ifdef TSC_VERBOSE
} else {
case 0x02: /* DAC Volume Control */
s->volume = value;
- s->volume_change = qemu_get_clock_ns(vm_clock);
+ s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
return;
case 0x03:
case 0x05: /* Stereo DAC Power Control */
if ((value & ~s->dac_power) & (1 << 10))
- s->powerdown = qemu_get_clock_ns(vm_clock);
+ s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->dac_power = value & 0x9543;
#ifdef TSC_VERBOSE
s->busy = 1;
s->precision = s->nextprecision;
s->function = s->nextfunction;
- expires = qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() >> 10);
- qemu_mod_timer(s->timer, expires);
+ expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 10);
+ timer_mod(s->timer, expires);
}
static uint16_t tsc210x_read(TSC210xState *s)
static void tsc210x_save(QEMUFile *f, void *opaque)
{
TSC210xState *s = (TSC210xState *) opaque;
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int i;
qemu_put_be16(f, s->x);
qemu_put_byte(f, s->irq);
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->host_mode);
qemu_put_byte(f, s->function);
static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
{
TSC210xState *s = (TSC210xState *) opaque;
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
int i;
s->x = qemu_get_be16(f);
s->irq = qemu_get_byte(f);
qemu_get_be16s(f, &s->dav);
- qemu_get_timer(f, s->timer);
+ timer_get(f, s->timer);
s->enabled = qemu_get_byte(f);
s->host_mode = qemu_get_byte(f);
s->function = qemu_get_byte(f);
for (i = 0; i < 0x14; i ++)
qemu_get_be16s(f, &s->filter_data[i]);
- s->busy = qemu_timer_pending(s->timer);
+ s->busy = timer_pending(s->timer);
qemu_set_irq(s->pint, !s->irq);
qemu_set_irq(s->davint, !s->dav);
s->y = 160;
s->pressure = 0;
s->precision = s->nextprecision = 0;
- s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
s->pint = pint;
s->model = 0x2102;
s->name = "tsc2102";
s->y = 240;
s->pressure = 0;
s->precision = s->nextprecision = 0;
- s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
s->pint = penirq;
s->kbint = kbirq;
s->davint = dav;
{
int64_t d;
uint32_t val;
- d = (qemu_get_clock_ns(vm_clock) - s->initial_count_load_time) >>
+ d = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->initial_count_load_time) >>
s->count_shift;
if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
/* periodic */
static void apic_timer_update(APICCommonState *s, int64_t current_time)
{
if (apic_next_timer(s, current_time)) {
- qemu_mod_timer(s->timer, s->next_time);
+ timer_mod(s->timer, s->next_time);
} else {
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
}
int n = index - 0x32;
s->lvt[n] = val;
if (n == APIC_LVT_TIMER) {
- apic_timer_update(s, qemu_get_clock_ns(vm_clock));
+ apic_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
} else if (n == APIC_LVT_LINT0 && apic_check_pic(s)) {
apic_update_irq(s);
}
break;
case 0x38:
s->initial_count = val;
- s->initial_count_load_time = qemu_get_clock_ns(vm_clock);
+ s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
apic_timer_update(s, s->initial_count_load_time);
break;
case 0x39:
static void apic_post_load(APICCommonState *s)
{
if (s->timer_expiry != -1) {
- qemu_mod_timer(s->timer, s->timer_expiry);
+ timer_mod(s->timer, s->timer_expiry);
} else {
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
}
memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi",
APIC_SPACE_SIZE);
- s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s);
local_apics[s->idx] = s;
msi_supported = true;
s->wait_for_sipi = 1;
if (s->timer) {
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
s->timer_expiry = -1;
}
static void systick_reload(nvic_state *s, int reset)
{
if (reset)
- s->systick.tick = qemu_get_clock_ns(vm_clock);
+ s->systick.tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->systick.tick += (s->systick.reload + 1) * systick_scale(s);
- qemu_mod_timer(s->systick.timer, s->systick.tick);
+ timer_mod(s->systick.timer, s->systick.tick);
}
static void systick_timer_tick(void * opaque)
s->systick.control = 0;
s->systick.reload = 0;
s->systick.tick = 0;
- qemu_del_timer(s->systick.timer);
+ timer_del(s->systick.timer);
}
/* The external routines use the hardware vector numbering, ie. the first
int64_t t;
if ((s->systick.control & SYSTICK_ENABLE) == 0)
return 0;
- t = qemu_get_clock_ns(vm_clock);
+ t = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (t >= s->systick.tick)
return 0;
val = ((s->systick.tick - (t + 1)) / systick_scale(s)) + 1;
s->systick.control &= 0xfffffff8;
s->systick.control |= value & 7;
if ((oldval ^ value) & SYSTICK_ENABLE) {
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (value & SYSTICK_ENABLE) {
if (s->systick.tick) {
s->systick.tick += now;
- qemu_mod_timer(s->systick.timer, s->systick.tick);
+ timer_mod(s->systick.timer, s->systick.tick);
} else {
systick_reload(s, 1);
}
} else {
- qemu_del_timer(s->systick.timer);
+ timer_del(s->systick.timer);
s->systick.tick -= now;
if (s->systick.tick < 0)
s->systick.tick = 0;
* by the v7M architecture.
*/
memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
- s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
+ s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s);
}
static void armv7m_nvic_instance_init(Object *obj)
#endif
#ifdef DEBUG_IRQ_LATENCY
if (level) {
- irq_time[irq_index] = qemu_get_clock_ns(vm_clock);
+ irq_time[irq_index] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
#endif
#ifdef DEBUG_IRQ_LATENCY
printf("IRQ%d latency=%0.3fus\n",
irq,
- (double)(qemu_get_clock_ns(vm_clock) -
+ (double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
irq_time[irq]) * 1000000.0 / get_ticks_per_sec());
#endif
DPRINTF("pic_interrupt: irq=%d\n", irq);
uint64_t now, next;
uint32_t wait;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
wait = env->CP0_Compare - env->CP0_Count -
(uint32_t)muldiv64(now, TIMER_FREQ, get_ticks_per_sec());
next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
- qemu_mod_timer(env->timer, next);
+ timer_mod(env->timer, next);
}
/* Expire the timer. */
} else {
uint64_t now;
- now = qemu_get_clock_ns(vm_clock);
- if (qemu_timer_pending(env->timer)
- && qemu_timer_expired(env->timer, now)) {
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (timer_pending(env->timer)
+ && timer_expired(env->timer, now)) {
/* The timer has already expired. */
cpu_mips_timer_expire(env);
}
else {
/* Store new count register */
env->CP0_Count =
- count - (uint32_t)muldiv64(qemu_get_clock_ns(vm_clock),
+ count - (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
TIMER_FREQ, get_ticks_per_sec());
/* Update timer timer */
cpu_mips_timer_update(env);
void cpu_mips_stop_count(CPUMIPSState *env)
{
/* Store the current value */
- env->CP0_Count += (uint32_t)muldiv64(qemu_get_clock_ns(vm_clock),
+ env->CP0_Count += (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
TIMER_FREQ, get_ticks_per_sec());
}
void cpu_mips_clock_init (CPUMIPSState *env)
{
- env->timer = qemu_new_timer_ns(vm_clock, &mips_timer_cb, env);
+ env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
env->CP0_Compare = 0;
cpu_mips_store_count(env, 1);
}
case 0x58: /* BOOTCS */
return 0;
case 0x5c: /* 24MHz */
- return muldiv64(qemu_get_clock_ns(vm_clock), 24000000, get_ticks_per_sec());
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24000000, get_ticks_per_sec());
case 0x60: /* MISC */
return 0;
case 0x84: /* PROCID0 */
int64_t d;
unsigned int counter;
- d = muldiv64(qemu_get_clock_ns(vm_clock) - s->load_time,
+ d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->load_time,
CUDA_TIMER_FREQ, get_ticks_per_sec());
if (s->index == 0) {
/* the timer goes down from latch to -1 (period of latch + 2) */
static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
{
CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val);
- ti->load_time = qemu_get_clock_ns(vm_clock);
+ ti->load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ti->counter_value = val;
cuda_timer_update(s, ti, ti->load_time);
}
if (!ti->timer)
return;
if ((s->acr & T1MODE) != T1MODE_CONT) {
- qemu_del_timer(ti->timer);
+ timer_del(ti->timer);
} else {
ti->next_irq_time = get_next_irq_time(ti, current_time);
- qemu_mod_timer(ti->timer, ti->next_irq_time);
+ timer_mod(ti->timer, ti->next_irq_time);
}
}
break;
case 4:
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+ cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case 5:
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
break;
case 6:
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+ cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case 7:
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
s->ifr &= ~T1_INT;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+ cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case 8:
s->timers[1].latch = val;
break;
case 11:
s->acr = val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+ cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
cuda_update(s);
break;
case 12:
obuf[1] = 0x40; /* polled data */
cuda_send_packet_to_host(s, obuf, olen + 2);
}
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->adb_poll_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
}
if (autopoll != s->autopoll) {
s->autopoll = autopoll;
if (autopoll) {
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->adb_poll_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
} else {
- qemu_del_timer(s->adb_poll_timer);
+ timer_del(s->adb_poll_timer);
}
}
obuf[0] = CUDA_PACKET;
break;
case CUDA_SET_TIME:
ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4];
- s->tick_offset = ti - (qemu_get_clock_ns(vm_clock) / get_ticks_per_sec());
+ s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
obuf[0] = CUDA_PACKET;
obuf[1] = 0;
obuf[2] = 0;
cuda_send_packet_to_host(s, obuf, 3);
break;
case CUDA_GET_TIME:
- ti = s->tick_offset + (qemu_get_clock_ns(vm_clock) / get_ticks_per_sec());
+ ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
obuf[0] = CUDA_PACKET;
obuf[1] = 0;
obuf[2] = 0;
CUDAState *s = CUDA(dev);
struct tm tm;
- s->timers[0].timer = qemu_new_timer_ns(vm_clock, cuda_timer1, s);
+ s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
qemu_get_timedate(&tm, 0);
s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
- s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
+ s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
}
static void cuda_initfn(Object *obj)
switch (addr) {
case 0x38:
- value = qemu_get_clock_ns(vm_clock);
+ value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
break;
case 0x3c:
- value = qemu_get_clock_ns(vm_clock) >> 32;
+ value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 32;
break;
}
VFIODevice *vdev = opaque;
if (vdev->intx.pending) {
- qemu_mod_timer(vdev->intx.mmap_timer,
- qemu_get_clock_ms(vm_clock) + vdev->intx.mmap_timeout);
+ timer_mod(vdev->intx.mmap_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vdev->intx.mmap_timeout);
return;
}
qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 1);
vfio_mmap_set_enabled(vdev, false);
if (vdev->intx.mmap_timeout) {
- qemu_mod_timer(vdev->intx.mmap_timer,
- qemu_get_clock_ms(vm_clock) + vdev->intx.mmap_timeout);
+ timer_mod(vdev->intx.mmap_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vdev->intx.mmap_timeout);
}
}
{
int fd;
- qemu_del_timer(vdev->intx.mmap_timer);
+ timer_del(vdev->intx.mmap_timer);
vfio_disable_intx_kvm(vdev);
vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
vdev->intx.pending = false;
}
if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) {
- vdev->intx.mmap_timer = qemu_new_timer_ms(vm_clock,
+ vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
vfio_intx_mmap_enable, vdev);
pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_update_irq);
ret = vfio_enable_intx(vdev);
pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
vfio_disable_interrupts(vdev);
if (vdev->intx.mmap_timer) {
- qemu_free_timer(vdev->intx.mmap_timer);
+ timer_free(vdev->intx.mmap_timer);
}
vfio_teardown_msi(vdev);
vfio_unmap_bars(vdev);
static void do_software_reset(dp8393xState *s)
{
- qemu_del_timer(s->watchdog);
+ timer_del(s->watchdog);
s->regs[SONIC_CR] &= ~(SONIC_CR_LCAM | SONIC_CR_RRRA | SONIC_CR_TXP | SONIC_CR_HTX);
s->regs[SONIC_CR] |= SONIC_CR_RST | SONIC_CR_RXDIS;
int64_t delay;
if (s->regs[SONIC_CR] & SONIC_CR_STP) {
- qemu_del_timer(s->watchdog);
+ timer_del(s->watchdog);
return;
}
ticks = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
- s->wt_last_update = qemu_get_clock_ns(vm_clock);
+ s->wt_last_update = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
delay = get_ticks_per_sec() * ticks / 5000000;
- qemu_mod_timer(s->watchdog, s->wt_last_update + delay);
+ timer_mod(s->watchdog, s->wt_last_update + delay);
}
static void update_wt_regs(dp8393xState *s)
uint32_t val;
if (s->regs[SONIC_CR] & SONIC_CR_STP) {
- qemu_del_timer(s->watchdog);
+ timer_del(s->watchdog);
return;
}
- elapsed = s->wt_last_update - qemu_get_clock_ns(vm_clock);
+ elapsed = s->wt_last_update - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
val = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
val -= elapsed / 5000000;
s->regs[SONIC_WT1] = (val >> 16) & 0xffff;
static void nic_reset(void *opaque)
{
dp8393xState *s = opaque;
- qemu_del_timer(s->watchdog);
+ timer_del(s->watchdog);
s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS;
s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR);
memory_region_del_subregion(s->address_space, &s->mmio);
memory_region_destroy(&s->mmio);
- qemu_del_timer(s->watchdog);
- qemu_free_timer(s->watchdog);
+ timer_del(s->watchdog);
+ timer_free(s->watchdog);
g_free(s);
}
s->memory_rw = memory_rw;
s->it_shift = it_shift;
s->irq = irq;
- s->watchdog = qemu_new_timer_ns(vm_clock, dp8393x_watchdog, s);
+ s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
s->conf.macaddr = nd->macaddr;
e1000_link_down(s);
s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
DBGOUT(PHY, "Start link auto negotiation\n");
- qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500);
+ timer_mod(s->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
}
}
uint8_t *macaddr = d->conf.macaddr.a;
int i;
- qemu_del_timer(d->autoneg_timer);
+ timer_del(d->autoneg_timer);
memset(d->phy_reg, 0, sizeof d->phy_reg);
memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
memset(d->mac_reg, 0, sizeof d->mac_reg);
s->phy_reg[PHY_CTRL] & MII_CR_RESTART_AUTO_NEG &&
!(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
nc->link_down = false;
- qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500);
+ timer_mod(s->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
}
return 0;
{
E1000State *d = E1000(dev);
- qemu_del_timer(d->autoneg_timer);
- qemu_free_timer(d->autoneg_timer);
+ timer_del(d->autoneg_timer);
+ timer_free(d->autoneg_timer);
memory_region_destroy(&d->mmio);
memory_region_destroy(&d->io);
qemu_del_nic(d->nic);
add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0");
- d->autoneg_timer = qemu_new_timer_ms(vm_clock, e1000_autoneg_timer, d);
+ d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
return 0;
}
s->afc_cfg = 0;
s->e2p_cmd = 0;
s->e2p_data = 0;
- s->free_timer_start = qemu_get_clock_ns(vm_clock) / 40;
+ s->free_timer_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 40;
ptimer_stop(s->timer);
ptimer_set_count(s->timer, 0xffff);
case CSR_WORD_SWAP:
return s->word_swap;
case CSR_FREE_RUN:
- return (qemu_get_clock_ns(vm_clock) / 40) - s->free_timer_start;
+ return (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 40) - s->free_timer_start;
case CSR_RX_DROP:
/* TODO: Implement dropped frames counter. */
return 0;
memory_region_destroy(&d->state.mmio);
memory_region_destroy(&d->io_bar);
- qemu_del_timer(d->state.poll_timer);
- qemu_free_timer(d->state.poll_timer);
+ timer_del(d->state.poll_timer);
+ timer_free(d->state.poll_timer);
qemu_del_nic(d->state.nic);
}
{
PCNetState *s = opaque;
- qemu_del_timer(s->poll_timer);
+ timer_del(s->poll_timer);
if (CSR_TDMD(s)) {
pcnet_transmit(s);
pcnet_update_irq(s);
if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
- uint64_t now = qemu_get_clock_ns(vm_clock) * 33;
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) * 33;
if (!s->timer || !now)
s->timer = now;
else {
} else
CSR_POLL(s) = t;
}
- qemu_mod_timer(s->poll_timer,
- pcnet_get_next_poll_time(s,qemu_get_clock_ns(vm_clock)));
+ timer_mod(s->poll_timer,
+ pcnet_get_next_poll_time(s,qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)));
}
}
int i;
uint16_t checksum;
- s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
+ s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
s->IntrMask = val;
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
rtl8139_update_irq(s);
}
* and probably emulated is slower is better to assume this resetting was
* done before testing on previous rtl8139_update_irq lead to IRQ losing
*/
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
rtl8139_update_irq(s);
#endif
static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
{
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
uint32_t ret = s->IntrStatus;
s->TimerExpire = next_time;
if ((s->IntrMask & PCSTimeout) != 0 && (s->IntrStatus & PCSTimeout) == 0) {
- qemu_mod_timer(s->timer, next_time);
+ timer_mod(s->timer, next_time);
}
}
case Timer:
DPRINTF("TCTR Timer reset on write\n");
- s->TCTR_base = qemu_get_clock_ns(vm_clock);
+ s->TCTR_base = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
rtl8139_set_next_tctr_time(s, s->TCTR_base);
break;
DPRINTF("FlashReg TimerInt write val=0x%08x\n", val);
if (s->TimerInt != val) {
s->TimerInt = val;
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}
break;
break;
case Timer:
- ret = muldiv64(qemu_get_clock_ns(vm_clock) - s->TCTR_base,
+ ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->TCTR_base,
PCI_FREQUENCY, get_ticks_per_sec());
DPRINTF("TCTR Timer read val=0x%08x\n", ret);
break;
static int rtl8139_post_load(void *opaque, int version_id)
{
RTL8139State* s = opaque;
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
if (version_id < 4) {
s->cplus_enabled = s->CpCmd != 0;
}
static void rtl8139_pre_save(void *opaque)
{
RTL8139State* s = opaque;
- int64_t current_time = qemu_get_clock_ns(vm_clock);
+ int64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* set IntrStatus correctly */
rtl8139_set_next_tctr_time(s, current_time);
s->IntrStatus |= PCSTimeout;
rtl8139_update_irq(s);
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}
static void rtl8139_cleanup(NetClientState *nc)
g_free(s->cplus_txbuffer);
s->cplus_txbuffer = NULL;
}
- qemu_del_timer(s->timer);
- qemu_free_timer(s->timer);
+ timer_del(s->timer);
+ timer_free(s->timer);
qemu_del_nic(s->nic);
}
s->cplus_txbuffer_offset = 0;
s->TimerExpire = 0;
- s->timer = qemu_new_timer_ns(vm_clock, rtl8139_timer, s);
- rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
+ rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
add_boot_device_path(s->conf.bootindex, d, "/ethernet-phy@0");
if (virtio_net_started(n, queue_status) && !n->vhost_started) {
if (q->tx_timer) {
- qemu_mod_timer(q->tx_timer,
- qemu_get_clock_ns(vm_clock) + n->tx_timeout);
+ timer_mod(q->tx_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
} else {
qemu_bh_schedule(q->tx_bh);
}
} else {
if (q->tx_timer) {
- qemu_del_timer(q->tx_timer);
+ timer_del(q->tx_timer);
} else {
qemu_bh_cancel(q->tx_bh);
}
if (q->tx_waiting) {
virtio_queue_set_notification(vq, 1);
- qemu_del_timer(q->tx_timer);
+ timer_del(q->tx_timer);
q->tx_waiting = 0;
virtio_net_flush_tx(q);
} else {
- qemu_mod_timer(q->tx_timer,
- qemu_get_clock_ns(vm_clock) + n->tx_timeout);
+ timer_mod(q->tx_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
q->tx_waiting = 1;
virtio_queue_set_notification(vq, 0);
}
if (n->vqs[i].tx_timer) {
n->vqs[i].tx_vq =
virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
- n->vqs[i].tx_timer = qemu_new_timer_ns(vm_clock,
+ n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_net_tx_timer,
&n->vqs[i]);
} else {
if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
virtio_net_handle_tx_timer);
- n->vqs[0].tx_timer = qemu_new_timer_ns(vm_clock, virtio_net_tx_timer,
+ n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer,
&n->vqs[0]);
} else {
n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
qemu_purge_queued_packets(nc);
if (q->tx_timer) {
- qemu_del_timer(q->tx_timer);
- qemu_free_timer(q->tx_timer);
+ timer_del(q->tx_timer);
+ timer_free(q->tx_timer);
} else {
qemu_bh_delete(q->tx_bh);
}
uint64_t now, next;
uint32_t wait;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (!is_counting) {
- qemu_del_timer(cpu->env.timer);
+ timer_del(cpu->env.timer);
last_clk = now;
return;
}
}
next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
- qemu_mod_timer(cpu->env.timer, next);
+ timer_mod(cpu->env.timer, next);
}
void cpu_openrisc_count_start(OpenRISCCPU *cpu)
OpenRISCCPU *cpu = opaque;
if ((cpu->env.ttmr & TTMR_IE) &&
- qemu_timer_expired(cpu->env.timer, qemu_get_clock_ns(vm_clock))) {
+ timer_expired(cpu->env.timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))) {
CPUState *cs = CPU(cpu);
cpu->env.ttmr |= TTMR_IP;
void cpu_openrisc_clock_init(OpenRISCCPU *cpu)
{
- cpu->env.timer = qemu_new_timer_ns(vm_clock, &openrisc_timer_cb, cpu);
+ cpu->env.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &openrisc_timer_cb, cpu);
cpu->env.ttmr = 0x00000000;
cpu->env.ttcr = 0x00000000;
}
kernel_filename);
exit(1);
}
+ cpu->env.pc = entry;
}
-
- cpu->env.pc = entry;
}
static void openrisc_sim_init(QEMUMachineInitArgs *args)
{
OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
CPUState *cs = CPU(cpu);
- int i;
- uint32_t irq_bit = 1 << irq;
+ uint32_t irq_bit;
if (irq > 31 || irq < 0) {
return;
}
+ irq_bit = 1U << irq;
+
if (level) {
cpu->env.picsr |= irq_bit;
} else {
cpu->env.picsr &= ~irq_bit;
}
- for (i = 0; i < 32; i++) {
- if ((cpu->env.picsr && (1 << i)) && (cpu->env.picmr && (1 << i))) {
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
- cpu->env.picsr &= ~(1 << i);
- }
+ if (cpu->env.picsr & cpu->env.picmr) {
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ } else {
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+ cpu->env.picsr = 0;
}
}
return env->spr[SPR_TBL];
}
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb >> 32;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
tb &= 0xFFFFFFFF00000000ULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
&tb_env->tb_offset, tb | (uint64_t)value);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
tb &= 0x00000000FFFFFFFFULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
&tb_env->tb_offset, ((uint64_t)value << 32) | tb);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
return tb >> 32;
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
tb &= 0xFFFFFFFF00000000ULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
&tb_env->atb_offset, tb | (uint64_t)value);
}
ppc_tb_t *tb_env = env->tb_env;
uint64_t tb;
- tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+ tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
tb &= 0x00000000FFFFFFFFULL;
- cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+ cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
&tb_env->atb_offset, ((uint64_t)value << 32) | tb);
}
/* If the time base is already frozen, do nothing */
if (tb_env->tb_freq != 0) {
- vmclk = qemu_get_clock_ns(vm_clock);
+ vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Get the time base */
tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
/* Get the alternate time base */
/* If the time base is not frozen, do nothing */
if (tb_env->tb_freq == 0) {
- vmclk = qemu_get_clock_ns(vm_clock);
+ vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Get the time base from tb_offset */
tb = tb_env->tb_offset;
/* Get the alternate time base from atb_offset */
uint32_t decr;
int64_t diff;
- diff = next - qemu_get_clock_ns(vm_clock);
+ diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (diff >= 0) {
decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
} else if (tb_env->flags & PPC_TIMER_BOOKE) {
ppc_tb_t *tb_env = env->tb_env;
uint64_t diff;
- diff = qemu_get_clock_ns(vm_clock) - tb_env->purr_start;
+ diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start;
return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec());
}
return;
}
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq);
if (is_excp) {
next += *nextp - now;
}
*nextp = next;
/* Adjust timer */
- qemu_mod_timer(timer, next);
+ timer_mod(timer, next);
/* If we set a negative value and the decrementer was positive, raise an
* exception.
ppc_tb_t *tb_env = cpu->env.tb_env;
tb_env->purr_load = value;
- tb_env->purr_start = qemu_get_clock_ns(vm_clock);
+ tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
env->tb_env = tb_env;
tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
/* Create new timer */
- tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, cpu);
+ tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu);
if (0) {
/* XXX: find a suitable condition to enable the hypervisor decrementer
*/
- tb_env->hdecr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_hdecr_cb,
+ tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb,
cpu);
} else {
tb_env->hdecr_timer = NULL;
cpu = ppc_env_get_cpu(env);
tb_env = env->tb_env;
ppc40x_timer = tb_env->opaque;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
case 0:
next = 1 << 9;
next = now + muldiv64(next, get_ticks_per_sec(), tb_env->tb_freq);
if (next == now)
next++;
- qemu_mod_timer(ppc40x_timer->fit_timer, next);
+ timer_mod(ppc40x_timer->fit_timer, next);
env->spr[SPR_40x_TSR] |= 1 << 26;
if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) {
ppc_set_irq(cpu, PPC_INTERRUPT_FIT, 1);
(is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
/* Stop PIT */
LOG_TB("%s: stop PIT\n", __func__);
- qemu_del_timer(tb_env->decr_timer);
+ timer_del(tb_env->decr_timer);
} else {
LOG_TB("%s: start PIT %016" PRIx64 "\n",
__func__, ppc40x_timer->pit_reload);
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
next = now + muldiv64(ppc40x_timer->pit_reload,
get_ticks_per_sec(), tb_env->decr_freq);
if (is_excp)
next += tb_env->decr_next - now;
if (next == now)
next++;
- qemu_mod_timer(tb_env->decr_timer, next);
+ timer_mod(tb_env->decr_timer, next);
tb_env->decr_next = next;
}
}
cpu = ppc_env_get_cpu(env);
tb_env = env->tb_env;
ppc40x_timer = tb_env->opaque;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
case 0:
next = 1 << 17;
switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
case 0x0:
case 0x1:
- qemu_mod_timer(ppc40x_timer->wdt_timer, next);
+ timer_mod(ppc40x_timer->wdt_timer, next);
ppc40x_timer->wdt_next = next;
env->spr[SPR_40x_TSR] |= 1 << 31;
break;
case 0x2:
- qemu_mod_timer(ppc40x_timer->wdt_timer, next);
+ timer_mod(ppc40x_timer->wdt_timer, next);
ppc40x_timer->wdt_next = next;
env->spr[SPR_40x_TSR] |= 1 << 30;
if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) {
LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
if (ppc40x_timer != NULL) {
/* We use decr timer for PIT */
- tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_4xx_pit_cb, env);
+ tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env);
ppc40x_timer->fit_timer =
- qemu_new_timer_ns(vm_clock, &cpu_4xx_fit_cb, env);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env);
ppc40x_timer->wdt_timer =
- qemu_new_timer_ns(vm_clock, &cpu_4xx_wdt_cb, env);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env);
ppc40x_timer->decr_excp = decr_excp;
}
switch (addr) {
case 0x00:
/* Time base counter */
- ret = muldiv64(qemu_get_clock_ns(vm_clock) + gpt->tb_offset,
+ ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + gpt->tb_offset,
gpt->tb_freq, get_ticks_per_sec());
break;
case 0x10:
case 0x00:
/* Time base counter */
gpt->tb_offset = muldiv64(value, get_ticks_per_sec(), gpt->tb_freq)
- - qemu_get_clock_ns(vm_clock);
+ - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ppc4xx_gpt_compute_timer(gpt);
break;
case 0x10:
int i;
gpt = opaque;
- qemu_del_timer(gpt->timer);
+ timer_del(gpt->timer);
gpt->oe = 0x00000000;
gpt->ol = 0x00000000;
gpt->im = 0x00000000;
for (i = 0; i < 5; i++) {
gpt->irqs[i] = irqs[i];
}
- gpt->timer = qemu_new_timer_ns(vm_clock, &ppc4xx_gpt_cb, gpt);
+ gpt->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, gpt);
#ifdef DEBUG_GPT
printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
#endif
uint64_t period;
uint64_t now;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
tb = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset);
period = 1ULL << target_bit;
delta_tick = period - (tb & (period - 1));
(*next)++;
}
- qemu_mod_timer(timer, *next);
+ timer_mod(timer, *next);
}
static void booke_decr_cb(void *opaque)
tb_env->tb_freq = freq;
tb_env->decr_freq = freq;
tb_env->opaque = booke_timer;
- tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &booke_decr_cb, cpu);
+ tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &booke_decr_cb, cpu);
booke_timer->fit_timer =
- qemu_new_timer_ns(vm_clock, &booke_fit_cb, cpu);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &booke_fit_cb, cpu);
booke_timer->wdt_timer =
- qemu_new_timer_ns(vm_clock, &booke_wdt_cb, cpu);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &booke_wdt_cb, cpu);
ret = kvmppc_booke_watchdog_enable(cpu);
{
int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
int index = spapr->htab_save_index;
- int64_t starttime = qemu_get_clock_ns(rt_clock);
+ int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
assert(spapr->htab_first_pass);
qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
HASH_PTE_SIZE_64 * n_valid);
- if ((qemu_get_clock_ns(rt_clock) - starttime) > max_ns) {
+ if ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
break;
}
}
int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
int examined = 0, sent = 0;
int index = spapr->htab_save_index;
- int64_t starttime = qemu_get_clock_ns(rt_clock);
+ int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
assert(!spapr->htab_first_pass);
HASH_PTE_SIZE_64 * n_valid);
sent += index - chunkstart;
- if (!final && (qemu_get_clock_ns(rt_clock) - starttime) > max_ns) {
+ if (!final && (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
break;
}
}
SDHCIState *s = (SDHCIState *)opaque;
if (s->norintsts & SDHC_NIS_REMOVE) {
- qemu_mod_timer(s->insert_timer,
- qemu_get_clock_ns(vm_clock) + SDHC_INSERTION_DELAY);
+ timer_mod(s->insert_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
} else {
s->prnsts = 0x1ff0000;
if (s->norintstsen & SDHC_NISEN_INSERT) {
if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
/* Give target some time to notice card ejection */
- qemu_mod_timer(s->insert_timer,
- qemu_get_clock_ns(vm_clock) + SDHC_INSERTION_DELAY);
+ timer_mod(s->insert_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
} else {
if (level) {
s->prnsts = 0x1ff0000;
static void sdhci_reset(SDHCIState *s)
{
- qemu_del_timer(s->insert_timer);
- qemu_del_timer(s->transfer_timer);
+ timer_del(s->insert_timer);
+ timer_del(s->transfer_timer);
/* Set all registers to 0. Capabilities registers are not cleared
* and assumed to always preserve their value, given to them during
* initialization */
}
/* we have unfinished business - reschedule to continue ADMA */
- qemu_mod_timer(s->transfer_timer,
- qemu_get_clock_ns(vm_clock) + SDHC_TRANSFER_DELAY);
+ timer_mod(s->transfer_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_TRANSFER_DELAY);
}
/* Perform data transfer according to controller configuration */
s->ro_cb = qemu_allocate_irqs(sdhci_card_readonly_cb, s, 1)[0];
sd_set_cb(s->card, s->ro_cb, s->eject_cb);
- s->insert_timer = qemu_new_timer_ns(vm_clock, sdhci_raise_insertion_irq, s);
- s->transfer_timer = qemu_new_timer_ns(vm_clock, sdhci_do_data_transfer, s);
+ s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
+ s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_do_data_transfer, s);
}
static void sdhci_uninitfn(Object *obj)
{
SDHCIState *s = SDHCI(obj);
- qemu_del_timer(s->insert_timer);
- qemu_free_timer(s->insert_timer);
- qemu_del_timer(s->transfer_timer);
- qemu_free_timer(s->transfer_timer);
+ timer_del(s->insert_timer);
+ timer_free(s->insert_timer);
+ timer_del(s->transfer_timer);
+ timer_free(s->transfer_timer);
qemu_free_irqs(&s->eject_cb);
qemu_free_irqs(&s->ro_cb);
qemu_put_be64s(f, &s->disabled_mask);
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)
qemu_get_be64s(f, &s->disabled_mask);
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,
timer->disabled_mask = disabled_mask;
timer->disabled = 1;
- timer->clock_offset = qemu_get_clock_ns(vm_clock);
+ timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- timer->qtimer = qemu_new_timer_ns(vm_clock, cb, cpu);
+ timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
return timer;
}
static void cpu_timer_reset(CPUTimer *timer)
{
timer->disabled = 1;
- timer->clock_offset = qemu_get_clock_ns(vm_clock);
+ timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- qemu_del_timer(timer->qtimer);
+ timer_del(timer->qtimer);
}
static void main_cpu_reset(void *opaque)
uint64_t real_count = count & ~timer->disabled_mask;
uint64_t disabled_bit = count & timer->disabled_mask;
- int64_t vm_clock_offset = qemu_get_clock_ns(vm_clock) -
+ int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
cpu_to_timer_ticks(real_count, timer->frequency);
TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",
uint64_t cpu_tick_get_count(CPUTimer *timer)
{
uint64_t real_count = timer_to_cpu_ticks(
- qemu_get_clock_ns(vm_clock) - timer->clock_offset,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
timer->frequency);
TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",
void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
{
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
uint64_t real_limit = limit & ~timer->disabled_mask;
timer->disabled = (limit & timer->disabled_mask) ? 1 : 0;
if (!real_limit) {
TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
timer->name);
- qemu_del_timer(timer->qtimer);
+ timer_del(timer->qtimer);
} else if (timer->disabled) {
- qemu_del_timer(timer->qtimer);
+ timer_del(timer->qtimer);
} else {
- qemu_mod_timer(timer->qtimer, expires);
+ timer_mod(timer->qtimer, expires);
}
}
return;
}
if (restart) {
- tb->tick = qemu_get_clock_ns(vm_clock);
+ tb->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
tb->tick += (int64_t)tb->count * timerblock_scale(tb);
- qemu_mod_timer(tb->timer, tb->tick);
+ timer_mod(tb->timer, tb->tick);
}
static void timerblock_tick(void *opaque)
return 0;
}
/* Slow and ugly, but hopefully won't happen too often. */
- val = tb->tick - qemu_get_clock_ns(vm_clock);
+ val = tb->tick - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
val /= timerblock_scale(tb);
if (val < 0) {
val = 0;
case 4: /* Counter. */
if ((tb->control & 1) && tb->count) {
/* Cancel the previous timer. */
- qemu_del_timer(tb->timer);
+ timer_del(tb->timer);
}
tb->count = value;
if (tb->control & 1) {
tb->status = 0;
tb->tick = 0;
if (tb->timer) {
- qemu_del_timer(tb->timer);
+ timer_del(tb->timer);
}
}
sysbus_init_mmio(dev, &s->iomem);
for (i = 0; i < s->num_cpu; i++) {
TimerBlock *tb = &s->timerblock[i];
- tb->timer = qemu_new_timer_ns(vm_clock, timerblock_tick, tb);
+ tb->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, timerblock_tick, tb);
sysbus_init_irq(dev, &tb->irq);
memory_region_init_io(&tb->iomem, OBJECT(s), &timerblock_ops, tb,
"arm_mptimer_timerblock", 0x20);
#include "qemu-common.h"
#include "hw/qdev.h"
#include "hw/ptimer.h"
+#include "qemu/main-loop.h"
/* Common timer implementation. */
event_interval = next_value - (int64_t)s->reg_value;
event_interval = (event_interval < 0) ? -event_interval : event_interval;
- qemu_mod_timer(s->timer, s->cpu_time +
+ timer_mod(s->timer, s->cpu_time +
cadence_timer_get_ns(s, event_interval));
}
(int64_t)s->reg_interval + 1 : 0x10000ULL) << 16;
uint64_t old_time = s->cpu_time;
- s->cpu_time = qemu_get_clock_ns(vm_clock);
+ s->cpu_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
DB_PRINT("cpu time: %lld ns\n", (long long)old_time);
if (!s->cpu_time_valid || old_time == s->cpu_time) {
cadence_timer_reset(s);
- s->timer = qemu_new_timer_ns(vm_clock, cadence_timer_tick, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cadence_timer_tick, s);
}
static int cadence_ttc_init(SysBusDevice *dev)
r = ptimer_get_count(t->ptimer_t1);
break;
case R_TIME:
- r = qemu_get_clock_ns(vm_clock) / 10;
+ r = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 10;
break;
case RW_INTR_MASK:
r = t->rw_intr_mask;
#include "hw/sysbus.h"
#include "qemu/timer.h"
+#include "qemu/main-loop.h"
#include "qemu-common.h"
#include "hw/ptimer.h"
/* raise interrupt if enabled */
if (s->reg.int_enb & L_INT_INTENB_ICNTEIE) {
#ifdef DEBUG_MCT
- time2[s->id] = qemu_get_clock_ns(vm_clock);
+ time2[s->id] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
DPRINTF("local timer[%d] IRQ: %llx\n", s->id,
time2[s->id] - time1[s->id]);
time1[s->id] = time2[s->id];
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "qemu-common.h"
+#include "qemu/main-loop.h"
#include "hw/ptimer.h"
#include "hw/arm/exynos4210.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/ptimer.h"
+#include "qemu/timer.h"
+#include "qemu/main-loop.h"
#include "trace.h"
static uint64_t hpet_get_ticks(HPETState *s)
{
- return ns_to_ticks(qemu_get_clock_ns(vm_clock) + s->hpet_offset);
+ return ns_to_ticks(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hpet_offset);
}
/*
HPETState *s = opaque;
/* Recalculate the offset between the main counter and guest time */
- s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_get_clock_ns(vm_clock);
+ s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Push number of timers into capability returned via HPET_ID */
s->capability &= ~HPET_ID_NUM_TIM_MASK;
}
}
diff = hpet_calculate_diff(t, cur_tick);
- qemu_mod_timer(t->qemu_timer,
- qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff));
+ timer_mod(t->qemu_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
} else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
if (t->wrap_flag) {
diff = hpet_calculate_diff(t, cur_tick);
- qemu_mod_timer(t->qemu_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(t->qemu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(int64_t)ticks_to_ns(diff));
t->wrap_flag = 0;
}
t->wrap_flag = 1;
}
}
- qemu_mod_timer(t->qemu_timer,
- qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff));
+ timer_mod(t->qemu_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
}
static void hpet_del_timer(HPETTimer *t)
{
- qemu_del_timer(t->qemu_timer);
+ timer_del(t->qemu_timer);
update_irq(t, 0);
}
if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
/* Enable main counter and interrupt generation. */
s->hpet_offset =
- ticks_to_ns(s->hpet_counter) - qemu_get_clock_ns(vm_clock);
+ ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
for (i = 0; i < s->num_timers; i++) {
if ((&s->timer[i])->cmp != ~0ULL) {
hpet_set_timer(&s->timer[i]);
}
for (i = 0; i < HPET_MAX_TIMERS; i++) {
timer = &s->timer[i];
- timer->qemu_timer = qemu_new_timer_ns(vm_clock, hpet_timer, timer);
+ timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, timer);
timer->tn = i;
timer->state = s;
}
uint64_t d;
int counter;
- d = muldiv64(qemu_get_clock_ns(vm_clock) - s->count_load_time, PIT_FREQ,
+ d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->count_load_time, PIT_FREQ,
get_ticks_per_sec());
switch(s->mode) {
case 0:
case 5:
if (sc->gate < val) {
/* restart counting on rising edge */
- sc->count_load_time = qemu_get_clock_ns(vm_clock);
+ sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
pit_irq_timer_update(sc, sc->count_load_time);
}
break;
case 3:
if (sc->gate < val) {
/* restart counting on rising edge */
- sc->count_load_time = qemu_get_clock_ns(vm_clock);
+ sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
pit_irq_timer_update(sc, sc->count_load_time);
}
/* XXX: disable/enable counting */
{
if (val == 0)
val = 0x10000;
- s->count_load_time = qemu_get_clock_ns(vm_clock);
+ s->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->count = val;
pit_irq_timer_update(s, s->count_load_time);
}
/* XXX: add BCD and null count */
s->status =
(pit_get_out(s,
- qemu_get_clock_ns(vm_clock)) << 7) |
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) << 7) |
(s->rw_mode << 4) |
(s->mode << 1) |
s->bcd;
#endif
s->next_transition_time = expire_time;
if (expire_time != -1)
- qemu_mod_timer(s->irq_timer, expire_time);
+ timer_mod(s->irq_timer, expire_time);
else
- qemu_del_timer(s->irq_timer);
+ timer_del(s->irq_timer);
}
static void pit_irq_timer(void *opaque)
s = &pit->channels[0];
if (!s->irq_disabled) {
- qemu_mod_timer(s->irq_timer, s->next_transition_time);
+ timer_mod(s->irq_timer, s->next_transition_time);
}
}
if (enable) {
s->irq_disabled = 0;
- pit_irq_timer_update(s, qemu_get_clock_ns(vm_clock));
+ pit_irq_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
} else {
s->irq_disabled = 1;
- qemu_del_timer(s->irq_timer);
+ timer_del(s->irq_timer);
}
}
PITChannelState *sc = &s->channels[0];
if (sc->next_transition_time != -1) {
- qemu_mod_timer(sc->irq_timer, sc->next_transition_time);
+ timer_mod(sc->irq_timer, sc->next_transition_time);
} else {
- qemu_del_timer(sc->irq_timer);
+ timer_del(sc->irq_timer);
}
}
s = &pit->channels[0];
/* the timer 0 is connected to an IRQ */
- s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
+ s->irq_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pit_irq_timer, s);
qdev_init_gpio_out(dev, &s->irq, 1);
memory_region_init_io(&pit->ioports, OBJECT(pit), &pit_ioport_ops,
info->gate = sc->gate;
info->mode = sc->mode;
info->initial_count = sc->count;
- info->out = pit_get_out(sc, qemu_get_clock_ns(vm_clock));
+ info->out = pit_get_out(sc, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}
void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info)
s = &pit->channels[i];
s->mode = 3;
s->gate = (i != 2);
- s->count_load_time = qemu_get_clock_ns(vm_clock);
+ s->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->count = 0x10000;
if (i == 0 && !s->irq_disabled) {
s->next_transition_time =
#include "hw/ptimer.h"
#include "hw/sysbus.h"
#include "hw/arm/imx.h"
+#include "qemu/main-loop.h"
#define TYPE_IMX_EPIT "imx.epit"
#include "hw/ptimer.h"
#include "hw/sysbus.h"
#include "hw/arm/imx.h"
+#include "qemu/main-loop.h"
#define TYPE_IMX_GPT "imx.gpt"
#include "qemu/timer.h"
#include "hw/ptimer.h"
#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
#define DEFAULT_FREQUENCY (50*1000000)
/* Repeat once a second */
next_time = 1;
}
- qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock_ns(rtc_clock) +
+ timer_mod(NVRAM->alrm_timer, qemu_clock_get_ns(rtc_clock) +
next_time * 1000);
qemu_set_irq(NVRAM->IRQ, 0);
}
{
int diff;
if (NVRAM->alrm_timer != NULL) {
- qemu_del_timer(NVRAM->alrm_timer);
+ timer_del(NVRAM->alrm_timer);
diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
if (diff > 0)
- qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
+ timer_mod(NVRAM->alrm_timer, diff * 1000);
}
}
NVRAM->buffer[0x1FF0] &= ~0x80;
if (NVRAM->wd_timer != NULL) {
- qemu_del_timer(NVRAM->wd_timer);
+ timer_del(NVRAM->wd_timer);
if (value != 0) {
interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
- qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
+ timer_mod(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
((interval * 1000) >> 4));
}
}
NVRAM->addr = 0;
NVRAM->lock = 0;
if (NVRAM->alrm_timer != NULL)
- qemu_del_timer(NVRAM->alrm_timer);
+ timer_del(NVRAM->alrm_timer);
if (NVRAM->wd_timer != NULL)
- qemu_del_timer(NVRAM->wd_timer);
+ timer_del(NVRAM->wd_timer);
}
static void m48t59_reset_isa(DeviceState *d)
{
s->buffer = g_malloc0(s->size);
if (s->model == 59) {
- s->alrm_timer = qemu_new_timer_ns(rtc_clock, &alarm_cb, s);
- s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s);
+ s->alrm_timer = timer_new_ns(rtc_clock, &alarm_cb, s);
+ s->wd_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &watchdog_cb, s);
}
qemu_get_timedate(&s->alarm, 0);
static uint64_t get_guest_rtc_ns(RTCState *s)
{
uint64_t guest_rtc;
- uint64_t guest_clock = qemu_get_clock_ns(rtc_clock);
+ uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);
guest_rtc = s->base_rtc * NSEC_PER_SEC
+ guest_clock - s->last_update + s->offset;
static void rtc_coalesced_timer_update(RTCState *s)
{
if (s->irq_coalesced == 0) {
- qemu_del_timer(s->coalesced_timer);
+ timer_del(s->coalesced_timer);
} else {
/* divide each RTC interval to 2 - 8 smaller intervals */
int c = MIN(s->irq_coalesced, 7) + 1;
- int64_t next_clock = qemu_get_clock_ns(rtc_clock) +
+ int64_t next_clock = qemu_clock_get_ns(rtc_clock) +
muldiv64(s->period / c, get_ticks_per_sec(), RTC_CLOCK_RATE);
- qemu_mod_timer(s->coalesced_timer, next_clock);
+ timer_mod(s->coalesced_timer, next_clock);
}
}
next_irq_clock = (cur_clock & ~(period - 1)) + period;
s->next_periodic_time =
muldiv64(next_irq_clock, get_ticks_per_sec(), RTC_CLOCK_RATE) + 1;
- qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
+ timer_mod(s->periodic_timer, s->next_periodic_time);
} else {
#ifdef TARGET_I386
s->irq_coalesced = 0;
#endif
- qemu_del_timer(s->periodic_timer);
+ timer_del(s->periodic_timer);
}
}
* from occurring, because the time of day is not updated.
*/
if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) {
- qemu_del_timer(s->update_timer);
+ timer_del(s->update_timer);
return;
}
if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- qemu_del_timer(s->update_timer);
+ timer_del(s->update_timer);
return;
}
if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
(s->cmos_data[RTC_REG_C] & REG_C_AF)) {
- qemu_del_timer(s->update_timer);
+ timer_del(s->update_timer);
return;
}
guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC;
/* if UF is clear, reprogram to next second */
- next_update_time = qemu_get_clock_ns(rtc_clock)
+ next_update_time = qemu_clock_get_ns(rtc_clock)
+ NSEC_PER_SEC - guest_nsec;
/* Compute time of next alarm. One second is already accounted
* the alarm time. */
next_update_time = s->next_alarm_time;
}
- if (next_update_time != qemu_timer_expire_time_ns(s->update_timer)) {
- qemu_mod_timer(s->update_timer, next_update_time);
+ if (next_update_time != timer_expire_time_ns(s->update_timer)) {
+ timer_mod(s->update_timer, next_update_time);
}
}
rtc_update_time(s);
s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
- if (qemu_get_clock_ns(rtc_clock) >= s->next_alarm_time) {
+ if (qemu_clock_get_ns(rtc_clock) >= s->next_alarm_time) {
irqs |= REG_C_AF;
if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
/* UIP bit is read only */
s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
(s->cmos_data[RTC_REG_A] & REG_A_UIP);
- periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
+ periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
check_update_timer(s);
break;
case RTC_REG_B:
qemu_irq_lower(s->irq);
}
s->cmos_data[RTC_REG_B] = data;
- periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
+ periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
check_update_timer(s);
break;
case RTC_REG_C:
rtc_get_time(s, &tm);
s->base_rtc = mktimegm(&tm);
- s->last_update = qemu_get_clock_ns(rtc_clock);
+ s->last_update = qemu_clock_get_ns(rtc_clock);
rtc_change_mon_event(&tm);
}
if (!rtc_running(s)) {
return 0;
}
- if (qemu_timer_pending(s->update_timer)) {
- int64_t next_update_time = qemu_timer_expire_time_ns(s->update_timer);
+ if (timer_pending(s->update_timer)) {
+ int64_t next_update_time = timer_expire_time_ns(s->update_timer);
/* Latch UIP until the timer expires. */
- if (qemu_get_clock_ns(rtc_clock) >= (next_update_time - UIP_HOLD_LENGTH)) {
+ if (qemu_clock_get_ns(rtc_clock) >=
+ (next_update_time - UIP_HOLD_LENGTH)) {
s->cmos_data[RTC_REG_A] |= REG_A_UIP;
return 1;
}
qemu_get_timedate(&tm, 0);
s->base_rtc = mktimegm(&tm);
- s->last_update = qemu_get_clock_ns(rtc_clock);
+ s->last_update = qemu_clock_get_ns(rtc_clock);
s->offset = 0;
/* set the CMOS date */
switch (s->lost_tick_policy) {
case LOST_TICK_SLEW:
s->coalesced_timer =
- qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
+ timer_new_ns(rtc_clock, rtc_coalesced_timer, s);
break;
case LOST_TICK_DISCARD:
break;
}
#endif
- s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
- s->update_timer = qemu_new_timer_ns(rtc_clock, rtc_update_timer, s);
+ s->periodic_timer = timer_new_ns(rtc_clock, rtc_periodic_timer, s);
+ s->update_timer = timer_new_ns(rtc_clock, rtc_update_timer, s);
check_update_timer(s);
s->clock_reset_notifier.notify = rtc_notify_clock_reset;
- qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
+ qemu_clock_register_reset_notifier(QEMU_CLOCK_REALTIME,
+ &s->clock_reset_notifier);
s->suspend_notifier.notify = rtc_notify_suspend;
qemu_register_suspend_notifier(&s->suspend_notifier);
uint64_t distance;
if (timer->st && timer->rate) {
- distance = qemu_get_clock_ns(vm_clock) - timer->time;
+ distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
if (distance >= 0xffffffff - timer->val)
{
if (timer->st) {
timer->val = omap_gp_timer_read(timer);
- timer->time = qemu_get_clock_ns(vm_clock);
+ timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
}
if (timer->st && timer->rate) {
expires = muldiv64(0x100000000ll - timer->val,
timer->ticks_per_sec, timer->rate);
- qemu_mod_timer(timer->timer, timer->time + expires);
+ timer_mod(timer->timer, timer->time + expires);
if (timer->ce && timer->match_val >= timer->val) {
matches = muldiv64(timer->match_val - timer->val,
timer->ticks_per_sec, timer->rate);
- qemu_mod_timer(timer->match, timer->time + matches);
+ timer_mod(timer->match, timer->time + matches);
} else
- qemu_del_timer(timer->match);
+ timer_del(timer->match);
} else {
- qemu_del_timer(timer->timer);
- qemu_del_timer(timer->match);
+ timer_del(timer->timer);
+ timer_del(timer->match);
omap_gp_timer_out(timer, timer->scpwm);
}
}
timer->val = 0;
} else {
timer->val = timer->load_val;
- timer->time = qemu_get_clock_ns(vm_clock);
+ timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
if (timer->trigger == gpt_trigger_overflow ||
break;
case 0x28: /* TCRR */
- s->time = qemu_get_clock_ns(vm_clock);
+ s->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->val = value;
omap_gp_timer_update(s);
break;
break;
case 0x30: /* TTGR */
- s->time = qemu_get_clock_ns(vm_clock);
+ s->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->val = s->load_val;
omap_gp_timer_update(s);
break;
s->ta = ta;
s->irq = irq;
s->clk = fclk;
- s->timer = qemu_new_timer_ns(vm_clock, omap_gp_timer_tick, s);
- s->match = qemu_new_timer_ns(vm_clock, omap_gp_timer_match, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_gp_timer_tick, s);
+ s->match = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_gp_timer_match, s);
s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
omap_gp_timer_reset(s);
omap_gp_timer_clk_setup(s);
/* 32-kHz Sync Timer of the OMAP2 */
static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
- return muldiv64(qemu_get_clock_ns(vm_clock), 0x8000, get_ticks_per_sec());
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 0x8000, get_ticks_per_sec());
}
void omap_synctimer_reset(struct omap_synctimer_s *s)
static uint32_t pl031_get_count(PL031State *s)
{
- int64_t now = qemu_get_clock_ns(rtc_clock);
+ int64_t now = qemu_clock_get_ns(rtc_clock);
return s->tick_offset + now / get_ticks_per_sec();
}
ticks = s->mr - pl031_get_count(s);
DPRINTF("Alarm set in %ud ticks\n", ticks);
if (ticks == 0) {
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
pl031_interrupt(s);
} else {
- int64_t now = qemu_get_clock_ns(rtc_clock);
- qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
+ int64_t now = qemu_clock_get_ns(rtc_clock);
+ timer_mod(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
}
}
sysbus_init_irq(dev, &s->irq);
qemu_get_timedate(&tm, 0);
- s->tick_offset = mktimegm(&tm) - qemu_get_clock_ns(rtc_clock) / get_ticks_per_sec();
+ s->tick_offset = mktimegm(&tm) -
+ qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
- s->timer = qemu_new_timer_ns(rtc_clock, pl031_interrupt, s);
+ s->timer = timer_new_ns(rtc_clock, pl031_interrupt, s);
return 0;
}
PL031State *s = opaque;
/* tick_offset is base_time - rtc_clock base time. Instead, we want to
- * store the base time relative to the vm_clock for backwards-compatibility. */
- int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+ * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility. */
+ int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
}
{
PL031State *s = opaque;
- int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+ int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
pl031_set_alarm(s);
return 0;
*/
#include "hw/sysbus.h"
#include "hw/ptimer.h"
+#include "qemu/main-loop.h"
#undef DEBUG_PUV3
#include "hw/unicore32/puv3.h"
for (i = 0; i < 4; i ++) {
new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
get_ticks_per_sec(), s->freq);
- qemu_mod_timer(s->timer[i].qtimer, new_qemu);
+ timer_mod(s->timer[i].qtimer, new_qemu);
}
}
counter = counters[n];
if (!s->tm4[counter].freq) {
- qemu_del_timer(s->tm4[n].tm.qtimer);
+ timer_del(s->tm4[n].tm.qtimer);
return;
}
new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
get_ticks_per_sec(), s->tm4[counter].freq);
- qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
+ timer_mod(s->tm4[n].tm.qtimer, new_qemu);
}
static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
goto badreg;
return s->tm4[tm].tm.value;
case OSCR:
- return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
+ return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
s->lastload, s->freq, get_ticks_per_sec());
case OSCR11: tm ++;
/* fall through */
if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
if (s->tm4[tm - 1].freq)
s->snapshot = s->tm4[tm - 1].clock + muldiv64(
- qemu_get_clock_ns(vm_clock) -
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
s->tm4[tm - 1].lastload,
s->tm4[tm - 1].freq, get_ticks_per_sec());
else
if (!s->tm4[tm].freq)
return s->tm4[tm].clock;
- return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) -
+ return s->tm4[tm].clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
case OIER:
return s->irq_enabled;
/* fall through */
case OSMR0:
s->timer[tm].value = value;
- pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
+ pxa2xx_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
break;
case OSMR11: tm ++;
/* fall through */
if (!pxa2xx_timer_has_tm4(s))
goto badreg;
s->tm4[tm].tm.value = value;
- pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
+ pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
break;
case OSCR:
s->oldclock = s->clock;
- s->lastload = qemu_get_clock_ns(vm_clock);
+ s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->clock = value;
pxa2xx_timer_update(s, s->lastload);
break;
if (!pxa2xx_timer_has_tm4(s))
goto badreg;
s->tm4[tm].oldclock = s->tm4[tm].clock;
- s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock);
+ s->tm4[tm].lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->tm4[tm].clock = value;
pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
break;
s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
else {
s->tm4[tm].freq = 0;
- pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
+ pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
}
break;
case OMCR11: tm ++;
pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)];
else {
s->tm4[tm].freq = 0;
- pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
+ pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
}
break;
default:
if (t->control & (1 << 3))
t->clock = 0;
if (t->control & (1 << 6))
- pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4);
+ pxa2xx_timer_update4(i, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), t->tm.num - 4);
if (i->events & 0xff0)
qemu_irq_raise(i->irq4);
}
int64_t now;
int i;
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
pxa2xx_timer_update(s, now);
if (pxa2xx_timer_has_tm4(s))
s->irq_enabled = 0;
s->oldclock = 0;
s->clock = 0;
- s->lastload = qemu_get_clock_ns(vm_clock);
+ s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
s->reset3 = 0;
for (i = 0; i < 4; i ++) {
sysbus_init_irq(dev, &s->timer[i].irq);
s->timer[i].info = s;
s->timer[i].num = i;
- s->timer[i].qtimer = qemu_new_timer_ns(vm_clock,
+ s->timer[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
pxa2xx_timer_tick, &s->timer[i]);
}
if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
s->tm4[i].tm.num = i + 4;
s->tm4[i].freq = 0;
s->tm4[i].control = 0x0;
- s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock,
+ s->tm4[i].tm.qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
pxa2xx_timer_tick4, &s->tm4[i]);
}
}
#include "hw/hw.h"
#include "hw/sh4/sh.h"
#include "qemu/timer.h"
+#include "qemu/main-loop.h"
#include "exec/address-spaces.h"
#include "hw/ptimer.h"
#include "hw/ptimer.h"
#include "hw/sysbus.h"
#include "trace.h"
+#include "qemu/main-loop.h"
/*
* Registers of hardware timer in sun4m.
case TUSB_DEV_OTG_TIMER:
s->otg_timer_val = value;
if (value & TUSB_DEV_OTG_TIMER_ENABLE)
- qemu_mod_timer(s->otg_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(s->otg_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
muldiv64(TUSB_DEV_OTG_TIMER_VAL(value),
get_ticks_per_sec(), TUSB_DEVCLOCK));
else
- qemu_del_timer(s->otg_timer);
+ timer_del(s->otg_timer);
break;
case TUSB_PRCM_CONF:
/* Pull the interrupt down after TUSB6010 comes up. */
s->intr_ok = 0;
tusb_intr_update(s);
- qemu_mod_timer(s->pwr_timer,
- qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2);
+ timer_mod(s->pwr_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() / 2);
}
}
DeviceState *dev = DEVICE(sbd);
TUSBState *s = TUSB(dev);
- s->otg_timer = qemu_new_timer_ns(vm_clock, tusb_otg_tick, s);
- s->pwr_timer = qemu_new_timer_ns(vm_clock, tusb_power_tick, s);
+ s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s);
+ s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s);
memory_region_init_io(&s->iomem[1], OBJECT(s), &tusb_async_ops, s,
"tusb-async", UINT32_MAX);
sysbus_init_mmio(sbd, &s->iomem[0]);
static inline void menelaus_rtc_start(MenelausState *s)
{
- s->rtc.next += qemu_get_clock_ms(rtc_clock);
- qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
+ s->rtc.next += qemu_clock_get_ms(rtc_clock);
+ timer_mod(s->rtc.hz_tm, s->rtc.next);
}
static inline void menelaus_rtc_stop(MenelausState *s)
{
- qemu_del_timer(s->rtc.hz_tm);
- s->rtc.next -= qemu_get_clock_ms(rtc_clock);
+ timer_del(s->rtc.hz_tm);
+ s->rtc.next -= qemu_clock_get_ms(rtc_clock);
if (s->rtc.next < 1)
s->rtc.next = 1;
}
s->rtc.next_comp --;
s->rtc.alm_sec --;
s->rtc.next += 1000;
- qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
+ timer_mod(s->rtc.hz_tm, s->rtc.next);
if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */
menelaus_rtc_update(s);
if (((s->rtc.ctrl >> 3) & 3) == 1 && !s->rtc.tm.tm_sec)
{
MenelausState *s = opaque;
/* Should be <= 1000 */
- s->rtc_next_vmstate = s->rtc.next - qemu_get_clock_ms(rtc_clock);
+ s->rtc_next_vmstate = s->rtc.next - qemu_clock_get_ms(rtc_clock);
}
static int menelaus_post_load(void *opaque, int version_id)
{
MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
- s->rtc.hz_tm = qemu_new_timer_ms(rtc_clock, menelaus_rtc_hz, s);
+ s->rtc.hz_tm = timer_new_ms(rtc_clock, menelaus_rtc_hz, s);
/* Three output pins plus one interrupt pin. */
qdev_init_gpio_out(&i2c->qdev, s->out, 4);
#include "hw/sysbus.h"
#include "hw/ptimer.h"
#include "qemu/log.h"
+#include "qemu/main-loop.h"
#define D(x)
#include "hw/pci/pci_ids.h"
#include "tpm_tis.h"
#include "qemu-common.h"
+#include "qemu/main-loop.h"
/*#define DEBUG_TIS */
#define NLPTR_TYPE_FSTN 3 // frame span traversal node
#define SET_LAST_RUN_CLOCK(s) \
- (s)->last_run_ns = qemu_get_clock_ns(vm_clock);
+ (s)->last_run_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* nifty macros from Arnon's EHCI version */
#define get_field(data, field) \
}
ehci_queues_rip_all(s, 0);
ehci_queues_rip_all(s, 1);
- qemu_del_timer(s->frame_timer);
+ timer_del(s->frame_timer);
qemu_bh_cancel(s->async_bh);
}
int uframes, skipped_uframes;
int i;
- t_now = qemu_get_clock_ns(vm_clock);
+ t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
ns_elapsed = t_now - ehci->last_run_ns;
uframes = ns_elapsed / UFRAME_TIMER_NS;
expire_time = t_now + (get_ticks_per_sec()
* (ehci->async_stepdown+1) / FRAME_TIMER_FREQ);
}
- qemu_mod_timer(ehci->frame_timer, expire_time);
+ timer_mod(ehci->frame_timer, expire_time);
}
}
s->ports[i].dev = 0;
}
- s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
+ s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_frame_timer, s);
s->async_bh = qemu_bh_new(ehci_frame_timer, s);
qemu_register_reset(ehci_reset, s);
return musb_cb_tick(ep);
if (!ep->intv_timer[dir])
- ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, ep);
+ ep->intv_timer[dir] = timer_new_ns(QEMU_CLOCK_VIRTUAL, musb_cb_tick, ep);
- qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) +
+ timer_mod(ep->intv_timer[dir], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
muldiv64(timeout, get_ticks_per_sec(), 8000));
}
static void musb_ep_frame_cancel(MUSBEndPoint *ep, int dir)
{
if (ep->intv_timer[dir])
- qemu_del_timer(ep->intv_timer[dir]);
+ timer_del(ep->intv_timer[dir]);
}
/* Bus control */
/* Generate a SOF event, and set a timer for EOF */
static void ohci_sof(OHCIState *ohci)
{
- ohci->sof_time = qemu_get_clock_ns(vm_clock);
- qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
+ ohci->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ timer_mod(ohci->eof_timer, ohci->sof_time + usb_frame_time);
ohci_set_interrupt(ohci, OHCI_INTR_SF);
}
*/
static int ohci_bus_start(OHCIState *ohci)
{
- ohci->eof_timer = qemu_new_timer_ns(vm_clock,
+ ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
ohci_frame_boundary,
ohci);
if (ohci->eof_timer == NULL) {
- fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name);
+ fprintf(stderr, "usb-ohci: %s: timer_new_ns failed\n", ohci->name);
ohci_die(ohci);
return 0;
}
static void ohci_bus_stop(OHCIState *ohci)
{
if (ohci->eof_timer)
- qemu_del_timer(ohci->eof_timer);
+ timer_del(ohci->eof_timer);
ohci->eof_timer = NULL;
}
/* Being in USB operational state guarnatees sof_time was
* set already.
*/
- tks = qemu_get_clock_ns(vm_clock) - ohci->sof_time;
+ tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ohci->sof_time;
/* avoid muldiv if possible */
if (tks >= usb_frame_time)
#include "qemu/iov.h"
#include "sysemu/dma.h"
#include "trace.h"
+#include "qemu/main-loop.h"
//#define DEBUG
//#define DEBUG_DUMP_DATA
UHCIState *s = opaque;
if (version_id < 2) {
- s->expire_time = qemu_get_clock_ns(vm_clock) +
+ s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(get_ticks_per_sec() / FRAME_TIMER_FREQ);
}
return 0;
if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
/* start frame processing */
trace_usb_uhci_schedule_start();
- s->expire_time = qemu_get_clock_ns(vm_clock) +
+ s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(get_ticks_per_sec() / FRAME_TIMER_FREQ);
- qemu_mod_timer(s->frame_timer, s->expire_time);
+ timer_mod(s->frame_timer, s->expire_time);
s->status &= ~UHCI_STS_HCHALTED;
} else if (!(val & UHCI_CMD_RS)) {
s->status |= UHCI_STS_HCHALTED;
if (!(s->cmd & UHCI_CMD_RS)) {
/* Full stop */
trace_usb_uhci_schedule_stop();
- qemu_del_timer(s->frame_timer);
+ timer_del(s->frame_timer);
uhci_async_cancel_all(s);
/* set hchalted bit in status - UHCI11D 2.1.2 */
s->status |= UHCI_STS_HCHALTED;
/* We still store expire_time in our state, for migration */
t_last_run = s->expire_time - frame_t;
- t_now = qemu_get_clock_ns(vm_clock);
+ t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
/* Process up to MAX_FRAMES_PER_TICK frames */
frames = (t_now - t_last_run) / frame_t;
}
s->pending_int_mask = 0;
- qemu_mod_timer(s->frame_timer, t_now + frame_t);
+ timer_mod(s->frame_timer, t_now + frame_t);
}
static const MemoryRegionOps uhci_ioport_ops = {
}
}
s->bh = qemu_bh_new(uhci_bh, s);
- s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
+ s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
s->num_ports_vmstate = NB_PORTS;
QTAILQ_INIT(&s->queues);
static uint64_t xhci_mfindex_get(XHCIState *xhci)
{
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
return (now - xhci->mfindex_start) / 125000;
}
int64_t now;
if ((xhci->usbcmd & bits) == bits) {
- now = qemu_get_clock_ns(vm_clock);
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
mfindex = ((now - xhci->mfindex_start) / 125000) & 0x3fff;
left = 0x4000 - mfindex;
- qemu_mod_timer(xhci->mfwrap_timer, now + left * 125000);
+ timer_mod(xhci->mfwrap_timer, now + left * 125000);
} else {
- qemu_del_timer(xhci->mfwrap_timer);
+ timer_del(xhci->mfwrap_timer);
}
}
{
trace_usb_xhci_run();
xhci->usbsts &= ~USBSTS_HCH;
- xhci->mfindex_start = qemu_get_clock_ns(vm_clock);
+ xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
static void xhci_stop(XHCIState *xhci)
for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {
usb_packet_init(&epctx->transfers[i].packet);
}
- epctx->kick_timer = qemu_new_timer_ns(vm_clock, xhci_ep_kick_timer, epctx);
+ epctx->kick_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_ep_kick_timer, epctx);
return epctx;
}
XHCIEPContext *epctx = t->xhci->slots[t->slotid-1].eps[t->epid-1];
if (epctx) {
epctx->retry = NULL;
- qemu_del_timer(epctx->kick_timer);
+ timer_del(epctx->kick_timer);
}
t->running_retry = 0;
}
xhci_set_ep_state(xhci, epctx, NULL, EP_DISABLED);
- qemu_free_timer(epctx->kick_timer);
+ timer_free(epctx->kick_timer);
g_free(epctx);
slot->eps[epid-1] = NULL;
XHCIEPContext *epctx, uint64_t mfindex)
{
if (xfer->mfindex_kick > mfindex) {
- qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(xfer->mfindex_kick - mfindex) * 125000);
xfer->running_retry = 1;
} else {
epctx->mfindex_last = xfer->mfindex_kick;
- qemu_del_timer(epctx->kick_timer);
+ timer_del(epctx->kick_timer);
xfer->running_retry = 0;
}
}
xhci->intr[i].ev_buffer_get = 0;
}
- xhci->mfindex_start = qemu_get_clock_ns(vm_clock);
+ xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
xhci_mfwrap_update(xhci);
}
xhci->numslots = 1;
}
- xhci->mfwrap_timer = qemu_new_timer_ns(vm_clock, xhci_mfwrap_timer, xhci);
+ xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci);
xhci->irq = dev->irq[0];
epctx->state = state;
if (state == EP_RUNNING) {
/* kick endpoint after vmload is finished */
- qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock));
+ timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}
}
}
if (unconnected == 0) {
/* nothing to watch */
if (usb_auto_timer) {
- qemu_del_timer(usb_auto_timer);
+ timer_del(usb_auto_timer);
trace_usb_host_auto_scan_disabled();
}
return;
usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
}
if (!usb_auto_timer) {
- usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
+ usb_auto_timer = timer_new_ms(QEMU_CLOCK_REALTIME, usb_host_auto_check, NULL);
if (!usb_auto_timer) {
return;
}
trace_usb_host_auto_scan_enabled();
}
- qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
+ timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
}
void usb_host_info(Monitor *mon, const QDict *qdict)
if (unconnected == 0) {
/* nothing to watch */
if (usb_auto_timer) {
- qemu_del_timer(usb_auto_timer);
+ timer_del(usb_auto_timer);
trace_usb_host_auto_scan_disabled();
}
return;
usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
}
if (!usb_auto_timer) {
- usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
+ usb_auto_timer = timer_new_ms(QEMU_CLOCK_REALTIME, usb_host_auto_check, NULL);
if (!usb_auto_timer) {
return;
}
trace_usb_host_auto_scan_enabled();
}
- qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
+ timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
}
#ifndef CONFIG_USB_LIBUSB
}
dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
- dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
+ dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev);
packet_id_queue_init(&dev->cancelled, dev, "cancelled");
packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight");
/* Note must be done after qemu_chr_close, as that causes a close event */
qemu_bh_delete(dev->chardev_close_bh);
- qemu_del_timer(dev->attach_timer);
- qemu_free_timer(dev->attach_timer);
+ timer_del(dev->attach_timer);
+ timer_free(dev->attach_timer);
usbredir_cleanup_device_queues(dev);
USBRedirDevice *dev = priv;
const char *speed;
- if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
+ if (timer_pending(dev->attach_timer) || dev->dev.attached) {
ERROR("Received device connect while already connected\n");
return;
}
}
usbredir_check_bulk_receiving(dev);
- qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
+ timer_mod(dev->attach_timer, dev->next_attach_time);
}
static void usbredir_device_disconnect(void *priv)
USBRedirDevice *dev = priv;
/* Stop any pending attaches */
- qemu_del_timer(dev->attach_timer);
+ timer_del(dev->attach_timer);
if (dev->dev.attached) {
DPRINTF("detaching device\n");
* Delay next usb device attach to give the guest a chance to see
* see the detach / attach in case of quick close / open succession
*/
- dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
+ dev->next_attach_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 200;
}
/* Reset state so that the next dev connected starts with a clean slate */
* If we receive interface info after the device has already been
* connected (ie on a set_config), re-check interface dependent things.
*/
- if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
+ if (timer_pending(dev->attach_timer) || dev->dev.attached) {
usbredir_check_bulk_receiving(dev);
if (usbredir_check_filter(dev)) {
ERROR("Device no longer matches filter after interface info "
static void balloon_stats_destroy_timer(VirtIOBalloon *s)
{
if (balloon_stats_enabled(s)) {
- qemu_del_timer(s->stats_timer);
- qemu_free_timer(s->stats_timer);
+ timer_del(s->stats_timer);
+ timer_free(s->stats_timer);
s->stats_timer = NULL;
s->stats_poll_interval = 0;
}
static void balloon_stats_change_timer(VirtIOBalloon *s, int secs)
{
- qemu_mod_timer(s->stats_timer, qemu_get_clock_ms(vm_clock) + secs * 1000);
+ timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000);
}
static void balloon_stats_poll_cb(void *opaque)
/* create a new timer */
g_assert(s->stats_timer == NULL);
- s->stats_timer = qemu_new_timer_ms(vm_clock, balloon_stats_poll_cb, s);
+ s->stats_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, balloon_stats_poll_cb, s);
s->stats_poll_interval = value;
balloon_stats_change_timer(s, 0);
}
vrng->quota_remaining = vrng->conf.max_bytes;
virtio_rng_process(vrng);
- qemu_mod_timer(vrng->rate_limit_timer,
- qemu_get_clock_ms(vm_clock) + vrng->conf.period_ms);
+ timer_mod(vrng->rate_limit_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms);
}
static int virtio_rng_device_init(VirtIODevice *vdev)
assert(vrng->conf.max_bytes <= INT64_MAX);
vrng->quota_remaining = vrng->conf.max_bytes;
- vrng->rate_limit_timer = qemu_new_timer_ms(vm_clock,
+ vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
check_rate_limit, vrng);
- qemu_mod_timer(vrng->rate_limit_timer,
- qemu_get_clock_ms(vm_clock) + vrng->conf.period_ms);
+ timer_mod(vrng->rate_limit_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms);
register_savevm(qdev, "virtio-rng", -1, 1, virtio_rng_save,
virtio_rng_load, vrng);
VirtIORNG *vrng = VIRTIO_RNG(qdev);
VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
- qemu_del_timer(vrng->rate_limit_timer);
- qemu_free_timer(vrng->rate_limit_timer);
+ timer_del(vrng->rate_limit_timer);
+ timer_free(vrng->rate_limit_timer);
unregister_savevm(qdev, "virtio-rng", vrng);
virtio_cleanup(vdev);
return 0;
i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
- qemu_mod_timer(d->timer, qemu_get_clock_ns(vm_clock) + timeout);
+ timer_mod(d->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
}
/* This is called when the guest disables the watchdog. */
{
i6300esb_debug("timer disabled\n");
- qemu_del_timer(d->timer);
+ timer_del(d->timer);
}
static void i6300esb_reset(DeviceState *dev)
i6300esb_debug("I6300State = %p\n", d);
- d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
+ d->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, i6300esb_timer_expired, d);
d->previous_reboot_flag = 0;
memory_region_init_io(&d->io_mem, OBJECT(d), &i6300esb_ops, d,
ib700_debug("addr = %x, data = %x\n", addr, data);
timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec();
- qemu_mod_timer(s->timer, qemu_get_clock_ns (vm_clock) + timeout);
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
}
/* A write (of any value) to this register disables the timer. */
ib700_debug("addr = %x, data = %x\n", addr, data);
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
/* This is called when the watchdog expires. */
ib700_debug("watchdog expired\n");
watchdog_perform_action();
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
static const VMStateDescription vmstate_ib700 = {
ib700_debug("watchdog init\n");
- s->timer = qemu_new_timer_ns(vm_clock, ib700_timer_expired, s);
+ s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s);
portio_list_init(port_list, OBJECT(s), wdt_portio_list, s, "ib700");
portio_list_add(port_list, isa_address_space_io(&s->parent_obj), 0);
ib700_debug("watchdog reset\n");
- qemu_del_timer(s->timer);
+ timer_del(s->timer);
}
static WatchdogTimerModel model = {
uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
int level;
- /* If the CPU is halted advance CCOUNT according to the vm_clock time
+ /* If the CPU is halted advance CCOUNT according to the QEMU_CLOCK_VIRTUAL time
* elapsed since the moment when it was advanced last time.
*/
if (cs->halted) {
- int64_t now = qemu_get_clock_ns(vm_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
xtensa_advance_ccount(env,
muldiv64(now - env->halt_clock,
}
}
env->wake_ccount = wake_ccount;
- qemu_mod_timer(env->ccompare_timer, env->halt_clock +
+ timer_mod(env->ccompare_timer, env->halt_clock +
muldiv64(wake_ccount - env->sregs[CCOUNT],
1000000, env->config->clock_freq_khz));
}
CPUState *cs = CPU(cpu);
if (cs->halted) {
- env->halt_clock = qemu_get_clock_ns(vm_clock);
+ env->halt_clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]);
if (!cpu_has_work(cs)) {
env->sregs[CCOUNT] = env->wake_ccount + 1;
if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT) &&
env->config->nccompare > 0) {
env->ccompare_timer =
- qemu_new_timer_ns(vm_clock, &xtensa_ccompare_cb, cpu);
+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &xtensa_ccompare_cb, cpu);
}
}
#ifndef QEMU_AIO_H
#define QEMU_AIO_H
+#include "qemu/typedefs.h"
#include "qemu-common.h"
#include "qemu/queue.h"
#include "qemu/event_notifier.h"
#include "qemu/thread.h"
+#include "qemu/timer.h"
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
typedef void BlockDriverCompletionFunc(void *opaque, int ret);
typedef void QEMUBHFunc(void *opaque);
typedef void IOHandler(void *opaque);
-typedef struct AioContext {
+struct AioContext {
GSource source;
/* The list of registered AIO handlers */
/* Thread pool for performing work and receiving completion callbacks */
struct ThreadPool *thread_pool;
-} AioContext;
+
+ /* TimerLists for calling timers - one per clock type */
+ QEMUTimerListGroup tlg;
+};
/**
* aio_context_new: Allocate a new AioContext.
void *opaque);
#endif
+/**
+ * aio_timer_new:
+ * @ctx: the aio context
+ * @type: the clock type
+ * @scale: the scale
+ * @cb: the callback to call on timer expiry
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Allocate a new timer attached to the context @ctx.
+ * The function is responsible for memory allocation.
+ *
+ * The preferred interface is aio_timer_init. Use that
+ * unless you really need dynamic memory allocation.
+ *
+ * Returns: a pointer to the new timer
+ */
+static inline QEMUTimer *aio_timer_new(AioContext *ctx, QEMUClockType type,
+ int scale,
+ QEMUTimerCB *cb, void *opaque)
+{
+ return timer_new_tl(ctx->tlg.tl[type], scale, cb, opaque);
+}
+
+/**
+ * aio_timer_init:
+ * @ctx: the aio context
+ * @ts: the timer
+ * @type: the clock type
+ * @scale: the scale
+ * @cb: the callback to call on timer expiry
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialise a new timer attached to the context @ctx.
+ * The caller is responsible for memory allocation.
+ */
+static inline void aio_timer_init(AioContext *ctx,
+ QEMUTimer *ts, QEMUClockType type,
+ int scale,
+ QEMUTimerCB *cb, void *opaque)
+{
+ timer_init(ts, ctx->tlg.tl[type], scale, cb, opaque);
+}
+
#endif
#include "monitor/monitor.h"
#include "qemu/hbitmap.h"
#include "block/snapshot.h"
+#include "qemu/main-loop.h"
#define BLOCK_FLAG_ENCRYPT 1
#define BLOCK_FLAG_COMPAT6 4
/* Whether the disk can expand beyond total_sectors */
int growable;
+ /* Whether produces zeros when read beyond eof */
+ bool zero_beyond_eof;
+
/* the memory alignment required for the buffers handled by this driver */
int buffer_alignment;
* Put the job to sleep (assuming that it wasn't canceled) for @ns
* nanoseconds. Canceling the job will interrupt the wait immediately.
*/
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns);
+void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns);
/**
* block_job_completed:
#define QEMU_COROUTINE_H
#include <stdbool.h>
+#include "qemu/typedefs.h"
#include "qemu/queue.h"
#include "qemu/timer.h"
* Note this function uses timers and hence only works when a main loop is in
* use. See main-loop.h and do not use from qemu-tool programs.
*/
-void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns);
+void coroutine_fn co_sleep_ns(QEMUClockType type, int64_t ns);
/**
* Yield until a file descriptor becomes readable
(6) jump to corresponding code of the next of fast path
*/
# if defined(__i386__) || defined(__x86_64__)
-/* To avoid broken disassembling, long jmp is used for embedding fast path pc,
- so that the destination is the next code of fast path, though this jmp is
- never executed.
-
- call MMU helper
- jmp POST_PROC (2byte) <- GETRA()
- jmp NEXT_CODE (5byte)
- POST_PROCESS ... <- GETRA() + 7
- */
-# define GETRA() ((uintptr_t)__builtin_return_address(0))
-# define GETPC_LDST() ((uintptr_t)(GETRA() + 7 + \
- *(int32_t *)((void *)GETRA() + 3) - 1))
+# define GETPC_EXT() GETPC()
# elif defined (_ARCH_PPC) && !defined (_ARCH_PPC64)
# define GETRA() ((uintptr_t)__builtin_return_address(0))
# define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1))
not the start of the next opcode */
return ra;
}
-#elif defined(__aarch64__)
+# elif defined(__aarch64__)
# define GETRA() ((uintptr_t)__builtin_return_address(0))
# define GETPC_LDST() tcg_getpc_ldst(GETRA())
static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
# error "CONFIG_QEMU_LDST_OPTIMIZATION needs GETPC_LDST() implementation!"
# endif
bool is_tcg_gen_code(uintptr_t pc_ptr);
-# define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC())
+# ifndef GETPC_EXT
+# define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC())
+# endif
#else
# define GETPC_EXT() GETPC()
#endif
#ifndef SOFTMMU_DEFS_H
#define SOFTMMU_DEFS_H
+uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr,
+ int mmu_idx, uintptr_t retaddr);
+uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr,
+ int mmu_idx, uintptr_t retaddr);
+uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr,
+ int mmu_idx, uintptr_t retaddr);
+uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr,
+ int mmu_idx, uintptr_t retaddr);
+
+void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
+ int mmu_idx, uintptr_t retaddr);
+void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
+ int mmu_idx, uintptr_t retaddr);
+void helper_ret_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
+ int mmu_idx, uintptr_t retaddr);
+void helper_ret_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
+ int mmu_idx, uintptr_t retaddr);
+
uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
- int mmu_idx);
uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
- int mmu_idx);
uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
- int mmu_idx);
uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
- int mmu_idx);
+
+void helper_stb_mmu(CPUArchState *env, target_ulong addr,
+ uint8_t val, int mmu_idx);
+void helper_stw_mmu(CPUArchState *env, target_ulong addr,
+ uint16_t val, int mmu_idx);
+void helper_stl_mmu(CPUArchState *env, target_ulong addr,
+ uint32_t val, int mmu_idx);
+void helper_stq_mmu(CPUArchState *env, target_ulong addr,
+ uint64_t val, int mmu_idx);
uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stb_cmmu(CPUArchState *env, target_ulong addr, uint8_t val,
-int mmu_idx);
uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stw_cmmu(CPUArchState *env, target_ulong addr, uint16_t val,
- int mmu_idx);
uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stl_cmmu(CPUArchState *env, target_ulong addr, uint32_t val,
- int mmu_idx);
uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
- int mmu_idx);
-#endif
+
+#endif /* SOFTMMU_DEFS_H */
#define ADDR_READ addr_read
#endif
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
- target_ulong addr,
- int mmu_idx,
- uintptr_t retaddr);
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
hwaddr physaddr,
target_ulong addr,
}
/* handle all cases except unaligned access which span two pages */
+#ifdef SOFTMMU_CODE_ACCESS
+static
+#endif
DATA_TYPE
-glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
- int mmu_idx)
+glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+ target_ulong addr, int mmu_idx,
+ uintptr_t retaddr)
{
- DATA_TYPE res;
- int index;
- target_ulong tlb_addr;
- hwaddr ioaddr;
- uintptr_t retaddr;
+ int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+ target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
+ uintptr_t haddr;
- /* test if there is match for unaligned or IO access */
- /* XXX: could done more in memory macro in a non portable way */
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- retaddr = GETPC_EXT();
- ioaddr = env->iotlb[mmu_idx][index];
- res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- /* slow unaligned access (it spans two pages or IO) */
- do_unaligned_access:
- retaddr = GETPC_EXT();
+ /* If the TLB entry is for a different page, reload and try again. */
+ if ((addr & TARGET_PAGE_MASK)
+ != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0) {
do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
-#endif
- res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr,
- mmu_idx, retaddr);
- } else {
- /* unaligned/aligned access in the same page */
- uintptr_t addend;
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0) {
- retaddr = GETPC_EXT();
- do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
- }
-#endif
- addend = env->tlb_table[mmu_idx][index].addend;
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
- (addr + addend));
}
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC_EXT();
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0)
- do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
#endif
tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
- goto redo;
+ tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
}
- return res;
-}
-/* handle all unaligned cases */
-static DATA_TYPE
-glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
- target_ulong addr,
- int mmu_idx,
- uintptr_t retaddr)
-{
- DATA_TYPE res, res1, res2;
- int index, shift;
- hwaddr ioaddr;
- target_ulong tlb_addr, addr1, addr2;
+ /* Handle an IO access. */
+ if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
+ hwaddr ioaddr;
+ if ((addr & (DATA_SIZE - 1)) != 0) {
+ goto do_unaligned_access;
+ }
+ ioaddr = env->iotlb[mmu_idx][index];
+ return glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
+ }
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- ioaddr = env->iotlb[mmu_idx][index];
- res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- /* slow unaligned access (it spans two pages) */
- addr1 = addr & ~(DATA_SIZE - 1);
- addr2 = addr1 + DATA_SIZE;
- res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr1,
- mmu_idx, retaddr);
- res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr2,
- mmu_idx, retaddr);
- shift = (addr & (DATA_SIZE - 1)) * 8;
+ /* Handle slow unaligned access (it spans two pages or IO). */
+ if (DATA_SIZE > 1
+ && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
+ >= TARGET_PAGE_SIZE)) {
+ target_ulong addr1, addr2;
+ DATA_TYPE res1, res2, res;
+ unsigned shift;
+ do_unaligned_access:
+#ifdef ALIGNED_ONLY
+ do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+#endif
+ addr1 = addr & ~(DATA_SIZE - 1);
+ addr2 = addr1 + DATA_SIZE;
+ res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr1,
+ mmu_idx, retaddr);
+ res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr2,
+ mmu_idx, retaddr);
+ shift = (addr & (DATA_SIZE - 1)) * 8;
#ifdef TARGET_WORDS_BIGENDIAN
- res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
+ res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
#else
- res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
+ res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
#endif
- res = (DATA_TYPE)res;
- } else {
- /* unaligned/aligned access in the same page */
- uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
- (addr + addend));
- }
- } else {
- /* the page is not in the TLB : fill it */
- tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
- goto redo;
+ return res;
+ }
+
+ /* Handle aligned access or unaligned access in the same page. */
+#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0) {
+ do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
}
- return res;
+#endif
+
+ haddr = addr + env->tlb_table[mmu_idx][index].addend;
+ return glue(glue(ld, USUFFIX), _raw)((uint8_t *)haddr);
}
-#ifndef SOFTMMU_CODE_ACCESS
+DATA_TYPE
+glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
+ int mmu_idx)
+{
+ return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
+ GETPC_EXT());
+}
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
- target_ulong addr,
- DATA_TYPE val,
- int mmu_idx,
- uintptr_t retaddr);
+#ifndef SOFTMMU_CODE_ACCESS
static inline void glue(io_write, SUFFIX)(CPUArchState *env,
hwaddr physaddr,
io_mem_write(mr, physaddr, val, 1 << SHIFT);
}
-void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
- target_ulong addr, DATA_TYPE val,
- int mmu_idx)
+void
+glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+ target_ulong addr, DATA_TYPE val,
+ int mmu_idx, uintptr_t retaddr)
{
- hwaddr ioaddr;
- target_ulong tlb_addr;
- uintptr_t retaddr;
- int index;
+ int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+ target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
+ uintptr_t haddr;
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- retaddr = GETPC_EXT();
- ioaddr = env->iotlb[mmu_idx][index];
- glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- retaddr = GETPC_EXT();
+ /* If the TLB entry is for a different page, reload and try again. */
+ if ((addr & TARGET_PAGE_MASK)
+ != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0) {
do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
-#endif
- glue(glue(slow_st, SUFFIX), MMUSUFFIX)(env, addr, val,
- mmu_idx, retaddr);
- } else {
- /* aligned/unaligned access in the same page */
- uintptr_t addend;
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0) {
- retaddr = GETPC_EXT();
- do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
- }
-#endif
- addend = env->tlb_table[mmu_idx][index].addend;
- glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
- (addr + addend), val);
}
- } else {
- /* the page is not in the TLB : fill it */
- retaddr = GETPC_EXT();
-#ifdef ALIGNED_ONLY
- if ((addr & (DATA_SIZE - 1)) != 0)
- do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
#endif
tlb_fill(env, addr, 1, mmu_idx, retaddr);
- goto redo;
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
}
-}
-/* handles all unaligned cases */
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
- target_ulong addr,
- DATA_TYPE val,
- int mmu_idx,
- uintptr_t retaddr)
-{
- hwaddr ioaddr;
- target_ulong tlb_addr;
- int index, i;
+ /* Handle an IO access. */
+ if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
+ hwaddr ioaddr;
+ if ((addr & (DATA_SIZE - 1)) != 0) {
+ goto do_unaligned_access;
+ }
+ ioaddr = env->iotlb[mmu_idx][index];
+ glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
+ return;
+ }
- index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
- tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
- if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- if (tlb_addr & ~TARGET_PAGE_MASK) {
- /* IO access */
- if ((addr & (DATA_SIZE - 1)) != 0)
- goto do_unaligned_access;
- ioaddr = env->iotlb[mmu_idx][index];
- glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
- } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
- do_unaligned_access:
- /* XXX: not efficient, but simple */
- /* Note: relies on the fact that tlb_fill() does not remove the
- * previous page from the TLB cache. */
- for(i = DATA_SIZE - 1; i >= 0; i--) {
+ /* Handle slow unaligned access (it spans two pages or IO). */
+ if (DATA_SIZE > 1
+ && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
+ >= TARGET_PAGE_SIZE)) {
+ int i;
+ do_unaligned_access:
+#ifdef ALIGNED_ONLY
+ do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
+#endif
+ /* XXX: not efficient, but simple */
+ /* Note: relies on the fact that tlb_fill() does not remove the
+ * previous page from the TLB cache. */
+ for (i = DATA_SIZE - 1; i >= 0; i--) {
#ifdef TARGET_WORDS_BIGENDIAN
- glue(slow_stb, MMUSUFFIX)(env, addr + i,
- val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
- mmu_idx, retaddr);
+ uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
#else
- glue(slow_stb, MMUSUFFIX)(env, addr + i,
- val >> (i * 8),
- mmu_idx, retaddr);
+ uint8_t val8 = val >> (i * 8);
#endif
- }
- } else {
- /* aligned/unaligned access in the same page */
- uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
- glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
- (addr + addend), val);
+ glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
+ mmu_idx, retaddr);
}
- } else {
- /* the page is not in the TLB : fill it */
- tlb_fill(env, addr, 1, mmu_idx, retaddr);
- goto redo;
+ return;
+ }
+
+ /* Handle aligned access or unaligned access in the same page. */
+#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0) {
+ do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
}
+#endif
+
+ haddr = addr + env->tlb_table[mmu_idx][index].addend;
+ glue(glue(st, SUFFIX), _raw)((uint8_t *)haddr, val);
+}
+
+void
+glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
+ DATA_TYPE val, int mmu_idx)
+{
+ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx,
+ GETPC_EXT());
}
#endif /* !defined(SOFTMMU_CODE_ACCESS) */
#include "qemu/timer.h"
static inline int64_t acpi_pm_tmr_get_clock(void)
{
- return muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY,
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
get_ticks_per_sec());
}
#include "qapi/visitor.h"
#include "qemu/option.h"
+/* Inclusive upper bound on the size of any flattened range. This is a safety
+ * (= anti-annoyance) measure; wrong ranges should not cause long startup
+ * delays nor exhaust virtual memory.
+ */
+#define OPTS_VISITOR_RANGE_MAX 65536
+
typedef struct OptsVisitor OptsVisitor;
/* Contrarily to qemu-option.c::parse_option_number(), OptsVisitor's "int"
static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
{
- int64_t now = qemu_get_clock_ns(rt_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
if (limit->next_slice_time < now) {
limit->next_slice_time = now + limit->slice_ns;
#ifndef QEMU_TIMER_H
#define QEMU_TIMER_H
+#include "qemu/typedefs.h"
#include "qemu-common.h"
-#include "qemu/main-loop.h"
#include "qemu/notify.h"
/* timers */
#define SCALE_US 1000
#define SCALE_NS 1
-typedef struct QEMUClock QEMUClock;
+/**
+ * QEMUClockType:
+ *
+ * The following clock types are available:
+ *
+ * @QEMU_CLOCK_REALTIME: Real time clock
+ *
+ * The real time clock should be used only for stuff which does not
+ * change the virtual machine state, as it is run even if the virtual
+ * machine is stopped. The real time clock has a frequency of 1000
+ * Hz.
+ *
+ * @QEMU_CLOCK_VIRTUAL: virtual clock
+ *
+ * The virtual clock is only run during the emulation. It is stopped
+ * when the virtual machine is stopped. Virtual timers use a high
+ * precision clock, usually cpu cycles (use ticks_per_sec).
+ *
+ * @QEMU_CLOCK_HOST: host clock
+ *
+ * The host clock should be use for device models that emulate accurate
+ * real time sources. It will continue to run when the virtual machine
+ * 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
+ * the virtual clock.
+ */
+
+typedef enum {
+ QEMU_CLOCK_REALTIME = 0,
+ QEMU_CLOCK_VIRTUAL = 1,
+ QEMU_CLOCK_HOST = 2,
+ QEMU_CLOCK_MAX
+} QEMUClockType;
+
+typedef struct QEMUTimerList QEMUTimerList;
+
+struct QEMUTimerListGroup {
+ QEMUTimerList *tl[QEMU_CLOCK_MAX];
+};
+
typedef void QEMUTimerCB(void *opaque);
+typedef void QEMUTimerListNotifyCB(void *opaque);
+
+struct QEMUTimer {
+ int64_t expire_time; /* in nanoseconds */
+ QEMUTimerList *timer_list;
+ QEMUTimerCB *cb;
+ void *opaque;
+ QEMUTimer *next;
+ int scale;
+};
+
+extern QEMUTimerListGroup main_loop_tlg;
+
+/*
+ * QEMUClockType
+ */
+
+/*
+ * qemu_clock_get_ns;
+ * @type: the clock type
+ *
+ * Get the nanosecond value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in nanoseconds
+ */
+int64_t qemu_clock_get_ns(QEMUClockType type);
+
+/**
+ * qemu_clock_get_ms;
+ * @type: the clock type
+ *
+ * Get the millisecond value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in milliseconds
+ */
+static inline int64_t qemu_clock_get_ms(QEMUClockType type)
+{
+ return qemu_clock_get_ns(type) / SCALE_MS;
+}
+
+/**
+ * qemu_clock_get_us;
+ * @type: the clock type
+ *
+ * Get the microsecond value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in microseconds
+ */
+static inline int64_t qemu_clock_get_us(QEMUClockType type)
+{
+ return qemu_clock_get_ns(type) / SCALE_US;
+}
+
+/**
+ * qemu_clock_has_timers:
+ * @type: the clock type
+ *
+ * Determines whether a clock's default timer list
+ * has timers attached
+ *
+ * Returns: true if the clock's default timer list
+ * has timers attached
+ */
+bool qemu_clock_has_timers(QEMUClockType type);
+
+/**
+ * qemu_clock_expired:
+ * @type: the clock type
+ *
+ * Determines whether a clock's default timer list
+ * has an expired clock.
+ *
+ * Returns: true if the clock's default timer list has
+ * an expired timer
+ */
+bool qemu_clock_expired(QEMUClockType type);
+
+/**
+ * qemu_clock_use_for_deadline:
+ * @type: the clock type
+ *
+ * Determine whether a clock should be used for deadline
+ * calculations. Some clocks, for instance vm_clock with
+ * use_icount set, do not count in nanoseconds. Such clocks
+ * are not used for deadline calculations, and are presumed
+ * to interrupt any poll using qemu_notify/aio_notify
+ * etc.
+ *
+ * Returns: true if the clock runs in nanoseconds and
+ * should be used for a deadline.
+ */
+bool qemu_clock_use_for_deadline(QEMUClockType type);
+
+/**
+ * qemu_clock_deadline_ns_all:
+ * @type: the clock type
+ *
+ * Calculate the deadline across all timer lists associated
+ * with a clock (as opposed to just the default one)
+ * 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_all(QEMUClockType type);
+
+/**
+ * qemu_clock_get_main_loop_timerlist:
+ * @type: the clock type
+ *
+ * Return the default timer list assocatiated with a clock.
+ *
+ * Returns: the default timer list
+ */
+QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type);
-/* The real time clock should be used only for stuff which does not
- change the virtual machine state, as it is run even if the virtual
- machine is stopped. The real time clock has a frequency of 1000
- Hz. */
-extern QEMUClock *rt_clock;
-
-/* The virtual clock is only run during the emulation. It is stopped
- when the virtual machine is stopped. Virtual timers use a high
- precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
-
-/* The host clock should be use for device models that emulate accurate
- real time sources. It will continue to run when the virtual machine
- 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
- the virtual clock. */
-extern QEMUClock *host_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);
-void qemu_clock_enable(QEMUClock *clock, bool enabled);
-void qemu_clock_warp(QEMUClock *clock);
-
-void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
-void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
+/**
+ * qemu_clock_nofify:
+ * @type: the clock type
+ *
+ * Call the notifier callback connected with the default timer
+ * list linked to the clock, or qemu_notify() if none.
+ */
+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);
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
- QEMUTimerCB *cb, void *opaque);
-void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-bool qemu_timer_pending(QEMUTimer *ts);
-bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
-uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
-
-void qemu_run_timers(QEMUClock *clock);
-void qemu_run_all_timers(void);
-void configure_alarms(char const *opt);
-void init_clocks(void);
-int init_timer_alarm(void);
+/**
+ * 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);
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
+/**
+ * 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:
+ * @type: the clock type to associate with the timerlist
+ * @cb: the callback to call on notification
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timerlist associated with the clock of
+ * type @type.
+ *
+ * Returns: a pointer to the QEMUTimerList created
+ */
+QEMUTimerList *timerlist_new(QEMUClockType type,
+ QEMUTimerListNotifyCB *cb, void *opaque);
+
+/**
+ * timerlist_free:
+ * @timer_list: the timer list to free
+ *
+ * Frees a timer_list. It must have no active timers.
+ */
+void timerlist_free(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_has_timers:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine whether a timer list has active timers
+ *
+ * Returns: true if the timer list has timers.
+ */
+bool timerlist_has_timers(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_expired:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine whether a timer list has any timers which
+ * are expired.
+ *
+ * Returns: true if the timer list has timers which
+ * have expired.
+ */
+bool timerlist_expired(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_deadline_ns:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine the deadline for a timer_list, i.e.
+ * the number of nanoseconds until the first timer
+ * expires. Return -1 if there are no timers.
+ *
+ * Returns: the number of nanoseconds until the earliest
+ * timer expires -1 if none
+ */
+int64_t timerlist_deadline_ns(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_get_clock:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine the clock type associated with a timer list.
+ *
+ * Returns: the clock type associated with the
+ * timer list.
+ */
+QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_run_timers:
+ * @timer_list: the timer list to use
+ *
+ * Call all expired timers associated with the timer list.
+ *
+ * Returns: true if any timer expired
+ */
+bool timerlist_run_timers(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_notify:
+ * @timer_list: the timer list to use
+ *
+ * call the notifier callback associated with the timer list.
+ */
+void timerlist_notify(QEMUTimerList *timer_list);
+
+/*
+ * QEMUTimerListGroup
+ */
+
+/**
+ * timerlistgroup_init:
+ * @tlg: the timer list group
+ * @cb: the callback to call when a notify is required
+ * @opaque: the opaque pointer to be passed to the callback.
+ *
+ * Initialise a timer list group. This must already be
+ * allocated in memory and zeroed. The notifier callback is
+ * called whenever a clock in the timer list group is
+ * reenabled or whenever a timer associated with any timer
+ * list is modified. If @cb is specified as null, qemu_notify()
+ * is used instead.
+ */
+void timerlistgroup_init(QEMUTimerListGroup *tlg,
+ QEMUTimerListNotifyCB *cb, void *opaque);
+
+/**
+ * timerlistgroup_deinit:
+ * @tlg: the timer list group
+ *
+ * Deinitialise a timer list group. This must already be
+ * initialised. Note the memory is not freed.
+ */
+void timerlistgroup_deinit(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_run_timers:
+ * @tlg: the timer list group
+ *
+ * Run the timers associated with a timer list group.
+ * This will run timers on multiple clocks.
+ *
+ * Returns: true if any timer callback ran
+ */
+bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_deadline_ns:
+ * @tlg: the timer list group
+ *
+ * Determine the deadline of the soonest timer to
+ * expire associated with any timer list linked to
+ * the timer list group. Only clocks suitable for
+ * deadline calculation are included.
+ *
+ * Returns: the deadline in nanoseconds or -1 if no
+ * timers are to expire.
+ */
+int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
+
+/*
+ * QEMUTimer
+ */
+
+/**
+ * timer_init:
+ * @ts: the timer to be initialised
+ * @timer_list: the timer list to attach the timer to
+ * @scale: the scale value for the tiemr
+ * @cb: the callback to be called when the timer expires
+ * @opaque: the opaque pointer to be passed to the callback
+ *
+ * Initialise a new timer and associate it with @timer_list.
+ * The caller is responsible for allocating the memory.
+ *
+ * You need not call an explicit deinit call. Simply make
+ * sure it is not on a list with timer_del.
+ */
+void timer_init(QEMUTimer *ts,
+ QEMUTimerList *timer_list, int scale,
+ QEMUTimerCB *cb, void *opaque);
+
+/**
+ * timer_new_tl:
+ * @timer_list: the timer list to attach the timer to
+ * @scale: the scale value for the tiemr
+ * @cb: the callback to be called when the timer expires
+ * @opaque: the opaque pointer to be passed to the callback
+ *
+ * Creeate a new timer and associate it with @timer_list.
+ * The memory is allocated by the function.
+ *
+ * This is not the preferred interface unless you know you
+ * are going to call timer_free. Use timer_init instead.
+ *
+ * Returns: a pointer to the timer
+ */
+static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list,
+ int scale,
+ QEMUTimerCB *cb,
+ void *opaque)
+{
+ QEMUTimer *ts = g_malloc0(sizeof(QEMUTimer));
+ timer_init(ts, timer_list, scale, cb, opaque);
+ return ts;
+}
-static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
- void *opaque)
+/**
+ * timer_new:
+ * @type: the clock type to use
+ * @scale: the scale value for the tiemr
+ * @cb: the callback to be called when the timer expires
+ * @opaque: the opaque pointer to be passed to the callback
+ *
+ * Creeate a new timer and associate it with the default
+ * timer list for the clock type @type.
+ *
+ * Returns: a pointer to the timer
+ */
+static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
+ QEMUTimerCB *cb, void *opaque)
{
- return qemu_new_timer(clock, SCALE_NS, cb, opaque);
+ return timer_new_tl(main_loop_tlg.tl[type], scale, cb, opaque);
}
-static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb,
- void *opaque)
+/**
+ * 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 qemu_new_timer(clock, SCALE_MS, cb, opaque);
+ return timer_new(type, SCALE_NS, cb, opaque);
}
-static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
+/**
+ * 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 qemu_get_clock_ns(clock) / SCALE_MS;
+ 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:
+ * @ts: the timer
+ *
+ * Free a timer (it must not be on the active list)
+ */
+void timer_free(QEMUTimer *ts);
+
+/**
+ * timer_del:
+ * @ts: the timer
+ *
+ * Delete a timer from the active list.
+ */
+void timer_del(QEMUTimer *ts);
+
+/**
+ * timer_mod_ns:
+ * @ts: the timer
+ * @expire_time: the expiry time in nanoseconds
+ *
+ * Modify a timer to expire at @expire_time
+ */
+void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
+
+/**
+ * timer_mod:
+ * @ts: the timer
+ * @expire_time: the expire time in the units associated with the timer
+ *
+ * Modify a timer to expiry at @expire_time, taking into
+ * account the scale associated with the timer.
+ */
+void timer_mod(QEMUTimer *ts, int64_t expire_timer);
+
+/**
+ * timer_pending:
+ * @ts: the timer
+ *
+ * Determines whether a timer is pending (i.e. is on the
+ * active list of timers, whether or not it has not yet expired).
+ *
+ * Returns: true if the timer is pending
+ */
+bool timer_pending(QEMUTimer *ts);
+
+/**
+ * timer_expired:
+ * @ts: the timer
+ *
+ * Determines whether a timer has expired.
+ *
+ * Returns: true if the timer has expired
+ */
+bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
+
+/**
+ * timer_expire_time_ns:
+ * @ts: the timer
+ *
+ * Determine the expiry time of a timer
+ *
+ * Returns: the expiry time in nanoseconds
+ */
+uint64_t timer_expire_time_ns(QEMUTimer *ts);
+
+/**
+ * timer_get:
+ * @f: the file
+ * @ts: the timer
+ *
+ * Read a timer @ts from a file @f
+ */
+void timer_get(QEMUFile *f, QEMUTimer *ts);
+
+/**
+ * timer_put:
+ * @f: the file
+ * @ts: the timer
+ */
+void timer_put(QEMUFile *f, QEMUTimer *ts);
+
+/*
+ * General utility functions
+ */
+
+/**
+ * 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);
+
+/**
+ * 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_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;
+}
+
+/**
+ * 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;
}
+/*
+ * Low level clock functions
+ */
+
/* real time host monotonic timer */
static inline int64_t get_clock_realtime(void)
{
}
#endif
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
/* icount */
int64_t cpu_get_icount(void);
int64_t cpu_get_clock(void);
/* A load of opaque types so that device init declarations don't have to
pull in all the real definitions. */
typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUTimerListGroup QEMUTimerListGroup;
typedef struct QEMUFile QEMUFile;
typedef struct QEMUBH QEMUBH;
+typedef struct AioContext AioContext;
+
struct Monitor;
typedef struct Monitor Monitor;
typedef struct MigrationParams MigrationParams;
extern uint8_t *boot_splash_filedata;
extern size_t boot_splash_filedata_size;
extern uint8_t qemu_extra_params_fw[2];
-extern QEMUClock *rtc_clock;
+extern QEMUClockType rtc_clock;
#define MAX_NODES 64
#define MAX_CPUMASK_BITS 255
GSource *src;
init_clocks();
- if (init_timer_alarm() < 0) {
- fprintf(stderr, "could not initialize alarm timer\n");
- exit(1);
- }
ret = qemu_signal_init();
if (ret) {
static int glib_pollfds_idx;
static int glib_n_poll_fds;
-static void glib_pollfds_fill(uint32_t *cur_timeout)
+static void glib_pollfds_fill(int64_t *cur_timeout)
{
GMainContext *context = g_main_context_default();
int timeout = 0;
+ int64_t timeout_ns;
int n;
g_main_context_prepare(context, &max_priority);
glib_n_poll_fds);
} while (n != glib_n_poll_fds);
- if (timeout >= 0 && timeout < *cur_timeout) {
- *cur_timeout = timeout;
+ if (timeout < 0) {
+ timeout_ns = -1;
+ } else {
+ timeout_ns = (int64_t)timeout * (int64_t)SCALE_MS;
}
+
+ *cur_timeout = qemu_soonest_timeout(timeout_ns, *cur_timeout);
}
static void glib_pollfds_poll(void)
#define MAX_MAIN_LOOP_SPIN (1000)
-static int os_host_main_loop_wait(uint32_t timeout)
+static int os_host_main_loop_wait(int64_t timeout)
{
int ret;
static int spin_counter;
* print a message to the screen. If we run into this condition, create
* a fake timeout in order to give the VCPU threads a chance to run.
*/
- if (spin_counter > MAX_MAIN_LOOP_SPIN) {
+ if (!timeout && (spin_counter > MAX_MAIN_LOOP_SPIN)) {
static bool notified;
if (!notified) {
notified = true;
}
- timeout = 1;
+ timeout = SCALE_MS;
}
- if (timeout > 0) {
+ if (timeout) {
spin_counter = 0;
qemu_mutex_unlock_iothread();
} else {
spin_counter++;
}
- ret = g_poll((GPollFD *)gpollfds->data, gpollfds->len, timeout);
+ ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout);
- if (timeout > 0) {
+ if (timeout) {
qemu_mutex_lock_iothread();
}
}
}
-static int os_host_main_loop_wait(uint32_t timeout)
+static int os_host_main_loop_wait(int64_t timeout)
{
GMainContext *context = g_main_context_default();
GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
PollingEntry *pe;
WaitObjects *w = &wait_objects;
gint poll_timeout;
+ int64_t poll_timeout_ns;
static struct timeval tv0;
fd_set rfds, wfds, xfds;
int nfds;
poll_fds[n_poll_fds + i].events = G_IO_IN;
}
- if (poll_timeout < 0 || timeout < poll_timeout) {
- poll_timeout = timeout;
+ if (poll_timeout < 0) {
+ poll_timeout_ns = -1;
+ } else {
+ poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
}
+ poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);
+
qemu_mutex_unlock_iothread();
- g_poll_ret = g_poll(poll_fds, n_poll_fds + w->num, poll_timeout);
+ g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);
+
qemu_mutex_lock_iothread();
if (g_poll_ret > 0) {
for (i = 0; i < w->num; i++) {
{
int ret;
uint32_t timeout = UINT32_MAX;
+ int64_t timeout_ns;
if (nonblocking) {
timeout = 0;
slirp_pollfds_fill(gpollfds);
#endif
qemu_iohandler_fill(gpollfds);
- ret = os_host_main_loop_wait(timeout);
+
+ if (timeout == UINT32_MAX) {
+ timeout_ns = -1;
+ } else {
+ timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS);
+ }
+
+ timeout_ns = qemu_soonest_timeout(timeout_ns,
+ timerlistgroup_deadline_ns(
+ &main_loop_tlg));
+
+ ret = os_host_main_loop_wait(timeout_ns);
qemu_iohandler_poll(gpollfds, ret);
#ifdef CONFIG_SLIRP
slirp_pollfds_poll(gpollfds, (ret < 0));
#endif
- qemu_run_all_timers();
+ qemu_clock_run_all_timers();
return ret;
}
#include "qemu-common.h"
#include "qemu/sockets.h"
+#include "qemu/main-loop.h"
#include "migration/migration.h"
#include "migration/qemu-file.h"
#include "block/block.h"
*/
#include "qemu-common.h"
+#include "qemu/main-loop.h"
#include "qemu/sockets.h"
#include "migration/migration.h"
#include "monitor/monitor.h"
#include "migration/migration.h"
#include "migration/qemu-file.h"
#include "block/block.h"
+#include "qemu/main-loop.h"
//#define DEBUG_MIGRATION_TCP
#include "qemu-common.h"
#include "qemu/sockets.h"
+#include "qemu/main-loop.h"
#include "migration/migration.h"
#include "migration/qemu-file.h"
#include "block/block.h"
*/
#include "qemu-common.h"
+#include "qemu/main-loop.h"
#include "migration/migration.h"
#include "monitor/monitor.h"
#include "migration/qemu-file.h"
info->has_status = true;
info->status = g_strdup("active");
info->has_total_time = true;
- info->total_time = qemu_get_clock_ms(rt_clock)
+ info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
- s->total_time;
info->has_expected_downtime = true;
info->expected_downtime = s->expected_downtime;
s->state = MIG_STATE_SETUP;
trace_migrate_set_state(MIG_STATE_SETUP);
- s->total_time = qemu_get_clock_ms(rt_clock);
+ s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
return s;
}
static void *migration_thread(void *opaque)
{
MigrationState *s = opaque;
- int64_t initial_time = qemu_get_clock_ms(rt_clock);
- int64_t setup_start = qemu_get_clock_ms(host_clock);
+ int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
int64_t initial_bytes = 0;
int64_t max_size = 0;
int64_t start_time = initial_time;
DPRINTF("beginning savevm\n");
qemu_savevm_state_begin(s->file, &s->params);
- s->setup_time = qemu_get_clock_ms(host_clock) - setup_start;
+ s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
migrate_set_state(s, MIG_STATE_SETUP, MIG_STATE_ACTIVE);
DPRINTF("setup complete\n");
DPRINTF("done iterating\n");
qemu_mutex_lock_iothread();
- start_time = qemu_get_clock_ms(rt_clock);
+ start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
old_vm_running = runstate_is_running();
migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR);
break;
}
- current_time = qemu_get_clock_ms(rt_clock);
+ current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
if (current_time >= initial_time + BUFFER_DELAY) {
uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
uint64_t time_spent = current_time - initial_time;
qemu_mutex_lock_iothread();
if (s->state == MIG_STATE_COMPLETED) {
- int64_t end_time = qemu_get_clock_ms(rt_clock);
+ int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
s->total_time = end_time - s->total_time;
s->downtime = end_time - start_time;
runstate_set(RUN_STATE_POSTMIGRATE);
QObject *data)
{
MonitorEventState *evstate;
- int64_t now = qemu_get_clock_ns(rt_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
assert(event < QEVENT_MAX);
qemu_mutex_lock(&monitor_event_state_lock);
qobject_decref(evstate->data);
} else {
int64_t then = evstate->last + evstate->rate;
- qemu_mod_timer_ns(evstate->timer, then);
+ timer_mod_ns(evstate->timer, then);
}
evstate->data = data;
qobject_incref(evstate->data);
static void monitor_protocol_event_handler(void *opaque)
{
MonitorEventState *evstate = opaque;
- int64_t now = qemu_get_clock_ns(rt_clock);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
qemu_mutex_lock(&monitor_event_state_lock);
trace_monitor_protocol_event_throttle(event, rate);
evstate->event = event;
evstate->rate = rate * SCALE_MS;
- evstate->timer = qemu_new_timer(rt_clock,
+ evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
SCALE_MS,
monitor_protocol_event_handler,
evstate);
{ NULL },
};
-static void expr_error(Monitor *mon, const char *msg)
+static void expr_error(Monitor *mon, const char *fmt, ...)
{
- monitor_printf(mon, "%s\n", msg);
+ va_list ap;
+ va_start(ap, fmt);
+ monitor_vprintf(mon, fmt, ap);
+ monitor_printf(mon, "\n");
+ va_end(ap);
siglongjmp(expr_env, 1);
}
expr_error(mon, "number too large");
}
if (pch == p) {
- expr_error(mon, "invalid char in expression");
+ expr_error(mon, "invalid char '%c' in expression", *p);
}
pch = p;
while (qemu_isspace(*pch))
#include "qemu/sockets.h"
#include "qemu/queue.h"
+#include "qemu/main-loop.h"
//#define DEBUG_NBD
return size;
}
- ts = muldiv64(qemu_get_clock_ns(vm_clock), 1000000, get_ticks_per_sec());
+ ts = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 1000000, get_ticks_per_sec());
caplen = size > s->pcap_caplen ? s->pcap_caplen : size;
hdr.ts.tv_sec = ts / 1000000 + s->start_ts;
#include "qmp-commands.h"
#include "hw/qdev.h"
#include "qemu/iov.h"
+#include "qemu/main-loop.h"
#include "qapi-visit.h"
#include "qapi/opts-visitor.h"
#include "qapi/dealloc-visitor.h"
#include "qemu/option.h"
#include "qemu/sockets.h"
#include "qemu/iov.h"
+#include "qemu/main-loop.h"
typedef struct NetSocketState {
NetClientState nc;
/*
* Options Visitor
*
- * Copyright Red Hat, Inc. 2012
+ * Copyright Red Hat, Inc. 2012, 2013
*
* Author: Laszlo Ersek <lersek@redhat.com>
*
#include "qapi/visitor-impl.h"
+enum ListMode
+{
+ LM_NONE, /* not traversing a list of repeated options */
+ LM_STARTED, /* opts_start_list() succeeded */
+
+ LM_IN_PROGRESS, /* opts_next_list() has been called.
+ *
+ * Generating the next list link will consume the most
+ * recently parsed QemuOpt instance of the repeated
+ * option.
+ *
+ * Parsing a value into the list link will examine the
+ * next QemuOpt instance of the repeated option, and
+ * possibly enter LM_SIGNED_INTERVAL or
+ * LM_UNSIGNED_INTERVAL.
+ */
+
+ LM_SIGNED_INTERVAL, /* opts_next_list() has been called.
+ *
+ * Generating the next list link will consume the most
+ * recently stored element from the signed interval,
+ * parsed from the most recent QemuOpt instance of the
+ * repeated option. This may consume QemuOpt itself
+ * and return to LM_IN_PROGRESS.
+ *
+ * Parsing a value into the list link will store the
+ * next element of the signed interval.
+ */
+
+ LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */
+};
+
+typedef enum ListMode ListMode;
+
struct OptsVisitor
{
Visitor visitor;
/* The list currently being traversed with opts_start_list() /
* opts_next_list(). The list must have a struct element type in the
* schema, with a single mandatory scalar member. */
+ ListMode list_mode;
GQueue *repeated_opts;
- bool repeated_opts_first;
+
+ /* When parsing a list of repeating options as integers, values of the form
+ * "a-b", representing a closed interval, are allowed. Elements in the
+ * range are generated individually.
+ */
+ union {
+ int64_t s;
+ uint64_t u;
+ } range_next, range_limit;
/* If "opts_root->id" is set, reinstantiate it as a fake QemuOpt for
* uniformity. Only its "name" and "str" fields are set. "fake_id_opt" does
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
/* we can't traverse a list in a list */
- assert(ov->repeated_opts == NULL);
+ assert(ov->list_mode == LM_NONE);
ov->repeated_opts = lookup_distinct(ov, name, errp);
- ov->repeated_opts_first = (ov->repeated_opts != NULL);
+ if (ov->repeated_opts != NULL) {
+ ov->list_mode = LM_STARTED;
+ }
}
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
GenericList **link;
- if (ov->repeated_opts_first) {
- ov->repeated_opts_first = false;
+ switch (ov->list_mode) {
+ case LM_STARTED:
+ ov->list_mode = LM_IN_PROGRESS;
link = list;
- } else {
+ break;
+
+ case LM_SIGNED_INTERVAL:
+ case LM_UNSIGNED_INTERVAL:
+ link = &(*list)->next;
+
+ if (ov->list_mode == LM_SIGNED_INTERVAL) {
+ if (ov->range_next.s < ov->range_limit.s) {
+ ++ov->range_next.s;
+ break;
+ }
+ } else if (ov->range_next.u < ov->range_limit.u) {
+ ++ov->range_next.u;
+ break;
+ }
+ ov->list_mode = LM_IN_PROGRESS;
+ /* range has been completed, fall through in order to pop option */
+
+ case LM_IN_PROGRESS: {
const QemuOpt *opt;
opt = g_queue_pop_head(ov->repeated_opts);
return NULL;
}
link = &(*list)->next;
+ break;
+ }
+
+ default:
+ abort();
}
*link = g_malloc0(sizeof **link);
{
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+ assert(ov->list_mode == LM_STARTED ||
+ ov->list_mode == LM_IN_PROGRESS ||
+ ov->list_mode == LM_SIGNED_INTERVAL ||
+ ov->list_mode == LM_UNSIGNED_INTERVAL);
ov->repeated_opts = NULL;
+ ov->list_mode = LM_NONE;
}
static const QemuOpt *
lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp)
{
- if (ov->repeated_opts == NULL) {
+ if (ov->list_mode == LM_NONE) {
GQueue *list;
/* the last occurrence of any QemuOpt takes effect when queried by name
list = lookup_distinct(ov, name, errp);
return list ? g_queue_peek_tail(list) : NULL;
}
+ assert(ov->list_mode == LM_IN_PROGRESS);
return g_queue_peek_head(ov->repeated_opts);
}
static void
processed(OptsVisitor *ov, const char *name)
{
- if (ov->repeated_opts == NULL) {
+ if (ov->list_mode == LM_NONE) {
g_hash_table_remove(ov->unprocessed_opts, name);
+ return;
}
+ assert(ov->list_mode == LM_IN_PROGRESS);
+ /* do nothing */
}
long long val;
char *endptr;
+ if (ov->list_mode == LM_SIGNED_INTERVAL) {
+ *obj = ov->range_next.s;
+ return;
+ }
+
opt = lookup_scalar(ov, name, errp);
if (!opt) {
return;
}
str = opt->str ? opt->str : "";
+ /* we've gotten past lookup_scalar() */
+ assert(ov->list_mode == LM_NONE || ov->list_mode == LM_IN_PROGRESS);
+
errno = 0;
val = strtoll(str, &endptr, 0);
- if (*str != '\0' && *endptr == '\0' && errno == 0 && INT64_MIN <= val &&
- val <= INT64_MAX) {
- *obj = val;
- processed(ov, name);
- return;
+ if (errno == 0 && endptr > str && INT64_MIN <= val && val <= INT64_MAX) {
+ if (*endptr == '\0') {
+ *obj = val;
+ processed(ov, name);
+ return;
+ }
+ if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) {
+ long long val2;
+
+ str = endptr + 1;
+ val2 = strtoll(str, &endptr, 0);
+ if (errno == 0 && endptr > str && *endptr == '\0' &&
+ INT64_MIN <= val2 && val2 <= INT64_MAX && val <= val2 &&
+ (val > INT64_MAX - OPTS_VISITOR_RANGE_MAX ||
+ val2 < val + OPTS_VISITOR_RANGE_MAX)) {
+ ov->range_next.s = val;
+ ov->range_limit.s = val2;
+ ov->list_mode = LM_SIGNED_INTERVAL;
+
+ /* as if entering on the top */
+ *obj = ov->range_next.s;
+ return;
+ }
+ }
}
- error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, "an int64 value");
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
+ (ov->list_mode == LM_NONE) ? "an int64 value" :
+ "an int64 value or range");
}
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
const QemuOpt *opt;
const char *str;
+ unsigned long long val;
+ char *endptr;
+
+ if (ov->list_mode == LM_UNSIGNED_INTERVAL) {
+ *obj = ov->range_next.u;
+ return;
+ }
opt = lookup_scalar(ov, name, errp);
if (!opt) {
return;
}
-
str = opt->str;
- if (str != NULL) {
- while (isspace((unsigned char)*str)) {
- ++str;
- }
- if (*str != '-' && *str != '\0') {
- unsigned long long val;
- char *endptr;
+ /* we've gotten past lookup_scalar() */
+ assert(ov->list_mode == LM_NONE || ov->list_mode == LM_IN_PROGRESS);
- /* non-empty, non-negative subject sequence */
- errno = 0;
- val = strtoull(str, &endptr, 0);
- if (*endptr == '\0' && errno == 0 && val <= UINT64_MAX) {
- *obj = val;
- processed(ov, name);
+ if (parse_uint(str, &val, &endptr, 0) == 0 && val <= UINT64_MAX) {
+ if (*endptr == '\0') {
+ *obj = val;
+ processed(ov, name);
+ return;
+ }
+ if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) {
+ unsigned long long val2;
+
+ str = endptr + 1;
+ if (parse_uint_full(str, &val2, 0) == 0 &&
+ val2 <= UINT64_MAX && val <= val2 &&
+ val2 - val < OPTS_VISITOR_RANGE_MAX) {
+ ov->range_next.u = val;
+ ov->range_limit.u = val2;
+ ov->list_mode = LM_UNSIGNED_INTERVAL;
+
+ /* as if entering on the top */
+ *obj = ov->range_next.u;
return;
}
}
}
error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
- "an uint64 value");
+ (ov->list_mode == LM_NONE) ? "a uint64 value" :
+ "a uint64 value or range");
}
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
/* we only support a single mandatory scalar field in a list node */
- assert(ov->repeated_opts == NULL);
+ assert(ov->list_mode == LM_NONE);
*present = (lookup_distinct(ov, name, NULL) != NULL);
}
int64_t ti;
int secs;
- ti = qemu_get_clock_ms(rt_clock);
+ ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
if (d->timestamps_start == -1)
d->timestamps_start = ti;
ti -= d->timestamps_start;
chr = qemu_chr_new_from_opts(opts, init, &err);
if (error_is_set(&err)) {
- fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_report("%s", error_get_pretty(err));
error_free(err);
}
if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
#include "qemu/sockets.h"
#include "block/coroutine.h"
#include "qemu/iov.h"
+#include "qemu/main-loop.h"
ssize_t coroutine_fn
qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
qemu_coroutine_enter(sleep_cb->co, NULL);
}
-void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns)
+void coroutine_fn co_sleep_ns(QEMUClockType type, int64_t ns)
{
CoSleepCB sleep_cb = {
.co = qemu_coroutine_self(),
};
- sleep_cb.ts = qemu_new_timer(clock, SCALE_NS, co_sleep_cb, &sleep_cb);
- qemu_mod_timer(sleep_cb.ts, qemu_get_clock_ns(clock) + ns);
+ sleep_cb.ts = timer_new(type, SCALE_NS, co_sleep_cb, &sleep_cb);
+ timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns);
qemu_coroutine_yield();
- qemu_del_timer(sleep_cb.ts);
- qemu_free_timer(sleep_cb.ts);
+ timer_del(sleep_cb.ts);
+ timer_free(sleep_cb.ts);
}
#include "qemu-io.h"
#include "block/block_int.h"
+#include "qemu/main-loop.h"
#define CMD_NOFILE_OK 0x01
#include "qemu-common.h"
#include "block/block.h"
#include "block/nbd.h"
+#include "qemu/main-loop.h"
#include <stdarg.h>
#include <stdio.h>
#include <pthread.h>
#endif
-#ifdef _WIN32
-#include <mmsystem.h>
+#ifdef CONFIG_PPOLL
+#include <poll.h>
+#endif
+
+#ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
+#include <sys/prctl.h>
#endif
/***********************************************************/
/* timers */
-#define QEMU_CLOCK_REALTIME 0
-#define QEMU_CLOCK_VIRTUAL 1
-#define QEMU_CLOCK_HOST 2
-
-struct QEMUClock {
- QEMUTimer *active_timers;
+typedef struct QEMUClock {
+ QLIST_HEAD(, QEMUTimerList) timerlists;
NotifierList reset_notifiers;
int64_t last;
- int type;
+ QEMUClockType type;
bool enabled;
-};
+} QEMUClock;
-struct QEMUTimer {
- int64_t expire_time; /* in nanoseconds */
- QEMUClock *clock;
- QEMUTimerCB *cb;
- void *opaque;
- QEMUTimer *next;
- int scale;
-};
+QEMUTimerListGroup main_loop_tlg;
+QEMUClock qemu_clocks[QEMU_CLOCK_MAX];
-struct qemu_alarm_timer {
- char const *name;
- int (*start)(struct qemu_alarm_timer *t);
- void (*stop)(struct qemu_alarm_timer *t);
- void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
-#if defined(__linux__)
- timer_t timer;
- int fd;
-#elif defined(_WIN32)
- HANDLE timer;
-#endif
- bool expired;
- bool pending;
+/* A QEMUTimerList is a list of timers attached to a clock. More
+ * than one QEMUTimerList can be attached to each clock, for instance
+ * used by different AioContexts / threads. Each clock also has
+ * a list of the QEMUTimerLists associated with it, in order that
+ * reenabling the clock can call all the notifiers.
+ */
+
+struct QEMUTimerList {
+ QEMUClock *clock;
+ QEMUTimer *active_timers;
+ QLIST_ENTRY(QEMUTimerList) list;
+ QEMUTimerListNotifyCB *notify_cb;
+ void *notify_opaque;
};
-static struct qemu_alarm_timer *alarm_timer;
+/**
+ * qemu_clock_ptr:
+ * @type: type of clock
+ *
+ * Translate a clock type into a pointer to QEMUClock object.
+ *
+ * Returns: a pointer to the QEMUClock object
+ */
+static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
+{
+ return &qemu_clocks[type];
+}
-static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
+static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
{
return timer_head && (timer_head->expire_time <= current_time);
}
-static int64_t qemu_next_alarm_deadline(void)
+QEMUTimerList *timerlist_new(QEMUClockType type,
+ QEMUTimerListNotifyCB *cb,
+ void *opaque)
{
- int64_t delta = INT64_MAX;
- int64_t rtdelta;
-
- if (!use_icount && vm_clock->enabled && vm_clock->active_timers) {
- delta = vm_clock->active_timers->expire_time -
- qemu_get_clock_ns(vm_clock);
- }
- if (host_clock->enabled && host_clock->active_timers) {
- int64_t hdelta = host_clock->active_timers->expire_time -
- qemu_get_clock_ns(host_clock);
- if (hdelta < delta) {
- delta = hdelta;
- }
- }
- if (rt_clock->enabled && rt_clock->active_timers) {
- rtdelta = (rt_clock->active_timers->expire_time -
- qemu_get_clock_ns(rt_clock));
- if (rtdelta < delta) {
- delta = rtdelta;
- }
- }
+ QEMUTimerList *timer_list;
+ QEMUClock *clock = qemu_clock_ptr(type);
- return delta;
+ timer_list = g_malloc0(sizeof(QEMUTimerList));
+ timer_list->clock = clock;
+ timer_list->notify_cb = cb;
+ timer_list->notify_opaque = opaque;
+ QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
+ return timer_list;
}
-static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
+void timerlist_free(QEMUTimerList *timer_list)
{
- int64_t nearest_delta_ns = qemu_next_alarm_deadline();
- if (nearest_delta_ns < INT64_MAX) {
- t->rearm(t, nearest_delta_ns);
+ assert(!timerlist_has_timers(timer_list));
+ if (timer_list->clock) {
+ QLIST_REMOVE(timer_list, list);
}
+ g_free(timer_list);
}
-/* TODO: MIN_TIMER_REARM_NS should be optimized */
-#define MIN_TIMER_REARM_NS 250000
-
-#ifdef _WIN32
-
-static int mm_start_timer(struct qemu_alarm_timer *t);
-static void mm_stop_timer(struct qemu_alarm_timer *t);
-static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-static int win32_start_timer(struct qemu_alarm_timer *t);
-static void win32_stop_timer(struct qemu_alarm_timer *t);
-static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-#else
-
-static int unix_start_timer(struct qemu_alarm_timer *t);
-static void unix_stop_timer(struct qemu_alarm_timer *t);
-static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-#ifdef __linux__
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t);
-static void dynticks_stop_timer(struct qemu_alarm_timer *t);
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-#endif /* __linux__ */
-
-#endif /* _WIN32 */
+static void qemu_clock_init(QEMUClockType type)
+{
+ QEMUClock *clock = qemu_clock_ptr(type);
-static struct qemu_alarm_timer alarm_timers[] = {
-#ifndef _WIN32
-#ifdef __linux__
- {"dynticks", dynticks_start_timer,
- dynticks_stop_timer, dynticks_rearm_timer},
-#endif
- {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
-#else
- {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer},
- {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
-#endif
- {NULL, }
-};
+ clock->type = type;
+ clock->enabled = true;
+ clock->last = INT64_MIN;
+ QLIST_INIT(&clock->timerlists);
+ notifier_list_init(&clock->reset_notifiers);
+ main_loop_tlg.tl[type] = timerlist_new(type, NULL, NULL);
+}
-static void show_available_alarms(void)
+bool qemu_clock_use_for_deadline(QEMUClockType type)
{
- int i;
-
- printf("Available alarm timers, in order of precedence:\n");
- for (i = 0; alarm_timers[i].name; i++)
- printf("%s\n", alarm_timers[i].name);
+ return !(use_icount && (type == QEMU_CLOCK_VIRTUAL));
}
-void configure_alarms(char const *opt)
+void qemu_clock_notify(QEMUClockType type)
{
- int i;
- int cur = 0;
- int count = ARRAY_SIZE(alarm_timers) - 1;
- char *arg;
- char *name;
- struct qemu_alarm_timer tmp;
+ QEMUTimerList *timer_list;
+ QEMUClock *clock = qemu_clock_ptr(type);
+ QLIST_FOREACH(timer_list, &clock->timerlists, list) {
+ timerlist_notify(timer_list);
+ }
+}
- if (is_help_option(opt)) {
- show_available_alarms();
- exit(0);
+void qemu_clock_enable(QEMUClockType type, bool enabled)
+{
+ QEMUClock *clock = qemu_clock_ptr(type);
+ bool old = clock->enabled;
+ clock->enabled = enabled;
+ if (enabled && !old) {
+ qemu_clock_notify(type);
}
+}
- arg = g_strdup(opt);
+bool timerlist_has_timers(QEMUTimerList *timer_list)
+{
+ return !!timer_list->active_timers;
+}
- /* Reorder the array */
- name = strtok(arg, ",");
- while (name) {
- for (i = 0; i < count && alarm_timers[i].name; i++) {
- if (!strcmp(alarm_timers[i].name, name))
- break;
- }
+bool qemu_clock_has_timers(QEMUClockType type)
+{
+ return timerlist_has_timers(
+ main_loop_tlg.tl[type]);
+}
- if (i == count) {
- fprintf(stderr, "Unknown clock %s\n", name);
- goto next;
- }
+bool timerlist_expired(QEMUTimerList *timer_list)
+{
+ return (timer_list->active_timers &&
+ timer_list->active_timers->expire_time <
+ qemu_clock_get_ns(timer_list->clock->type));
+}
- if (i < cur)
- /* Ignore */
- goto next;
+bool qemu_clock_expired(QEMUClockType type)
+{
+ return timerlist_expired(
+ main_loop_tlg.tl[type]);
+}
- /* Swap */
- tmp = alarm_timers[i];
- alarm_timers[i] = alarm_timers[cur];
- alarm_timers[cur] = tmp;
+/*
+ * 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 timerlist_deadline_ns(QEMUTimerList *timer_list)
+{
+ int64_t delta;
- cur++;
-next:
- name = strtok(NULL, ",");
+ if (!timer_list->clock->enabled || !timer_list->active_timers) {
+ return -1;
}
- g_free(arg);
+ delta = timer_list->active_timers->expire_time -
+ qemu_clock_get_ns(timer_list->clock->type);
- if (cur) {
- /* Disable remaining timers */
- for (i = cur; i < count; i++)
- alarm_timers[i].name = NULL;
- } else {
- show_available_alarms();
- exit(1);
+ if (delta <= 0) {
+ return 0;
}
-}
-QEMUClock *rt_clock;
-QEMUClock *vm_clock;
-QEMUClock *host_clock;
+ return delta;
+}
-static QEMUClock *qemu_new_clock(int type)
+/* Calculate the soonest deadline across all timerlists attached
+ * to the clock. This is used for the icount timeout so we
+ * ignore whether or not the clock should be used in deadline
+ * calculations.
+ */
+int64_t qemu_clock_deadline_ns_all(QEMUClockType type)
{
- QEMUClock *clock;
-
- clock = g_malloc0(sizeof(QEMUClock));
- clock->type = type;
- clock->enabled = true;
- clock->last = INT64_MIN;
- notifier_list_init(&clock->reset_notifiers);
- return clock;
+ int64_t deadline = -1;
+ QEMUTimerList *timer_list;
+ QEMUClock *clock = qemu_clock_ptr(type);
+ QLIST_FOREACH(timer_list, &clock->timerlists, list) {
+ deadline = qemu_soonest_timeout(deadline,
+ timerlist_deadline_ns(timer_list));
+ }
+ return deadline;
}
-void qemu_clock_enable(QEMUClock *clock, bool enabled)
+QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list)
{
- bool old = clock->enabled;
- clock->enabled = enabled;
- if (enabled && !old) {
- qemu_rearm_alarm_timer(alarm_timer);
- }
+ return timer_list->clock->type;
}
-int64_t qemu_clock_has_timers(QEMUClock *clock)
+QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type)
{
- return !!clock->active_timers;
+ return main_loop_tlg.tl[type];
}
-int64_t qemu_clock_expired(QEMUClock *clock)
+void timerlist_notify(QEMUTimerList *timer_list)
{
- return (clock->active_timers &&
- clock->active_timers->expire_time < qemu_get_clock_ns(clock));
+ if (timer_list->notify_cb) {
+ timer_list->notify_cb(timer_list->notify_opaque);
+ } else {
+ qemu_notify_event();
+ }
}
-int64_t qemu_clock_deadline(QEMUClock *clock)
+/* 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)
{
- /* To avoid problems with overflow limit this to 2^32. */
- int64_t delta = INT32_MAX;
+ int64_t ms;
+ if (ns < 0) {
+ return -1;
+ }
- if (clock->active_timers) {
- delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
+ if (!ns) {
+ return 0;
}
- if (delta < 0) {
- delta = 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 delta;
+
+ return (int) ms;
}
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
- QEMUTimerCB *cb, void *opaque)
+
+/* qemu implementation of g_poll which uses a nanosecond timeout but is
+ * otherwise identical to g_poll
+ */
+int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
{
- QEMUTimer *ts;
+#ifdef CONFIG_PPOLL
+ if (timeout < 0) {
+ return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
+ } else {
+ struct timespec ts;
+ ts.tv_sec = timeout / 1000000000LL;
+ ts.tv_nsec = timeout % 1000000000LL;
+ return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
+ }
+#else
+ return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));
+#endif
+}
- ts = g_malloc0(sizeof(QEMUTimer));
- ts->clock = clock;
+
+void timer_init(QEMUTimer *ts,
+ QEMUTimerList *timer_list, int scale,
+ QEMUTimerCB *cb, void *opaque)
+{
+ ts->timer_list = timer_list;
ts->cb = cb;
ts->opaque = opaque;
ts->scale = scale;
- return ts;
}
-void qemu_free_timer(QEMUTimer *ts)
+void timer_free(QEMUTimer *ts)
{
g_free(ts);
}
/* stop a timer, but do not dealloc it */
-void qemu_del_timer(QEMUTimer *ts)
+void timer_del(QEMUTimer *ts)
{
QEMUTimer **pt, *t;
/* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &ts->clock->active_timers;
+ timer_expired() can be called from a signal. */
+ pt = &ts->timer_list->active_timers;
for(;;) {
t = *pt;
if (!t)
/* modify the current timer so that it will be fired when current_time
>= 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;
- qemu_del_timer(ts);
+ timer_del(ts);
/* add the timer in the sorted list */
/* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &ts->clock->active_timers;
+ timer_expired() can be called from a signal. */
+ pt = &ts->timer_list->active_timers;
for(;;) {
t = *pt;
- if (!qemu_timer_expired_ns(t, expire_time)) {
+ if (!timer_expired_ns(t, expire_time)) {
break;
}
pt = &t->next;
*pt = ts;
/* Rearm if necessary */
- if (pt == &ts->clock->active_timers) {
- if (!alarm_timer->pending) {
- qemu_rearm_alarm_timer(alarm_timer);
- }
+ if (pt == &ts->timer_list->active_timers) {
/* Interrupt execution to force deadline recalculation. */
- qemu_clock_warp(ts->clock);
- if (use_icount) {
- qemu_notify_event();
- }
+ qemu_clock_warp(ts->timer_list->clock->type);
+ 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 qemu_timer_pending(QEMUTimer *ts)
+bool timer_pending(QEMUTimer *ts)
{
QEMUTimer *t;
- for (t = ts->clock->active_timers; t != NULL; t = t->next) {
+ for (t = ts->timer_list->active_timers; t != NULL; t = t->next) {
if (t == ts) {
return true;
}
return false;
}
-bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
+bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
{
- return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
+ return timer_expired_ns(timer_head, current_time * timer_head->scale);
}
-void qemu_run_timers(QEMUClock *clock)
+bool timerlist_run_timers(QEMUTimerList *timer_list)
{
QEMUTimer *ts;
int64_t current_time;
+ bool progress = false;
- if (!clock->enabled)
- return;
+ if (!timer_list->clock->enabled) {
+ return progress;
+ }
- current_time = qemu_get_clock_ns(clock);
+ current_time = qemu_clock_get_ns(timer_list->clock->type);
for(;;) {
- ts = clock->active_timers;
- if (!qemu_timer_expired_ns(ts, current_time)) {
+ ts = timer_list->active_timers;
+ if (!timer_expired_ns(ts, current_time)) {
break;
}
/* remove timer from the list before calling the callback */
- clock->active_timers = ts->next;
+ timer_list->active_timers = ts->next;
ts->next = NULL;
/* run the callback (the timer list can be modified) */
ts->cb(ts->opaque);
+ progress = true;
+ }
+ return progress;
+}
+
+bool qemu_clock_run_timers(QEMUClockType type)
+{
+ return timerlist_run_timers(main_loop_tlg.tl[type]);
+}
+
+void timerlistgroup_init(QEMUTimerListGroup *tlg,
+ QEMUTimerListNotifyCB *cb, void *opaque)
+{
+ QEMUClockType type;
+ for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+ tlg->tl[type] = timerlist_new(type, cb, opaque);
}
}
-int64_t qemu_get_clock_ns(QEMUClock *clock)
+void timerlistgroup_deinit(QEMUTimerListGroup *tlg)
+{
+ QEMUClockType type;
+ for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+ timerlist_free(tlg->tl[type]);
+ }
+}
+
+bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
+{
+ QEMUClockType type;
+ bool progress = false;
+ for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+ progress |= timerlist_run_timers(tlg->tl[type]);
+ }
+ return progress;
+}
+
+int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
+{
+ int64_t deadline = -1;
+ QEMUClockType type;
+ for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+ if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) {
+ deadline = qemu_soonest_timeout(deadline,
+ timerlist_deadline_ns(
+ tlg->tl[type]));
+ }
+ }
+ return deadline;
+}
+
+int64_t qemu_clock_get_ns(QEMUClockType type)
{
int64_t now, last;
+ QEMUClock *clock = qemu_clock_ptr(type);
- switch(clock->type) {
+ switch (type) {
case QEMU_CLOCK_REALTIME:
return get_clock();
default:
}
}
-void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
+void qemu_clock_register_reset_notifier(QEMUClockType type,
+ Notifier *notifier)
{
+ QEMUClock *clock = qemu_clock_ptr(type);
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);
}
void init_clocks(void)
{
- if (!rt_clock) {
- rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
- vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
- host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
- }
-}
-
-uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
-{
- return qemu_timer_pending(ts) ? ts->expire_time : -1;
-}
-
-void qemu_run_all_timers(void)
-{
- alarm_timer->pending = false;
-
- /* vm time timers */
- qemu_run_timers(vm_clock);
- qemu_run_timers(rt_clock);
- qemu_run_timers(host_clock);
-
- /* rearm timer, if not periodic */
- if (alarm_timer->expired) {
- alarm_timer->expired = false;
- qemu_rearm_alarm_timer(alarm_timer);
+ QEMUClockType type;
+ for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+ qemu_clock_init(type);
}
-}
-#ifdef _WIN32
-static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
-#else
-static void host_alarm_handler(int host_signum)
+#ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
+ prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
#endif
-{
- struct qemu_alarm_timer *t = alarm_timer;
- if (!t)
- return;
-
- t->expired = true;
- t->pending = true;
- qemu_notify_event();
-}
-
-#if defined(__linux__)
-
-#include "qemu/compatfd.h"
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t)
-{
- struct sigevent ev;
- timer_t host_timer;
- struct sigaction act;
-
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = host_alarm_handler;
-
- sigaction(SIGALRM, &act, NULL);
-
- /*
- * Initialize ev struct to 0 to avoid valgrind complaining
- * about uninitialized data in timer_create call
- */
- memset(&ev, 0, sizeof(ev));
- ev.sigev_value.sival_int = 0;
- ev.sigev_notify = SIGEV_SIGNAL;
-#ifdef CONFIG_SIGEV_THREAD_ID
- if (qemu_signalfd_available()) {
- ev.sigev_notify = SIGEV_THREAD_ID;
- ev._sigev_un._tid = qemu_get_thread_id();
- }
-#endif /* CONFIG_SIGEV_THREAD_ID */
- ev.sigev_signo = SIGALRM;
-
- if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
- perror("timer_create");
- return -1;
- }
-
- t->timer = host_timer;
-
- return 0;
-}
-
-static void dynticks_stop_timer(struct qemu_alarm_timer *t)
-{
- timer_t host_timer = t->timer;
-
- timer_delete(host_timer);
-}
-
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
- int64_t nearest_delta_ns)
-{
- timer_t host_timer = t->timer;
- struct itimerspec timeout;
- int64_t current_ns;
-
- if (nearest_delta_ns < MIN_TIMER_REARM_NS)
- nearest_delta_ns = MIN_TIMER_REARM_NS;
-
- /* check whether a timer is already running */
- if (timer_gettime(host_timer, &timeout)) {
- perror("gettime");
- fprintf(stderr, "Internal timer error: aborting\n");
- exit(1);
- }
- current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
- if (current_ns && current_ns <= nearest_delta_ns)
- return;
-
- timeout.it_interval.tv_sec = 0;
- timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
- timeout.it_value.tv_sec = nearest_delta_ns / 1000000000;
- timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
- if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
- perror("settime");
- fprintf(stderr, "Internal timer error: aborting\n");
- exit(1);
- }
-}
-
-#endif /* defined(__linux__) */
-
-#if !defined(_WIN32)
-
-static int unix_start_timer(struct qemu_alarm_timer *t)
-{
- struct sigaction act;
-
- /* timer signal */
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = host_alarm_handler;
-
- sigaction(SIGALRM, &act, NULL);
- return 0;
-}
-
-static void unix_rearm_timer(struct qemu_alarm_timer *t,
- int64_t nearest_delta_ns)
-{
- struct itimerval itv;
- int err;
-
- if (nearest_delta_ns < MIN_TIMER_REARM_NS)
- nearest_delta_ns = MIN_TIMER_REARM_NS;
-
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
- itv.it_value.tv_sec = nearest_delta_ns / 1000000000;
- itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
- err = setitimer(ITIMER_REAL, &itv, NULL);
- if (err) {
- perror("setitimer");
- fprintf(stderr, "Internal timer error: aborting\n");
- exit(1);
- }
-}
-
-static void unix_stop_timer(struct qemu_alarm_timer *t)
-{
- struct itimerval itv;
-
- memset(&itv, 0, sizeof(itv));
- setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-#endif /* !defined(_WIN32) */
-
-
-#ifdef _WIN32
-
-static MMRESULT mm_timer;
-static TIMECAPS mm_tc;
-
-static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
- DWORD_PTR dwUser, DWORD_PTR dw1,
- DWORD_PTR dw2)
-{
- struct qemu_alarm_timer *t = alarm_timer;
- if (!t) {
- return;
- }
- t->expired = true;
- t->pending = true;
- qemu_notify_event();
}
-static int mm_start_timer(struct qemu_alarm_timer *t)
+uint64_t timer_expire_time_ns(QEMUTimer *ts)
{
- timeGetDevCaps(&mm_tc, sizeof(mm_tc));
- return 0;
+ return timer_pending(ts) ? ts->expire_time : -1;
}
-static void mm_stop_timer(struct qemu_alarm_timer *t)
+bool qemu_clock_run_all_timers(void)
{
- if (mm_timer) {
- timeKillEvent(mm_timer);
- }
-}
+ bool progress = false;
+ QEMUClockType type;
-static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
-{
- int64_t nearest_delta_ms = delta / 1000000;
- if (nearest_delta_ms < mm_tc.wPeriodMin) {
- nearest_delta_ms = mm_tc.wPeriodMin;
- } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
- nearest_delta_ms = mm_tc.wPeriodMax;
+ for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+ progress |= qemu_clock_run_timers(type);
}
- if (mm_timer) {
- timeKillEvent(mm_timer);
- }
- mm_timer = timeSetEvent((UINT)nearest_delta_ms,
- mm_tc.wPeriodMin,
- mm_alarm_handler,
- (DWORD_PTR)t,
- TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
-
- if (!mm_timer) {
- fprintf(stderr, "Failed to re-arm win32 alarm timer\n");
- timeEndPeriod(mm_tc.wPeriodMin);
- exit(1);
- }
+ return progress;
}
-
-static int win32_start_timer(struct qemu_alarm_timer *t)
-{
- HANDLE hTimer;
- BOOLEAN success;
-
- /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
- is zero) that has already expired, the timer is not updated. Since
- creating a new timer is relatively expensive, set a bogus one-hour
- interval in the dynticks case. */
- success = CreateTimerQueueTimer(&hTimer,
- NULL,
- host_alarm_handler,
- t,
- 1,
- 3600000,
- WT_EXECUTEINTIMERTHREAD);
-
- if (!success) {
- fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
- GetLastError());
- return -1;
- }
-
- t->timer = hTimer;
- return 0;
-}
-
-static void win32_stop_timer(struct qemu_alarm_timer *t)
-{
- HANDLE hTimer = t->timer;
-
- if (hTimer) {
- DeleteTimerQueueTimer(NULL, hTimer, NULL);
- }
-}
-
-static void win32_rearm_timer(struct qemu_alarm_timer *t,
- int64_t nearest_delta_ns)
-{
- HANDLE hTimer = t->timer;
- int64_t nearest_delta_ms;
- BOOLEAN success;
-
- nearest_delta_ms = nearest_delta_ns / 1000000;
- if (nearest_delta_ms < 1) {
- nearest_delta_ms = 1;
- }
- /* ULONG_MAX can be 32 bit */
- if (nearest_delta_ms > ULONG_MAX) {
- nearest_delta_ms = ULONG_MAX;
- }
- success = ChangeTimerQueueTimer(NULL,
- hTimer,
- (unsigned long) nearest_delta_ms,
- 3600000);
-
- if (!success) {
- fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
- GetLastError());
- exit(-1);
- }
-
-}
-
-#endif /* _WIN32 */
-
-static void quit_timers(void)
-{
- struct qemu_alarm_timer *t = alarm_timer;
- alarm_timer = NULL;
- t->stop(t);
-}
-
-#ifdef CONFIG_POSIX
-static void reinit_timers(void)
-{
- struct qemu_alarm_timer *t = alarm_timer;
- t->stop(t);
- if (t->start(t)) {
- fprintf(stderr, "Internal timer error: aborting\n");
- exit(1);
- }
- qemu_rearm_alarm_timer(t);
-}
-#endif /* CONFIG_POSIX */
-
-int init_timer_alarm(void)
-{
- struct qemu_alarm_timer *t = NULL;
- int i, err = -1;
-
- if (alarm_timer) {
- return 0;
- }
-
- for (i = 0; alarm_timers[i].name; i++) {
- t = &alarm_timers[i];
-
- err = t->start(t);
- if (!err)
- break;
- }
-
- if (err) {
- err = -ENOENT;
- goto fail;
- }
-
- atexit(quit_timers);
-#ifdef CONFIG_POSIX
- pthread_atfork(NULL, NULL, reinit_timers);
-#endif
- alarm_timer = t;
- return 0;
-
-fail:
- return err;
-}
-
*
* Clock management:
*
- * The qtest client is completely in charge of the vm_clock. qtest commands
+ * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL. qtest commands
* let you adjust the value of the clock (monotonically). All the commands
* return the current value of the clock in nanoseconds.
*
if (words[1]) {
ns = strtoll(words[1], NULL, 0);
} else {
- ns = qemu_clock_deadline(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_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
qtest_send_prefix(chr);
- qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+ qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
} else if (strcmp(words[0], "clock_set") == 0) {
int64_t ns;
ns = strtoll(words[1], NULL, 0);
qtest_clock_warp(ns);
qtest_send_prefix(chr);
- qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+ qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
} else {
qtest_send_prefix(chr);
qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
if (--count) {
/* delay 50ms, 150ms, 250ms, ... */
- qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
+ timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
} else {
- qemu_del_timer(timer);
- qemu_free_timer(timer);
+ timer_del(timer);
+ timer_free(timer);
}
}
void qemu_announce_self(void)
{
static QEMUTimer *timer;
- timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
+ timer = timer_new_ms(QEMU_CLOCK_REALTIME, qemu_announce_self_once, &timer);
qemu_announce_self_once(&timer);
}
/* timer */
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
+void timer_put(QEMUFile *f, QEMUTimer *ts)
{
uint64_t expire_time;
- expire_time = qemu_timer_expire_time_ns(ts);
+ expire_time = timer_expire_time_ns(ts);
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;
expire_time = qemu_get_be64(f);
if (expire_time != -1) {
- qemu_mod_timer_ns(ts, expire_time);
+ timer_mod_ns(ts, expire_time);
} else {
- qemu_del_timer(ts);
+ timer_del(ts);
}
}
static int get_timer(QEMUFile *f, void *pv, size_t size)
{
QEMUTimer *v = pv;
- qemu_get_timer(f, v);
+ timer_get(f, v);
return 0;
}
static void put_timer(QEMUFile *f, void *pv, size_t size)
{
QEMUTimer *v = pv;
- qemu_put_timer(f, v);
+ timer_put(f, v);
}
const VMStateInfo vmstate_info_timer = {
qemu_gettimeofday(&tv);
sn->date_sec = tv.tv_sec;
sn->date_nsec = tv.tv_usec * 1000;
- sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
+ sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (name) {
ret = bdrv_snapshot_find(bs, old_sn, name);
--- /dev/null
+#!/usr/bin/perl -w
+
+use File::Temp qw/ tempfile /;
+use Getopt::Long;
+
+# Default to the system objdump if a cross-compiler edition not given.
+my $aobjdump = "objdump";
+my $hobjdump = "";
+my $tobjdump = "";
+my $hmachine = "";
+my $tmachine = "";
+
+GetOptions ('O|objdump=s' => \$aobjdump,
+ 'host-objdump=s' => \$hobjdump,
+ 'target-objdump=s' => \$tobjdump,
+ 'h|host-machine=s' => \$hmachine,
+ 't|target-machine=s' => \$tmachine);
+
+# But we can't default the machines. Sanity check that we've at least one.
+die "No host or target machine type" if !$hmachine && !$tmachine;
+
+# Reuse one temp file for all of the hunks.
+my ($outh, $outname) = tempfile();
+binmode($outh);
+END { unlink $outname; }
+
+# Pre-construct the command-lines for executing the dump.
+sub mkobjcommand ($$) {
+ my ($cmd, $mach) = @_;
+ return 0 if !$mach;
+ $cmd = $aobjdump if !$cmd;
+ return "$cmd -m $mach --disassemble-all -b binary";
+}
+
+$objdump[1] = mkobjcommand($hobjdump, $hmachine);
+$objdump[2] = mkobjcommand($tobjdump, $tmachine);
+
+# Zero-initialize current dumping state.
+my $mem = "";
+my $inobjd = 0;
+my $vma = 0;
+
+sub objcommand {
+ my $ret = $objdump[$inobjd];
+ if (!$ret) {
+ die "Host machine type not specified" if $inobjd == 1;
+ die "Target machine type not specified" if $inobjd == 2;
+ die "Internal error";
+ }
+ return $ret;
+}
+
+while (<>) {
+ # Collect the data from the relevant OBJD-* lines ...
+ if (/^OBJD-H: /) {
+ die "Internal error" if $inobjd == 2;
+ $mem = $mem . pack("H*", substr($_, 8, -1));
+ $inobjd = 1;
+ } elsif (/^OBJD-T: /) {
+ die "Internal error" if $inobjd == 1;
+ $mem = $mem . pack("H*", substr($_, 8, -1));
+ $inobjd = 2;
+ }
+ # ... which will always be followed by a blank line,
+ # at which point we should produce our dump.
+ elsif ($inobjd) {
+ # Rewrite the temp file in one go; it will usually be small.
+ sysseek $outh, 0, 0;
+ truncate $outh, 0;
+ syswrite $outh, $mem;
+
+ my $cmd = objcommand();
+ $cmd = $cmd . " --adjust-vma=" . $vma if $vma;
+ $cmd = $cmd . " " . $outname;
+
+ # Pipe from objdump...
+ open IN, "-|", $cmd;
+
+ # ... copying all but the first 7 lines of boilerplate to our stdout.
+ my $i = 0;
+ while (<IN>) {
+ print if (++$i > 7);
+ }
+ close IN;
+ print "\n";
+
+ $mem = "";
+ $inobjd = 0;
+ $vma = 0;
+ }
+ # The line before "OBJD-*" will be of the form "0x<hex>+: +\n".
+ # Extract the value for passing to --adjust-vma.
+ elsif (/^(0x[0-9a-fA-F]+):\s*$/) {
+ $vma = $1;
+ print;
+ } else {
+ print;
+ }
+}
def parse_schema(fp):
try:
schema = QAPISchema(fp)
- except QAPISchemaError as e:
+ except QAPISchemaError, e:
print >>sys.stderr, e
exit(1)
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Getopt::Long;
+use FindBin;
+
+my @legacy = qw(qemu_clock_ptr qemu_get_clock_ns qemu_get_clock_ms qemu_register_clock_reset_notifier qemu_unregister_clock_reset_notifier qemu_new_timer qemu_free_timer qemu_del_timer qemu_mod_timer_ns qemu_mod_timer qemu_run_timers qemu_new_timer_ns qemu_new_timer_us qemu_new_timer_ms);
+my $legacyre = '\b('.join('|', @legacy).')\b';
+my $option_git;
+my $option_dryrun;
+my $option_quiet;
+my $option_rtc;
+my $suffix=".tmp.$$";
+my @files;
+my $getfiles = 'git grep -l -E \'\b((host|rt|vm|rtc)_clock\b|qemu_\w*timer)\' | egrep \'\.[ch]$\' | egrep -v \'qemu-timer\.c$|include/qemu/timer\.h$\'';
+
+sub Syntax
+{
+ print STDERR <<STOP;
+Usage: $FindBin::Script [options] FILE ...
+
+Translate each FILE to the new Qemu timer API. If no files
+are passed, a reasonable guess is taken.
+
+Options:
+ -q, --quiet Do not show warnings etc
+ -d, --dry-run Do a dry run
+ -g, --git Generate a git commit for each change
+ -r, --rtc Only fix up rtc usage
+ -h, --help Print this message
+
+STOP
+return;
+}
+
+sub ParseOptions
+{
+ if (!GetOptions (
+ "dry-run|d" => \$option_dryrun,
+ "git|g" => \$option_git,
+ "quiet|q" => \$option_quiet,
+ "rtc|r" => \$option_rtc,
+ "help|h" => sub { Syntax(); exit(0); }
+ ))
+ {
+ Syntax();
+ die "Bad options";
+ }
+
+ if ($#ARGV >=0)
+ {
+ @files = @ARGV;
+ }
+ else
+ {
+ @files = split(/\s+/, `$getfiles`);
+ }
+
+ foreach my $file (@files)
+ {
+ die "Cannot find $file" unless (-f $file && -r $file);
+ }
+}
+
+sub DoWarn
+{
+ my $text = shift @_;
+ my $line = shift @_;
+ return if ($option_quiet);
+ chomp ($line);
+ print STDERR "$text\n";
+ print STDERR "$line\n\n";
+}
+
+sub Process
+{
+ my $ifn = shift @_;
+ my $ofn = $ifn.$suffix;
+
+ my $intext;
+ my $outtext;
+ my $linenum = 0;
+
+ open my $input, "<", $ifn || die "Cannot open $ifn for read: $!";
+
+ while (<$input>)
+ {
+ my $line = $_;
+ $intext .= $line;
+ $linenum++;
+
+ # fix the specific uses
+ unless ($option_rtc)
+ {
+ $line =~ s/\bqemu_new_timer(_[num]s)\s*\((vm_|rt_|host_)clock\b/timer_new$1(XXX_$2clock/g;
+ $line =~ s/\bqemu_new_timer\s*\((vm_|rt_|host_)clock\b/timer_new(XXX_$1clock/g;
+ $line =~ s/\bqemu_get_clock(_[num]s)\s*\((vm_|rt_|host_)clock\b/qemu_clock_get$1(XXX_$2clock/g;
+ }
+
+ # rtc is different
+ $line =~ s/\bqemu_new_timer(_[num]s)\s*\(rtc_clock\b/timer_new$1(rtc_clock/g;
+ $line =~ s/\bqemu_new_timer\s*\(rtc_clock\b/timer_new(rtc_clock/g;
+ $line =~ s/\bqemu_get_clock(_[num]s)\s*\(rtc_clock\b/qemu_clock_get$1(rtc_clock/g;
+ $line =~ s/\bqemu_register_clock_reset_notifier\s*\(rtc_clock\b/qemu_register_clock_reset_notifier(qemu_clock_ptr(rtc_clock)/g;
+
+ unless ($option_rtc)
+ {
+ # fix up comments
+ $line =~ s/\b(vm_|rt_|host_)clock\b/XXX_$1clock/g if ($line =~ m,^[/ ]+\*,);
+
+ # spurious fprintf error reporting
+ $line =~ s/: qemu_new_timer_ns failed/: timer_new_ns failed/g;
+
+ # these have just changed name
+ $line =~ s/\bqemu_mod_timer\b/timer_mod/g;
+ $line =~ s/\bqemu_mod_timer_(ns|us|ms)\b/timer_mod_$1/g;
+ $line =~ s/\bqemu_free_timer\b/timer_free/g;
+ $line =~ s/\bqemu_del_timer\b/timer_del/g;
+ }
+
+ # fix up rtc_clock
+ $line =~ s/QEMUClock \*rtc_clock;/QEMUClockType rtc_clock;/g;
+ $line =~ s/\brtc_clock = (vm_|rt_|host_)clock\b/rtc_clock = XXX_$1clock/g;
+
+ unless ($option_rtc)
+ {
+ # replace any more general uses
+ $line =~ s/\b(vm_|rt_|host_)clock\b/qemu_clock_ptr(XXX_$1clock)/g;
+ }
+
+ # fix up the place holders
+ $line =~ s/\bXXX_vm_clock\b/QEMU_CLOCK_VIRTUAL/g;
+ $line =~ s/\bXXX_rt_clock\b/QEMU_CLOCK_REALTIME/g;
+ $line =~ s/\bXXX_host_clock\b/QEMU_CLOCK_HOST/g;
+
+ unless ($option_rtc)
+ {
+ DoWarn("$ifn:$linenum WARNING: timer $1 not fixed up", $line) if ($line =~ /\b((vm_|rt_|host_)clock)\b/);
+ DoWarn("$ifn:$linenum WARNING: function $1 not fixed up", $line) if ($line =~ /\b(qemu_new_timer\w+)\b/);
+ DoWarn("$ifn:$linenum WARNING: legacy function $1 remains", $line) if ($line =~ /$legacyre/o);
+ }
+
+ $outtext .= $line;
+ }
+
+ close $input;
+
+ if ($intext ne $outtext)
+ {
+ print STDERR "Patching $ifn\n" unless ($option_quiet);
+ unless ($option_dryrun)
+ {
+ open my $output, ">", $ofn || die "Cannot open $ofn for write: $!";
+ print $output $outtext;
+ close $output;
+ rename ($ofn, $ifn) || die "Cannot rename temp file to $ifn: $!";
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub DoCommit
+{
+ my $file = shift @_;
+ open (my $git, "| git commit -F - $file") || die "Cannot run git commit on $file: $!";
+ print $git "timers api: use new timer api in $file\n\nConvert $file to use new timer API.\nThis is an automated commit made by scripts/switch-timer-api\n";
+ close ($git);
+}
+
+ParseOptions;
+
+foreach my $file (@files)
+{
+ my $changed = Process ($file);
+ DoCommit($file) if ($changed && $option_git);
+}
*/
void if_start(Slirp *slirp)
{
- uint64_t now = qemu_get_clock_ns(rt_clock);
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
bool from_batchq, next_from_batchq;
struct mbuf *ifm, *ifm_next, *ifqt;
#include <libslirp.h>
#include "monitor/monitor.h"
+#include "qemu/main-loop.h"
#ifdef DEBUG
int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
return;
}
- curtime = qemu_get_clock_ms(rt_clock);
+ curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
ifm->arp_requested = true;
/* Expire request and drop outgoing packet after 1 second */
- ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL;
+ ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
}
return 0;
} else {
#include "qemu-common.h"
#include "qemu/timer.h"
-void qemu_clock_warp(QEMUClock *clock)
+void qemu_clock_warp(QEMUClockType type)
{
}
In order to make OS-level time accounting work with the RPCC,
present it with a well-timed clock fixed at 250MHz. */
return (((uint64_t)env->pcc_ofs << 32)
- | (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2));
+ | (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2));
#else
- /* In user-mode, vm_clock doesn't exist. Just pass through the host cpu
+ /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist. Just pass through the host cpu
clock ticks. Also, don't bother taking PCC_OFS into account. */
return (uint32_t)cpu_get_real_ticks();
#endif
uint64_t helper_get_vmtime(void)
{
- return qemu_get_clock_ns(vm_clock);
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
uint64_t helper_get_walltime(void)
{
- return qemu_get_clock_ns(rtc_clock);
+ return qemu_clock_get_ns(rtc_clock);
}
void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
if (expire) {
env->alarm_expire = expire;
- qemu_mod_timer(cpu->alarm_timer, expire);
+ timer_mod(cpu->alarm_timer, expire);
} else {
- qemu_del_timer(cpu->alarm_timer);
+ timer_del(cpu->alarm_timer);
}
}
qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 2);
}
- cpu->gt_timer[GTIMER_PHYS] = qemu_new_timer(vm_clock, GTIMER_SCALE,
+ cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
arm_gt_ptimer_cb, cpu);
- cpu->gt_timer[GTIMER_VIRT] = qemu_new_timer(vm_clock, GTIMER_SCALE,
+ cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
arm_gt_vtimer_cb, cpu);
qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
ARRAY_SIZE(cpu->gt_timer_outputs));
static uint64_t gt_get_countervalue(CPUARMState *env)
{
- return qemu_get_clock_ns(vm_clock) / GTIMER_SCALE;
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
}
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
if (nexttick > INT64_MAX / GTIMER_SCALE) {
nexttick = INT64_MAX / GTIMER_SCALE;
}
- qemu_mod_timer(cpu->gt_timer[timeridx], nexttick);
+ timer_mod(cpu->gt_timer[timeridx], nexttick);
} else {
/* Timer disabled: ISTATUS and timer output always clear */
gt->ctl &= ~4;
qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
- qemu_del_timer(cpu->gt_timer[timeridx]);
+ timer_del(cpu->gt_timer[timeridx]);
}
}
ARMCPU *cpu = arm_env_get_cpu(env);
int timeridx = ri->opc1 & 1;
- qemu_del_timer(cpu->gt_timer[timeridx]);
+ timer_del(cpu->gt_timer[timeridx]);
}
static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
#else
/* In user-mode none of the generic timer registers are accessible,
- * and their implementation depends on vm_clock and qdev gpio outputs,
+ * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs,
* so instead just don't register any of them.
*/
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
out:
if (error) {
- fprintf(stderr, "%s\n", error_get_pretty(error));
+ error_report("%s", error_get_pretty(error));
error_free(error);
if (cpu != NULL) {
object_unref(OBJECT(cpu));
}
}
#if 0
- qemu_log(TARGET_FMT_lx " %d %d => " TARGET_FMT_lx " %d (%d)\n",
+ qemu_log(TARGET_FMT_lx " %d %d => %" HWADDR_PRIx " %d (%d)\n",
address, rw, access_type, *physical, *prot, ret);
#endif
return ret;
}
- idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_cpu, cpu);
+ idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, kvm_kick_cpu, cpu);
/* Some targets support access to KVM's guest TLB. */
switch (cenv->mmu_model) {
}
/* Always wake up soon in case the interrupt was level based */
- qemu_mod_timer(idle_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(idle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
(get_ticks_per_sec() / 50));
}
int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
{
- int64_t starttime = qemu_get_clock_ns(rt_clock);
+ int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
uint8_t buf[bufsize];
ssize_t rc;
}
} while ((rc != 0)
&& ((max_ns < 0)
- || ((qemu_get_clock_ns(rt_clock) - starttime) < max_ns)));
+ || ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) < max_ns)));
return (rc == 0) ? 1 : 0;
}
static void kvmppc_timer_hack(void *opaque)
{
qemu_notify_event();
- qemu_mod_timer(kvmppc_timer, qemu_get_clock_ns(vm_clock) + kvmppc_timer_rate);
+ timer_mod(kvmppc_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + kvmppc_timer_rate);
}
void kvmppc_init(void)
* run. So, until QEMU gains IO threads, we create this timer to ensure
* that the device model gets a chance to run. */
kvmppc_timer_rate = get_ticks_per_sec() / 10;
- kvmppc_timer = qemu_new_timer_ns(vm_clock, &kvmppc_timer_hack, NULL);
- qemu_mod_timer(kvmppc_timer, qemu_get_clock_ns(vm_clock) + kvmppc_timer_rate);
+ kvmppc_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &kvmppc_timer_hack, NULL);
+ timer_mod(kvmppc_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + kvmppc_timer_rate);
}
#include "cpu-models.h"
#include "mmu-hash32.h"
#include "mmu-hash64.h"
+#include "qemu/error-report.h"
//#define PPC_DUMP_CPU
//#define PPC_DEBUG_SPR
object_property_set_bool(OBJECT(cpu), true, "realized", &err);
if (err != NULL) {
- fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_report("%s", error_get_pretty(err));
error_free(err);
object_unref(OBJECT(cpu));
return NULL;
env->tod_offset = TOD_UNIX_EPOCH +
(time2tod(mktimegm(&tm)) * 1000000000ULL);
env->tod_basetime = 0;
- env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu);
- env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu);
+ env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
+ env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
/* set CPUState::halted state to 1 to avoid decrementing the running
* cpu counter in s390_cpu_reset to a negative number at
* initial ipl */
uint64_t time;
time = env->tod_offset +
- time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
+ time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - env->tod_basetime);
return time;
}
/* nanoseconds */
time = (time * 125) >> 9;
- qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
+ timer_mod(env->tod_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
}
/* Store Clock Comparator */
/* nanoseconds */
time = (time * 125) >> 9;
- qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
+ timer_mod(env->cpu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
}
/* Store CPU Timer */
}
cpu = CPU(xtensa_env_get_cpu(env));
- env->halt_clock = qemu_get_clock_ns(vm_clock);
+ env->halt_clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
cpu->halted = 1;
if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
xtensa_rearm_ccompare_timer(env);
/* qemu_ld/st address constraint */
case 'L':
ct->ct |= TCG_CT_REG;
-#if TCG_TARGET_REG_BITS == 64
+ if (TCG_TARGET_REG_BITS == 64) {
tcg_regset_set32(ct->u.regs, 0, 0xffff);
-#else
+ } else {
tcg_regset_set32(ct->u.regs, 0, 0xff);
-#endif
+ }
tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
break;
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
+ tcg_target_long diff;
+
if (arg == 0) {
tgen_arithr(s, ARITH_XOR, ret, ret);
return;
- } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
+ }
+ if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
tcg_out32(s, arg);
- } else if (arg == (int32_t)arg) {
+ return;
+ }
+ if (arg == (int32_t)arg) {
tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
tcg_out32(s, arg);
- } else {
- tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
- tcg_out32(s, arg);
- tcg_out32(s, arg >> 31 >> 1);
+ return;
+ }
+
+ /* Try a 7 byte pc-relative lea before the 10 byte movq. */
+ diff = arg - ((tcg_target_long)s->code_ptr + 7);
+ if (diff == (int32_t)diff) {
+ tcg_out_opc(s, OPC_LEA | P_REXW, ret, 0, 0);
+ tcg_out8(s, (LOWREGMASK(ret) << 3) | 5);
+ tcg_out32(s, diff);
+ return;
}
+
+ tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
+ tcg_out64(s, arg);
}
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
}
+static inline void tcg_out_sti(TCGContext *s, TCGType type, TCGReg base,
+ tcg_target_long ofs, tcg_target_long val)
+{
+ int opc = OPC_MOVL_EvIz + (type == TCG_TYPE_I64 ? P_REXW : 0);
+ tcg_out_modrm_offset(s, opc, 0, base, ofs);
+ tcg_out32(s, val);
+}
+
static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
{
/* Propagate an opcode prefix, such as P_DATA16. */
#include "exec/softmmu_defs.h"
-/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
- int mmu_idx) */
-static const void *qemu_ld_helpers[4] = {
- helper_ldb_mmu,
- helper_ldw_mmu,
- helper_ldl_mmu,
- helper_ldq_mmu,
+/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ * int mmu_idx, uintptr_t ra)
+ */
+static const void * const qemu_ld_helpers[4] = {
+ helper_ret_ldb_mmu,
+ helper_ret_ldw_mmu,
+ helper_ret_ldl_mmu,
+ helper_ret_ldq_mmu,
};
-/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
- uintxx_t val, int mmu_idx) */
-static const void *qemu_st_helpers[4] = {
- helper_stb_mmu,
- helper_stw_mmu,
- helper_stl_mmu,
- helper_stq_mmu,
+/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ * uintxx_t val, int mmu_idx, uintptr_t ra)
+ */
+static const void * const qemu_st_helpers[4] = {
+ helper_ret_stb_mmu,
+ helper_ret_stw_mmu,
+ helper_ret_stl_mmu,
+ helper_ret_stq_mmu,
};
static void add_qemu_ldst_label(TCGContext *s,
}
}
+/* See the GETPC definition in include/exec/exec-all.h. */
+static inline uintptr_t do_getpc(uint8_t *raddr)
+{
+ return (uintptr_t)raddr - 1;
+}
+
/*
* Generate code for the slow path for a load at the end of block
*/
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
+static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
- int s_bits;
- int opc = label->opc;
- int mem_index = label->mem_index;
-#if TCG_TARGET_REG_BITS == 32
- int stack_adjust;
- int addrlo_reg = label->addrlo_reg;
- int addrhi_reg = label->addrhi_reg;
-#endif
- int data_reg = label->datalo_reg;
- int data_reg2 = label->datahi_reg;
- uint8_t *raddr = label->raddr;
- uint8_t **label_ptr = &label->label_ptr[0];
-
- s_bits = opc & 3;
+ int opc = l->opc;
+ int s_bits = opc & 3;
+ TCGReg data_reg;
+ uint8_t **label_ptr = &l->label_ptr[0];
/* resolve label address */
*(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
*(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
}
-#if TCG_TARGET_REG_BITS == 32
- tcg_out_pushi(s, mem_index);
- stack_adjust = 4;
- if (TARGET_LONG_BITS == 64) {
- tcg_out_push(s, addrhi_reg);
- stack_adjust += 4;
- }
- tcg_out_push(s, addrlo_reg);
- stack_adjust += 4;
- tcg_out_push(s, TCG_AREG0);
- stack_adjust += 4;
-#else
- tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
- /* The second argument is already loaded with addrlo. */
- tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
-#endif
+ if (TCG_TARGET_REG_BITS == 32) {
+ int ofs = 0;
- /* Code generation of qemu_ld/st's slow path calling MMU helper
+ tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
+ ofs += 4;
- PRE_PROC ...
- call MMU helper
- jmp POST_PROC (2b) : short forward jump <- GETRA()
- jmp next_code (5b) : dummy long backward jump which is never executed
- POST_PROC ... : do post-processing <- GETRA() + 7
- jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
- */
+ tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
+ ofs += 4;
- tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
+ if (TARGET_LONG_BITS == 64) {
+ tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
+ ofs += 4;
+ }
- /* Jump to post-processing code */
- tcg_out8(s, OPC_JMP_short);
- tcg_out8(s, 5);
- /* Dummy backward jump having information of fast path'pc for MMU helpers */
- tcg_out8(s, OPC_JMP_long);
- *(int32_t *)s->code_ptr = (int32_t)(raddr - s->code_ptr - 4);
- s->code_ptr += 4;
+ tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
+ ofs += 4;
-#if TCG_TARGET_REG_BITS == 32
- if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
- /* Pop and discard. This is 2 bytes smaller than the add. */
- tcg_out_pop(s, TCG_REG_ECX);
- } else if (stack_adjust != 0) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
+ tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr));
+ } else {
+ tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
+ /* The second argument is already loaded with addrlo. */
+ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+ l->mem_index);
+ tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3],
+ do_getpc(l->raddr));
}
-#endif
+ tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
+
+ data_reg = l->datalo_reg;
switch(opc) {
case 0 | 4:
tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
} else if (data_reg == TCG_REG_EDX) {
/* xchg %edx, %eax */
tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
- tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
+ tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EAX);
} else {
tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
- tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
+ tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EDX);
}
break;
default:
}
/* Jump to the code corresponding to next IR of qemu_st */
- tcg_out_jmp(s, (tcg_target_long)raddr);
+ tcg_out_jmp(s, (tcg_target_long)l->raddr);
}
/*
* Generate code for the slow path for a store at the end of block
*/
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
+static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
{
- int s_bits;
- int stack_adjust;
- int opc = label->opc;
- int mem_index = label->mem_index;
- int data_reg = label->datalo_reg;
-#if TCG_TARGET_REG_BITS == 32
- int data_reg2 = label->datahi_reg;
- int addrlo_reg = label->addrlo_reg;
- int addrhi_reg = label->addrhi_reg;
-#endif
- uint8_t *raddr = label->raddr;
- uint8_t **label_ptr = &label->label_ptr[0];
-
- s_bits = opc & 3;
+ int opc = l->opc;
+ int s_bits = opc & 3;
+ uint8_t **label_ptr = &l->label_ptr[0];
/* resolve label address */
*(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
*(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
}
-#if TCG_TARGET_REG_BITS == 32
- tcg_out_pushi(s, mem_index);
- stack_adjust = 4;
- if (opc == 3) {
- tcg_out_push(s, data_reg2);
- stack_adjust += 4;
- }
- tcg_out_push(s, data_reg);
- stack_adjust += 4;
- if (TARGET_LONG_BITS == 64) {
- tcg_out_push(s, addrhi_reg);
- stack_adjust += 4;
- }
- tcg_out_push(s, addrlo_reg);
- stack_adjust += 4;
- tcg_out_push(s, TCG_AREG0);
- stack_adjust += 4;
-#else
- tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
- /* The second argument is already loaded with addrlo. */
- tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
- tcg_target_call_iarg_regs[2], data_reg);
- tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], mem_index);
- stack_adjust = 0;
-#endif
+ if (TCG_TARGET_REG_BITS == 32) {
+ int ofs = 0;
- /* Code generation of qemu_ld/st's slow path calling MMU helper
+ tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
+ ofs += 4;
- PRE_PROC ...
- call MMU helper
- jmp POST_PROC (2b) : short forward jump <- GETRA()
- jmp next_code (5b) : dummy long backward jump which is never executed
- POST_PROC ... : do post-processing <- GETRA() + 7
- jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
- */
+ tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
+ ofs += 4;
- tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
+ if (TARGET_LONG_BITS == 64) {
+ tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
+ ofs += 4;
+ }
- /* Jump to post-processing code */
- tcg_out8(s, OPC_JMP_short);
- tcg_out8(s, 5);
- /* Dummy backward jump having information of fast path'pc for MMU helpers */
- tcg_out8(s, OPC_JMP_long);
- *(int32_t *)s->code_ptr = (int32_t)(raddr - s->code_ptr - 4);
- s->code_ptr += 4;
+ tcg_out_st(s, TCG_TYPE_I32, l->datalo_reg, TCG_REG_ESP, ofs);
+ ofs += 4;
+
+ if (opc == 3) {
+ tcg_out_st(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_ESP, ofs);
+ ofs += 4;
+ }
- if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
- /* Pop and discard. This is 2 bytes smaller than the add. */
- tcg_out_pop(s, TCG_REG_ECX);
- } else if (stack_adjust != 0) {
- tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
+ tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
+ ofs += 4;
+
+ tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr));
+ } else {
+ uintptr_t pc;
+
+ tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
+ /* The second argument is already loaded with addrlo. */
+ tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
+ tcg_target_call_iarg_regs[2], l->datalo_reg);
+ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+ l->mem_index);
+
+ pc = do_getpc(l->raddr);
+ if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) {
+ tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[4], pc);
+ } else if (pc == (int32_t)pc) {
+ tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, 0, pc);
+ } else {
+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, pc);
+ tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RAX, TCG_REG_ESP, 0);
+ }
}
- /* Jump to the code corresponding to next IR of qemu_st */
- tcg_out_jmp(s, (tcg_target_long)raddr);
+ tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
+
+ tcg_out_jmp(s, (tcg_target_long)l->raddr);
}
/*
static inline void tcg_out16(TCGContext *s, uint16_t v)
{
- *(uint16_t *)s->code_ptr = v;
- s->code_ptr += 2;
+ uint8_t *p = s->code_ptr;
+ *(uint16_t *)p = v;
+ s->code_ptr = p + 2;
}
static inline void tcg_out32(TCGContext *s, uint32_t v)
{
- *(uint32_t *)s->code_ptr = v;
- s->code_ptr += 4;
+ uint8_t *p = s->code_ptr;
+ *(uint32_t *)p = v;
+ s->code_ptr = p + 4;
+}
+
+static inline void tcg_out64(TCGContext *s, uint64_t v)
+{
+ uint8_t *p = s->code_ptr;
+ *(uint64_t *)p = v;
+ s->code_ptr = p + 8;
}
/* label relocation processing */
gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c
check-unit-y += tests/test-string-output-visitor$(EXESUF)
gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c
+check-unit-y += tests/test-opts-visitor$(EXESUF)
+gcov-files-test-opts-visitor-y = qapi/opts-visitor.c
check-unit-y += tests/test-coroutine$(EXESUF)
gcov-files-test-coroutine-y = coroutine-$(CONFIG_COROUTINE_BACKEND).c
check-unit-y += tests/test-visitor-serialization$(EXESUF)
tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
tests/test-qmp-commands.o tests/test-visitor-serialization.o \
- tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o
+ tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \
+ tests/test-opts-visitor.o
test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o
tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) qapi-types.o qapi-visit.o libqemuutil.a libqemustub.a
tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
+tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a
tests/test-bitops$(EXESUF): tests/test-bitops.o libqemuutil.a
* qtest_clock_step_next:
* @s: #QTestState instance to operate on.
*
- * Advance the vm_clock to the next deadline.
+ * Advance the QEMU_CLOCK_VIRTUAL to the next deadline.
*
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
*/
int64_t qtest_clock_step_next(QTestState *s);
* @s: QTestState instance to operate on.
* @step: Number of nanoseconds to advance the clock by.
*
- * Advance the vm_clock by @step nanoseconds.
+ * Advance the QEMU_CLOCK_VIRTUAL by @step nanoseconds.
*
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
*/
int64_t qtest_clock_step(QTestState *s, int64_t step);
* @s: QTestState instance to operate on.
* @val: Nanoseconds value to advance the clock to.
*
- * Advance the vm_clock to @val nanoseconds since the VM was launched.
+ * Advance the QEMU_CLOCK_VIRTUAL to @val nanoseconds since the VM was launched.
*
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
*/
int64_t qtest_clock_set(QTestState *s, int64_t val);
/**
* clock_step_next:
*
- * Advance the vm_clock to the next deadline.
+ * Advance the QEMU_CLOCK_VIRTUAL to the next deadline.
*
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
*/
static inline int64_t clock_step_next(void)
{
* clock_step:
* @step: Number of nanoseconds to advance the clock by.
*
- * Advance the vm_clock by @step nanoseconds.
+ * Advance the QEMU_CLOCK_VIRTUAL by @step nanoseconds.
*
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
*/
static inline int64_t clock_step(int64_t step)
{
* clock_set:
* @val: Nanoseconds value to advance the clock to.
*
- * Advance the vm_clock to @val nanoseconds since the VM was launched.
+ * Advance the QEMU_CLOCK_VIRTUAL to @val nanoseconds since the VM was launched.
*
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
*/
static inline int64_t clock_set(int64_t val)
{
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
{ 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', 'ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' }
+
+# For testing integer range flattening in opts-visitor. The following schema
+# corresponds to the option format:
+#
+# -userdef i64=3-6,i64=-5--1,u64=2,u16=1,u16=7-12
+#
+# For simplicity, this example doesn't use [type=]discriminator nor optargs
+# specific to discriminator values.
+{ 'type': 'UserDefOptions',
+ 'data': {
+ '*i64' : [ 'int' ],
+ '*u64' : [ 'uint64' ],
+ '*u16' : [ 'uint16' ],
+ '*i64x': 'int' ,
+ '*u64x': 'uint64' } }
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]),
- OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')])]
+ OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
+ OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
['EnumOne', 'UserDefUnionKind', 'UserDefNativeListUnionKind']
[OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefOne'), ('data', OrderedDict([('integer', 'int'), ('string', 'str'), ('*enum1', 'EnumOne')]))]),
OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), ('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
- OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))])]
+ OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
#include <glib.h>
#include "block/aio.h"
+#include "qemu/timer.h"
AioContext *ctx;
int max;
} BHTestData;
+typedef struct {
+ QEMUTimer timer;
+ QEMUClockType clock_type;
+ int n;
+ int max;
+ int64_t ns;
+ AioContext *ctx;
+} TimerTestData;
+
static void bh_test_cb(void *opaque)
{
BHTestData *data = opaque;
}
}
+static void timer_test_cb(void *opaque)
+{
+ TimerTestData *data = opaque;
+ if (++data->n < data->max) {
+ timer_mod(&data->timer,
+ qemu_clock_get_ns(data->clock_type) + data->ns);
+ }
+}
+
+static void dummy_io_handler_read(void *opaque)
+{
+}
+
static void bh_delete_cb(void *opaque)
{
BHTestData *data = opaque;
event_notifier_cleanup(&data.e);
}
+static void test_timer_schedule(void)
+{
+ TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
+ .max = 2,
+ .clock_type = QEMU_CLOCK_VIRTUAL };
+ int pipefd[2];
+
+ /* aio_poll will not block to wait for timers to complete unless it has
+ * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
+ */
+ g_assert(!pipe2(pipefd, O_NONBLOCK));
+ aio_set_fd_handler(ctx, pipefd[0],
+ dummy_io_handler_read, NULL, NULL);
+ aio_poll(ctx, false);
+
+ aio_timer_init(ctx, &data.timer, data.clock_type,
+ SCALE_NS, timer_test_cb, &data);
+ timer_mod(&data.timer,
+ qemu_clock_get_ns(data.clock_type) +
+ data.ns);
+
+ g_assert_cmpint(data.n, ==, 0);
+
+ /* timer_mod may well cause an event notifer to have gone off,
+ * so clear that
+ */
+ do {} while (aio_poll(ctx, false));
+
+ g_assert(!aio_poll(ctx, false));
+ g_assert_cmpint(data.n, ==, 0);
+
+ sleep(1);
+ g_assert_cmpint(data.n, ==, 0);
+
+ g_assert(aio_poll(ctx, false));
+ g_assert_cmpint(data.n, ==, 1);
+
+ /* timer_mod called by our callback */
+ do {} while (aio_poll(ctx, false));
+
+ g_assert(!aio_poll(ctx, false));
+ g_assert_cmpint(data.n, ==, 1);
+
+ g_assert(aio_poll(ctx, true));
+ g_assert_cmpint(data.n, ==, 2);
+
+ /* As max is now 2, an event notifier should not have gone off */
+
+ g_assert(!aio_poll(ctx, false));
+ g_assert_cmpint(data.n, ==, 2);
+
+ aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
+ close(pipefd[0]);
+ close(pipefd[1]);
+
+ timer_del(&data.timer);
+}
+
/* Now the same tests, using the context as a GSource. They are
* very similar to the ones above, with g_main_context_iteration
* replacing aio_poll. However:
event_notifier_cleanup(&data.e);
}
+static void test_source_timer_schedule(void)
+{
+ TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
+ .max = 2,
+ .clock_type = QEMU_CLOCK_VIRTUAL };
+ int pipefd[2];
+ int64_t expiry;
+
+ /* aio_poll will not block to wait for timers to complete unless it has
+ * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
+ */
+ g_assert(!pipe2(pipefd, O_NONBLOCK));
+ aio_set_fd_handler(ctx, pipefd[0],
+ dummy_io_handler_read, NULL, NULL);
+ do {} while (g_main_context_iteration(NULL, false));
+
+ aio_timer_init(ctx, &data.timer, data.clock_type,
+ SCALE_NS, timer_test_cb, &data);
+ expiry = qemu_clock_get_ns(data.clock_type) +
+ data.ns;
+ timer_mod(&data.timer, expiry);
+
+ g_assert_cmpint(data.n, ==, 0);
+
+ sleep(1);
+ g_assert_cmpint(data.n, ==, 0);
+
+ g_assert(g_main_context_iteration(NULL, false));
+ g_assert_cmpint(data.n, ==, 1);
+
+ /* The comment above was not kidding when it said this wakes up itself */
+ do {
+ g_assert(g_main_context_iteration(NULL, true));
+ } while (qemu_clock_get_ns(data.clock_type) <= expiry);
+ sleep(1);
+ g_main_context_iteration(NULL, false);
+
+ g_assert_cmpint(data.n, ==, 2);
+
+ aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
+ close(pipefd[0]);
+ close(pipefd[1]);
+
+ timer_del(&data.timer);
+}
+
+
/* End of tests. */
int main(int argc, char **argv)
{
GSource *src;
+ init_clocks();
+
ctx = aio_context_new();
src = aio_get_g_source(ctx);
g_source_attach(src, NULL);
g_test_add_func("/aio/event/wait", test_wait_event_notifier);
g_test_add_func("/aio/event/wait/no-flush-cb", test_wait_event_notifier_noflush);
g_test_add_func("/aio/event/flush", test_flush_event_notifier);
+ g_test_add_func("/aio/timer/schedule", test_timer_schedule);
g_test_add_func("/aio-gsource/notify", test_source_notify);
g_test_add_func("/aio-gsource/flush", test_source_flush);
g_test_add_func("/aio-gsource/event/wait", test_source_wait_event_notifier);
g_test_add_func("/aio-gsource/event/wait/no-flush-cb", test_source_wait_event_notifier_noflush);
g_test_add_func("/aio-gsource/event/flush", test_source_flush_event_notifier);
+ g_test_add_func("/aio-gsource/timer/schedule", test_source_timer_schedule);
return g_test_run();
}
--- /dev/null
+/*
+ * Options Visitor unit-tests.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ * Laszlo Ersek <lersek@redhat.com> (based on test-string-output-visitor)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+
+#include "qemu/config-file.h" /* qemu_add_opts() */
+#include "qemu/option.h" /* qemu_opts_parse() */
+#include "qapi/opts-visitor.h" /* opts_visitor_new() */
+#include "test-qapi-visit.h" /* visit_type_UserDefOptions() */
+#include "qapi/dealloc-visitor.h" /* qapi_dealloc_visitor_new() */
+
+static QemuOptsList userdef_opts = {
+ .name = "userdef",
+ .head = QTAILQ_HEAD_INITIALIZER(userdef_opts.head),
+ .desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+/* fixture (= glib test case context) and test case manipulation */
+
+typedef struct OptsVisitorFixture {
+ UserDefOptions *userdef;
+ Error *err;
+} OptsVisitorFixture;
+
+
+static void
+setup_fixture(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ const char *opts_string = test_data;
+ QemuOpts *opts;
+ OptsVisitor *ov;
+
+ opts = qemu_opts_parse(qemu_find_opts("userdef"), opts_string, 0);
+ g_assert(opts != NULL);
+
+ ov = opts_visitor_new(opts);
+ visit_type_UserDefOptions(opts_get_visitor(ov), &f->userdef, NULL,
+ &f->err);
+ opts_visitor_cleanup(ov);
+ qemu_opts_del(opts);
+}
+
+
+static void
+teardown_fixture(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ if (f->userdef != NULL) {
+ QapiDeallocVisitor *dv;
+
+ dv = qapi_dealloc_visitor_new();
+ visit_type_UserDefOptions(qapi_dealloc_get_visitor(dv), &f->userdef,
+ NULL, NULL);
+ qapi_dealloc_visitor_cleanup(dv);
+ }
+ error_free(f->err);
+}
+
+
+static void
+add_test(const char *testpath,
+ void (*test_func)(OptsVisitorFixture *f, gconstpointer test_data),
+ gconstpointer test_data)
+{
+ g_test_add(testpath, OptsVisitorFixture, test_data, setup_fixture,
+ test_func, teardown_fixture);
+}
+
+/* test output evaluation */
+
+static void
+expect_ok(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ g_assert(f->err == NULL);
+ g_assert(f->userdef != NULL);
+}
+
+
+static void
+expect_fail(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ g_assert(f->err != NULL);
+
+ /* The error message is printed when this test utility is invoked directly
+ * (ie. without gtester) and the --verbose flag is passed:
+ *
+ * tests/test-opts-visitor --verbose
+ */
+ g_test_message("'%s': %s", (const char *)test_data,
+ error_get_pretty(f->err));
+}
+
+
+static void
+test_value(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ uint64_t magic, bitval;
+ intList *i64;
+ uint64List *u64;
+ uint16List *u16;
+
+ expect_ok(f, test_data);
+
+ magic = 0;
+ for (i64 = f->userdef->i64; i64 != NULL; i64 = i64->next) {
+ g_assert(-16 <= i64->value && i64->value < 64-16);
+ bitval = 1ull << (i64->value + 16);
+ g_assert((magic & bitval) == 0);
+ magic |= bitval;
+ }
+ g_assert(magic == 0xDEADBEEF);
+
+ magic = 0;
+ for (u64 = f->userdef->u64; u64 != NULL; u64 = u64->next) {
+ g_assert(u64->value < 64);
+ bitval = 1ull << u64->value;
+ g_assert((magic & bitval) == 0);
+ magic |= bitval;
+ }
+ g_assert(magic == 0xBADC0FFEE0DDF00D);
+
+ magic = 0;
+ for (u16 = f->userdef->u16; u16 != NULL; u16 = u16->next) {
+ g_assert(u16->value < 64);
+ bitval = 1ull << u16->value;
+ g_assert((magic & bitval) == 0);
+ magic |= bitval;
+ }
+ g_assert(magic == 0xD15EA5E);
+}
+
+
+static void
+expect_i64_min(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ expect_ok(f, test_data);
+ g_assert(f->userdef->has_i64);
+ g_assert(f->userdef->i64->next == NULL);
+ g_assert(f->userdef->i64->value == INT64_MIN);
+}
+
+
+static void
+expect_i64_max(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ expect_ok(f, test_data);
+ g_assert(f->userdef->has_i64);
+ g_assert(f->userdef->i64->next == NULL);
+ g_assert(f->userdef->i64->value == INT64_MAX);
+}
+
+
+static void
+expect_zero(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ expect_ok(f, test_data);
+ g_assert(f->userdef->has_u64);
+ g_assert(f->userdef->u64->next == NULL);
+ g_assert(f->userdef->u64->value == 0);
+}
+
+
+static void
+expect_u64_max(OptsVisitorFixture *f, gconstpointer test_data)
+{
+ expect_ok(f, test_data);
+ g_assert(f->userdef->has_u64);
+ g_assert(f->userdef->u64->next == NULL);
+ g_assert(f->userdef->u64->value == UINT64_MAX);
+}
+
+/* test cases */
+
+int
+main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ qemu_add_opts(&userdef_opts);
+
+ /* Three hexadecimal magic numbers, "dead beef", "bad coffee, odd food" and
+ * "disease", from
+ * <http://en.wikipedia.org/wiki/Magic_number_%28programming%29>, were
+ * converted to binary and dissected into bit ranges. Each magic number is
+ * going to be recomposed using the lists called "i64", "u64" and "u16",
+ * respectively.
+ *
+ * (Note that these types pertain to the individual bit shift counts, not
+ * the magic numbers themselves; the intent is to exercise opts_type_int()
+ * and opts_type_uint64().)
+ *
+ * The "i64" shift counts have been decreased by 16 (decimal) in order to
+ * test negative values as well. Finally, the full list of QemuOpt elements
+ * has been permuted with "shuf".
+ *
+ * Both "i64" and "u64" have some (distinct) single-element ranges
+ * represented as both "a" and "a-a". "u16" is a special case of "i64" (see
+ * visit_type_uint16()), so it wouldn't add a separate test in this regard.
+ */
+
+ add_test("/visitor/opts/flatten/value", &test_value,
+ "i64=-1-0,u64=12-16,u64=2-3,i64=-11--9,u64=57,u16=9,i64=5-5,"
+ "u16=1-4,u16=20,u64=63-63,i64=-16--13,u64=50-52,i64=14-15,u16=11,"
+ "i64=7,u16=18,i64=2-3,u16=6,u64=54-55,u64=0,u64=18-20,u64=33-43,"
+ "i64=9-12,u16=26-27,u64=59-61,u16=13-16,u64=29-31,u64=22-23,"
+ "u16=24,i64=-7--3");
+
+ add_test("/visitor/opts/i64/val1/errno", &expect_fail,
+ "i64=0x8000000000000000");
+ add_test("/visitor/opts/i64/val1/empty", &expect_fail, "i64=");
+ add_test("/visitor/opts/i64/val1/trailing", &expect_fail, "i64=5z");
+ add_test("/visitor/opts/i64/nonlist", &expect_fail, "i64x=5-6");
+ add_test("/visitor/opts/i64/val2/errno", &expect_fail,
+ "i64=0x7fffffffffffffff-0x8000000000000000");
+ add_test("/visitor/opts/i64/val2/empty", &expect_fail, "i64=5-");
+ add_test("/visitor/opts/i64/val2/trailing", &expect_fail, "i64=5-6z");
+ add_test("/visitor/opts/i64/range/empty", &expect_fail, "i64=6-5");
+ add_test("/visitor/opts/i64/range/minval", &expect_i64_min,
+ "i64=-0x8000000000000000--0x8000000000000000");
+ add_test("/visitor/opts/i64/range/maxval", &expect_i64_max,
+ "i64=0x7fffffffffffffff-0x7fffffffffffffff");
+
+ add_test("/visitor/opts/u64/val1/errno", &expect_fail, "u64=-1");
+ add_test("/visitor/opts/u64/val1/empty", &expect_fail, "u64=");
+ add_test("/visitor/opts/u64/val1/trailing", &expect_fail, "u64=5z");
+ add_test("/visitor/opts/u64/nonlist", &expect_fail, "u64x=5-6");
+ add_test("/visitor/opts/u64/val2/errno", &expect_fail,
+ "u64=0xffffffffffffffff-0x10000000000000000");
+ add_test("/visitor/opts/u64/val2/empty", &expect_fail, "u64=5-");
+ add_test("/visitor/opts/u64/val2/trailing", &expect_fail, "u64=5-6z");
+ add_test("/visitor/opts/u64/range/empty", &expect_fail, "u64=6-5");
+ add_test("/visitor/opts/u64/range/minval", &expect_zero, "u64=0-0");
+ add_test("/visitor/opts/u64/range/maxval", &expect_u64_max,
+ "u64=0xffffffffffffffff-0xffffffffffffffff");
+
+ /* Test maximum range sizes. The macro value is open-coded here
+ * *intentionally*; the test case must use concrete values by design. If
+ * OPTS_VISITOR_RANGE_MAX is changed, the following values need to be
+ * recalculated as well. The assert and this comment should help with it.
+ */
+ g_assert(OPTS_VISITOR_RANGE_MAX == 65536);
+
+ /* The unsigned case is simple, a u64-u64 difference can always be
+ * represented as a u64.
+ */
+ add_test("/visitor/opts/u64/range/max", &expect_ok, "u64=0-65535");
+ add_test("/visitor/opts/u64/range/2big", &expect_fail, "u64=0-65536");
+
+ /* The same cannot be said about an i64-i64 difference. */
+ add_test("/visitor/opts/i64/range/max/pos/a", &expect_ok,
+ "i64=0x7fffffffffff0000-0x7fffffffffffffff");
+ add_test("/visitor/opts/i64/range/max/pos/b", &expect_ok,
+ "i64=0x7ffffffffffeffff-0x7ffffffffffffffe");
+ add_test("/visitor/opts/i64/range/2big/pos", &expect_fail,
+ "i64=0x7ffffffffffeffff-0x7fffffffffffffff");
+ add_test("/visitor/opts/i64/range/max/neg/a", &expect_ok,
+ "i64=-0x8000000000000000--0x7fffffffffff0001");
+ add_test("/visitor/opts/i64/range/max/neg/b", &expect_ok,
+ "i64=-0x7fffffffffffffff--0x7fffffffffff0000");
+ add_test("/visitor/opts/i64/range/2big/neg", &expect_fail,
+ "i64=-0x8000000000000000--0x7fffffffffff0000");
+ add_test("/visitor/opts/i64/range/2big/full", &expect_fail,
+ "i64=-0x8000000000000000-0x7fffffffffffffff");
+
+ g_test_run();
+ return 0;
+}
#include "block/aio.h"
#include "block/thread-pool.h"
#include "block/block.h"
+#include "qemu/timer.h"
static AioContext *ctx;
static ThreadPool *pool;
{
int ret;
+ init_clocks();
+
ctx = aio_context_new();
pool = aio_get_thread_pool(ctx);
#include "block/block_int.h"
#include "qemu/event_notifier.h"
#include "block/thread-pool.h"
+#include "qemu/main-loop.h"
static void do_spawn_thread(ThreadPool *pool);
}
trace_console_refresh(interval);
}
- ds->last_update = qemu_get_clock_ms(rt_clock);
- qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+ ds->last_update = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+ timer_mod(ds->gui_timer, ds->last_update + interval);
}
static void gui_setup_refresh(DisplayState *ds)
}
if (need_timer && ds->gui_timer == NULL) {
- ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
- qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
+ ds->gui_timer = timer_new_ms(QEMU_CLOCK_REALTIME, gui_update, ds);
+ timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
}
if (!need_timer && ds->gui_timer != NULL) {
- qemu_del_timer(ds->gui_timer);
- qemu_free_timer(ds->gui_timer);
+ timer_del(ds->gui_timer);
+ timer_free(ds->gui_timer);
ds->gui_timer = NULL;
}
DisplayState *ds = s->ds;
if (active_console && active_console->cursor_timer) {
- qemu_del_timer(active_console->cursor_timer);
+ timer_del(active_console->cursor_timer);
}
active_console = s;
if (ds->have_gfx) {
dpy_text_resize(s, s->width, s->height);
}
if (s->cursor_timer) {
- qemu_mod_timer(s->cursor_timer,
- qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
+ timer_mod(s->cursor_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
}
}
}
/* characters are pending: we send them a bit later (XXX:
horrible, should change char device API) */
if (s->out_fifo.count > 0) {
- qemu_mod_timer(s->kbd_timer, qemu_get_clock_ms(rt_clock) + 1);
+ timer_mod(s->kbd_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1);
}
}
dcl->update_interval = interval;
if (!ds->refreshing && ds->update_interval > interval) {
- qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+ timer_mod(ds->gui_timer, ds->last_update + interval);
}
}
s->cursor_visible_phase = !s->cursor_visible_phase;
graphic_hw_invalidate(s);
- qemu_mod_timer(s->cursor_timer,
- qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
+ timer_mod(s->cursor_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
}
static const GraphicHwOps text_console_ops = {
s->out_fifo.buf = s->out_fifo_buf;
s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
- s->kbd_timer = qemu_new_timer_ms(rt_clock, kbd_send_chars, s);
+ s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s);
s->ds = ds;
s->y_displayed = 0;
}
s->cursor_timer =
- qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
+ timer_new_ms(QEMU_CLOCK_REALTIME, text_console_update_cursor, s);
s->hw_ops = &text_console_ops;
s->hw = s;
KeyValueList *p;
if (!key_timer) {
- key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL);
+ key_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, release_keys, NULL);
}
if (keycodes != NULL) {
- qemu_del_timer(key_timer);
+ timer_del(key_timer);
release_keys(NULL);
}
}
/* delayed key up events */
- qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) +
+ timer_mod(key_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
muldiv64(get_ticks_per_sec(), hold_time, 1000));
}
SpiceTimer *timer;
timer = g_malloc0(sizeof(*timer));
- timer->timer = qemu_new_timer_ms(rt_clock, func, opaque);
+ timer->timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
QTAILQ_INSERT_TAIL(&timers, timer, next);
return timer;
}
static void timer_start(SpiceTimer *timer, uint32_t ms)
{
- qemu_mod_timer(timer->timer, qemu_get_clock_ms(rt_clock) + ms);
+ timer_mod(timer->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ms);
}
static void timer_cancel(SpiceTimer *timer)
{
- qemu_del_timer(timer->timer);
+ timer_del(timer->timer);
}
static void timer_remove(SpiceTimer *timer)
{
- qemu_del_timer(timer->timer);
- qemu_free_timer(timer->timer);
+ timer_del(timer->timer);
+ timer_free(timer->timer);
QTAILQ_REMOVE(&timers, timer, next);
g_free(timer);
}
typedef struct VncDisplaySASL VncDisplaySASL;
#include "qemu/acl.h"
+#include "qemu/main-loop.h"
struct VncStateSASL {
sasl_conn_t *conn;
*/
#include "vnc.h"
-
+#include "qemu/main-loop.h"
static void start_auth_vencrypt_subauth(VncState *vs)
{
*/
#include "vnc.h"
+#include "qemu/main-loop.h"
#ifdef CONFIG_VNC_TLS
#include "qemu/sockets.h"
int autostart;
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
-QEMUClock *rtc_clock;
+QEMUClockType rtc_clock;
int vga_interface_type = VGA_NONE;
static int full_screen = 0;
static int no_frame = 0;
value = qemu_opt_get(opts, "clock");
if (value) {
if (!strcmp(value, "host")) {
- rtc_clock = host_clock;
+ rtc_clock = QEMU_CLOCK_HOST;
} else if (!strcmp(value, "rt")) {
- rtc_clock = rt_clock;
+ rtc_clock = QEMU_CLOCK_REALTIME;
} else if (!strcmp(value, "vm")) {
- rtc_clock = vm_clock;
+ rtc_clock = QEMU_CLOCK_VIRTUAL;
} else {
fprintf(stderr, "qemu: invalid option value '%s'\n", value);
exit(1);
qemu_chr_new_from_opts(opts, NULL, &local_err);
if (error_is_set(&local_err)) {
- fprintf(stderr, "%s\n", error_get_pretty(local_err));
+ error_report("%s", error_get_pretty(local_err));
error_free(local_err);
return -1;
}
runstate_init();
init_clocks();
- rtc_clock = host_clock;
+ rtc_clock = QEMU_CLOCK_HOST;
qemu_cache_utils_init(envp);
old_param = 1;
break;
case QEMU_OPTION_clock:
- configure_alarms(optarg);
+ /* Clock options no longer exist. Keep this option for
+ * backward compatibility.
+ */
break;
case QEMU_OPTION_startdate:
configure_rtc_date_offset(optarg, 1);
vnc_display_init(ds);
vnc_display_open(ds, vnc_display, &local_err);
if (local_err != NULL) {
- fprintf(stderr, "Failed to start VNC server on `%s': %s\n",
- vnc_display, error_get_pretty(local_err));
+ error_report("Failed to start VNC server on `%s': %s",
+ vnc_display, error_get_pretty(local_err));
error_free(local_err);
exit(1);
}
Error *local_err = NULL;
qemu_start_incoming_migration(incoming, &local_err);
if (local_err) {
- fprintf(stderr, "-incoming %s: %s\n", incoming, error_get_pretty(local_err));
+ error_report("-incoming %s: %s", incoming,
+ error_get_pretty(local_err));
error_free(local_err);
exit(1);
}
port = xc_evtchn_pending(state->xce_handle);
if (port == state->bufioreq_local_port) {
- qemu_mod_timer(state->buffered_io_timer,
- BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+ timer_mod(state->buffered_io_timer,
+ BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
return NULL;
}
XenIOState *state = opaque;
if (handle_buffered_iopage(state)) {
- qemu_mod_timer(state->buffered_io_timer,
- BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+ timer_mod(state->buffered_io_timer,
+ BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
} else {
- qemu_del_timer(state->buffered_io_timer);
+ timer_del(state->buffered_io_timer);
xc_evtchn_unmask(state->xce_handle, state->bufioreq_local_port);
}
}
evtchn_fd = xc_evtchn_fd(state->xce_handle);
}
- state->buffered_io_timer = qemu_new_timer_ms(rt_clock, handle_buffered_io,
+ state->buffered_io_timer = timer_new_ms(QEMU_CLOCK_REALTIME, handle_buffered_io,
state);
if (evtchn_fd != -1) {