g_get_real_time() returns the time since epoch in microseconds. It uses gettimeofday() internally while libvirt used clock_gettime because it is declared async signal safe. In practice gettimeofday is also async signal safe *provided* the timezone parameter is NULL. This is indeed the case in g_get_real_time(). Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- src/conf/moment_conf.c | 7 ++---- src/libxl/libxl_driver.c | 21 +++++++++-------- src/qemu/qemu_backup.c | 5 ++-- src/test/test_driver.c | 51 ++++++++-------------------------------- src/util/virtime.c | 22 +---------------- tests/eventtest.c | 18 +++++--------- tools/virsh-domain.c | 10 ++++---- tools/vsh.c | 11 ++++----- tools/vsh.h | 1 - 9 files changed, 40 insertions(+), 106 deletions(-) diff --git a/src/conf/moment_conf.c b/src/conf/moment_conf.c index d02fcb89e2..fb6f7824cb 100644 --- a/src/conf/moment_conf.c +++ b/src/conf/moment_conf.c @@ -73,13 +73,10 @@ virDomainMomentDefDispose(void *obj) int virDomainMomentDefPostParse(virDomainMomentDefPtr def) { - struct timeval tv; - - gettimeofday(&tv, NULL); + def->creationTime = g_get_real_time() / (1000*1000); if (!def->name) - def->name = g_strdup_printf("%lld", (long long)tv.tv_sec); + def->name = g_strdup_printf("%lld", def->creationTime); - def->creationTime = tv.tv_sec; return 0; } diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index b2f191b2ac..f021ec9c5d 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -235,9 +235,9 @@ libxlTimeoutRegisterEventHook(void *priv, void *xl_priv) { libxlOSEventHookInfoPtr info; - struct timeval now; - struct timeval res; - static struct timeval zero; + gint64 now_us; + gint64 abs_us; + gint64 res_ms; int timeout; if (VIR_ALLOC(info) < 0) @@ -246,15 +246,16 @@ libxlTimeoutRegisterEventHook(void *priv, info->ctx = priv; info->xl_priv = xl_priv; - gettimeofday(&now, NULL); - timersub(&abs_t, &now, &res); - /* Ensure timeout is not overflowed */ - if (timercmp(&res, &zero, <)) { + now_us = g_get_real_time(); + abs_us = (abs_t.tv_sec * (1000LL*1000LL)) + abs_t.tv_usec; + if (now_us >= abs_us) { timeout = 0; - } else if (res.tv_sec > INT_MAX / 1000) { - timeout = INT_MAX; } else { - timeout = res.tv_sec * 1000 + (res.tv_usec + 999) / 1000; + res_ms = (abs_us - now_us) / 1000; + if (res_ms > INT_MAX) + timeout = INT_MAX; + else + timeout = res_ms; } info->id = virEventAddTimeout(timeout, libxlTimerCallback, info, libxlOSEventHookInfoFree); diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 294d5999a0..a039beaede 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -715,7 +715,6 @@ qemuBackupBegin(virDomainObjPtr vm, g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); g_autoptr(virDomainBackupDef) def = NULL; g_autofree char *suffix = NULL; - struct timeval tv; bool pull = false; virDomainMomentObjPtr chk = NULL; g_autoptr(virDomainCheckpointDef) chkdef = NULL; @@ -749,8 +748,8 @@ qemuBackupBegin(virDomainObjPtr vm, suffix = g_strdup(chkdef->parent.name); } else { - gettimeofday(&tv, NULL); - suffix = g_strdup_printf("%lld", (long long)tv.tv_sec); + gint64 now_us = g_get_real_time(); + suffix = g_strdup_printf("%lld", (long long)now_us/(1000*1000)); } if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 2e4ecfd0ff..f8e08dcf07 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2052,29 +2052,19 @@ testDomainGetHostname(virDomainPtr domain, static int testDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) { - struct timeval tv; virDomainObjPtr privdom; - int ret = -1; if (!(privdom = testDomObjFromDomain(domain))) return -1; - if (gettimeofday(&tv, NULL) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("getting time of day")); - goto cleanup; - } - info->state = virDomainObjGetState(privdom, NULL); info->memory = privdom->def->mem.cur_balloon; info->maxMem = virDomainDefGetMemoryTotal(privdom->def); info->nrVirtCpu = virDomainDefGetVcpus(privdom->def); - info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll)); - ret = 0; + info->cpuTime = g_get_real_time() * 1000; - cleanup: virDomainObjEndAPI(&privdom); - return ret; + return 0; } static int @@ -2933,7 +2923,6 @@ static int testDomainGetVcpus(virDomainPtr domain, size_t i; int hostcpus; int ret = -1; - struct timeval tv; unsigned long long statbase; virBitmapPtr allcpumap = NULL; @@ -2948,13 +2937,7 @@ static int testDomainGetVcpus(virDomainPtr domain, def = privdom->def; - if (gettimeofday(&tv, NULL) < 0) { - virReportSystemError(errno, - "%s", _("getting time of day")); - goto cleanup; - } - - statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec; + statbase = g_get_real_time(); hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo); if (!(allcpumap = virBitmapNew(hostcpus))) @@ -4963,7 +4946,6 @@ static int testDomainBlockStats(virDomainPtr domain, virDomainBlockStatsPtr stats) { virDomainObjPtr privdom; - struct timeval tv; unsigned long long statbase; int ret = -1; @@ -4985,19 +4967,13 @@ static int testDomainBlockStats(virDomainPtr domain, goto error; } - if (gettimeofday(&tv, NULL) < 0) { - virReportSystemError(errno, - "%s", _("getting time of day")); - goto error; - } - /* No significance to these numbers, just enough to mix it up*/ - statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec; + statbase = g_get_real_time(); stats->rd_req = statbase / 10; stats->rd_bytes = statbase / 20; stats->wr_req = statbase / 30; stats->wr_bytes = statbase / 40; - stats->errs = tv.tv_sec / 2; + stats->errs = statbase / (1000LL * 1000LL * 2); ret = 0; error: @@ -5136,7 +5112,6 @@ testDomainInterfaceStats(virDomainPtr domain, virDomainInterfaceStatsPtr stats) { virDomainObjPtr privdom; - struct timeval tv; unsigned long long statbase; virDomainNetDefPtr net = NULL; int ret = -1; @@ -5151,22 +5126,16 @@ testDomainInterfaceStats(virDomainPtr domain, if (!(net = virDomainNetFind(privdom->def, device))) goto error; - if (gettimeofday(&tv, NULL) < 0) { - virReportSystemError(errno, - "%s", _("getting time of day")); - goto error; - } - /* No significance to these numbers, just enough to mix it up*/ - statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec; + statbase = g_get_real_time(); stats->rx_bytes = statbase / 10; stats->rx_packets = statbase / 100; - stats->rx_errs = tv.tv_sec / 1; - stats->rx_drop = tv.tv_sec / 2; + stats->rx_errs = statbase / (1000LL * 1000LL * 1); + stats->rx_drop = statbase / (1000LL * 1000LL * 2); stats->tx_bytes = statbase / 20; stats->tx_packets = statbase / 110; - stats->tx_errs = tv.tv_sec / 3; - stats->tx_drop = tv.tv_sec / 4; + stats->tx_errs = statbase / (1000LL * 1000LL * 3); + stats->tx_drop = statbase / (1000LL * 1000LL * 4); ret = 0; error: diff --git a/src/util/virtime.c b/src/util/virtime.c index 701b2f085a..54466b2f39 100644 --- a/src/util/virtime.c +++ b/src/util/virtime.c @@ -43,11 +43,6 @@ VIR_LOG_INIT("util.time"); -/* We prefer clock_gettime if available because that is officially - * async signal safe according to POSIX. Many platforms lack it - * though, so fallback to gettimeofday everywhere else - */ - /** * virTimeMillisNowRaw: * @now: filled with current time in milliseconds @@ -59,22 +54,7 @@ VIR_LOG_INIT("util.time"); */ int virTimeMillisNowRaw(unsigned long long *now) { -#ifdef HAVE_CLOCK_GETTIME - struct timespec ts; - - if (clock_gettime(CLOCK_REALTIME, &ts) < 0) - return -1; - - *now = (ts.tv_sec * 1000ull) + (ts.tv_nsec / (1000ull * 1000ull)); -#else - struct timeval tv; - - if (gettimeofday(&tv, NULL) < 0) - return -1; - - *now = (tv.tv_sec * 1000ull) + (tv.tv_usec / 1000ull); -#endif - + *now = g_get_real_time() / 1000; return 0; } diff --git a/tests/eventtest.c b/tests/eventtest.c index fdd732f7fa..a16922874a 100644 --- a/tests/eventtest.c +++ b/tests/eventtest.c @@ -262,20 +262,14 @@ startJob(void) static int finishJob(const char *name, int handle, int timer) { + unsigned long long now_us; struct timespec waitTime; int rc; -#if HAVE_MACH_CLOCK_ROUTINES - clock_serv_t cclock; - mach_timespec_t mts; - - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - waitTime.tv_sec = mts.tv_sec; - waitTime.tv_nsec = mts.tv_nsec; -#else - clock_gettime(CLOCK_REALTIME, &waitTime); -#endif + + now_us = g_get_real_time(); + waitTime.tv_sec = now_us / (1000*1000); + waitTime.tv_nsec = (now_us % ((now_us / (1000*1000)))) * 1000; + waitTime.tv_sec += 5; rc = 0; while (!eventThreadJobDone && rc == 0) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 9d4cdd26dd..9315755990 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4289,7 +4289,7 @@ virshWatchJob(vshControl *ctl, struct sigaction old_sig_action; struct pollfd pollfd[2] = {{.fd = pipe_fd, .events = POLLIN, .revents = 0}, {.fd = STDIN_FILENO, .events = POLLIN, .revents = 0}}; - struct timeval start, curr; + unsigned long long start_us, curr_us; virDomainJobInfo jobinfo; int ret = -1; char retchar; @@ -4311,7 +4311,7 @@ virshWatchJob(vshControl *ctl, if (!vshTTYAvailable(ctl)) npollfd = 1; - GETTIMEOFDAY(&start); + start_us = g_get_real_time(); while (1) { ret = poll((struct pollfd *)&pollfd, npollfd, 500); if (ret > 0) { @@ -4345,10 +4345,8 @@ virshWatchJob(vshControl *ctl, goto cleanup; } - GETTIMEOFDAY(&curr); - if (timeout_ms && (((int)(curr.tv_sec - start.tv_sec) * 1000 + - (int)(curr.tv_usec - start.tv_usec) / 1000) > - timeout_ms)) { + curr_us = g_get_real_time(); + if (timeout_ms && ((curr_us - start_us)/1000) > timeout_ms) { /* suspend the domain when migration timeouts. */ vshDebug(ctl, VSH_ERR_DEBUG, "%s timeout", label); if (timeout_func) diff --git a/tools/vsh.c b/tools/vsh.c index b982aeb359..a2f33e01aa 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1286,11 +1286,10 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd) bool ret = true; while (cmd) { - struct timeval before, after; + gint64 before, after; bool enable_timing = ctl->timing; - if (enable_timing) - GETTIMEOFDAY(&before); + before = g_get_real_time(); if ((cmd->def->flags & VSH_CMD_FLAG_NOCONNECT) || (hooks && hooks->connHandler && hooks->connHandler(ctl))) { @@ -1300,8 +1299,7 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd) ret = false; } - if (enable_timing) - GETTIMEOFDAY(&after); + after = g_get_real_time(); /* try to automatically catch disconnections */ if (!ret && @@ -1321,8 +1319,7 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd) return ret; if (enable_timing) { - double diff_ms = (((after.tv_sec - before.tv_sec) * 1000.0) + - ((after.tv_usec - before.tv_usec) / 1000.0)); + double diff_ms = (after - before) / 1000.0; vshPrint(ctl, _("\n(Time: %.3f ms)\n\n"), diff_ms); } else { diff --git a/tools/vsh.h b/tools/vsh.h index b6ac070f10..960cae8df0 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -31,7 +31,6 @@ #define VIR_FROM_THIS VIR_FROM_NONE -#define GETTIMEOFDAY(T) gettimeofday(T, NULL) #define VSH_MAX_XML_FILE (10*1024*1024) #define VSH_MATCH(FLAG) (flags & (FLAG)) -- 2.24.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list