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().
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
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;
}
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)
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);
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;
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)
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
size_t i;
int hostcpus;
int ret = -1;
- struct timeval tv;
unsigned long long statbase;
virBitmapPtr allcpumap = NULL;
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)))
virDomainBlockStatsPtr stats)
{
virDomainObjPtr privdom;
- struct timeval tv;
unsigned long long statbase;
int ret = -1;
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:
virDomainInterfaceStatsPtr stats)
{
virDomainObjPtr privdom;
- struct timeval tv;
unsigned long long statbase;
virDomainNetDefPtr net = NULL;
int ret = -1;
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:
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
*/
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;
}
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)
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;
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) {
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)
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))) {
ret = false;
}
- if (enable_timing)
- GETTIMEOFDAY(&after);
+ after = g_get_real_time();
/* try to automatically catch disconnections */
if (!ret &&
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 {
#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))