[PATCH 12/23] src: replace clock_gettime()/gettimeofday() with g_get_real_time()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux