mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
src: replace clock_gettime()/gettimeofday() with g_get_real_time()
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>
This commit is contained in:
parent
f7df985684
commit
f5e9bdb87f
@ -73,13 +73,10 @@ virDomainMomentDefDispose(void *obj)
|
|||||||
int
|
int
|
||||||
virDomainMomentDefPostParse(virDomainMomentDefPtr def)
|
virDomainMomentDefPostParse(virDomainMomentDefPtr def)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
def->creationTime = g_get_real_time() / (1000*1000);
|
||||||
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
|
|
||||||
if (!def->name)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -235,9 +235,9 @@ libxlTimeoutRegisterEventHook(void *priv,
|
|||||||
void *xl_priv)
|
void *xl_priv)
|
||||||
{
|
{
|
||||||
libxlOSEventHookInfoPtr info;
|
libxlOSEventHookInfoPtr info;
|
||||||
struct timeval now;
|
gint64 now_us;
|
||||||
struct timeval res;
|
gint64 abs_us;
|
||||||
static struct timeval zero;
|
gint64 res_ms;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
|
||||||
if (VIR_ALLOC(info) < 0)
|
if (VIR_ALLOC(info) < 0)
|
||||||
@ -246,15 +246,16 @@ libxlTimeoutRegisterEventHook(void *priv,
|
|||||||
info->ctx = priv;
|
info->ctx = priv;
|
||||||
info->xl_priv = xl_priv;
|
info->xl_priv = xl_priv;
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
now_us = g_get_real_time();
|
||||||
timersub(&abs_t, &now, &res);
|
abs_us = (abs_t.tv_sec * (1000LL*1000LL)) + abs_t.tv_usec;
|
||||||
/* Ensure timeout is not overflowed */
|
if (now_us >= abs_us) {
|
||||||
if (timercmp(&res, &zero, <)) {
|
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
} else if (res.tv_sec > INT_MAX / 1000) {
|
|
||||||
timeout = INT_MAX;
|
|
||||||
} else {
|
} 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->id = virEventAddTimeout(timeout, libxlTimerCallback,
|
||||||
info, libxlOSEventHookInfoFree);
|
info, libxlOSEventHookInfoFree);
|
||||||
|
@ -715,7 +715,6 @@ qemuBackupBegin(virDomainObjPtr vm,
|
|||||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
|
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
|
||||||
g_autoptr(virDomainBackupDef) def = NULL;
|
g_autoptr(virDomainBackupDef) def = NULL;
|
||||||
g_autofree char *suffix = NULL;
|
g_autofree char *suffix = NULL;
|
||||||
struct timeval tv;
|
|
||||||
bool pull = false;
|
bool pull = false;
|
||||||
virDomainMomentObjPtr chk = NULL;
|
virDomainMomentObjPtr chk = NULL;
|
||||||
g_autoptr(virDomainCheckpointDef) chkdef = NULL;
|
g_autoptr(virDomainCheckpointDef) chkdef = NULL;
|
||||||
@ -749,8 +748,8 @@ qemuBackupBegin(virDomainObjPtr vm,
|
|||||||
|
|
||||||
suffix = g_strdup(chkdef->parent.name);
|
suffix = g_strdup(chkdef->parent.name);
|
||||||
} else {
|
} else {
|
||||||
gettimeofday(&tv, NULL);
|
gint64 now_us = g_get_real_time();
|
||||||
suffix = g_strdup_printf("%lld", (long long)tv.tv_sec);
|
suffix = g_strdup_printf("%lld", (long long)now_us/(1000*1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL)
|
if (def->type == VIR_DOMAIN_BACKUP_TYPE_PULL)
|
||||||
|
@ -2052,29 +2052,19 @@ testDomainGetHostname(virDomainPtr domain,
|
|||||||
static int testDomainGetInfo(virDomainPtr domain,
|
static int testDomainGetInfo(virDomainPtr domain,
|
||||||
virDomainInfoPtr info)
|
virDomainInfoPtr info)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
|
||||||
virDomainObjPtr privdom;
|
virDomainObjPtr privdom;
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (!(privdom = testDomObjFromDomain(domain)))
|
if (!(privdom = testDomObjFromDomain(domain)))
|
||||||
return -1;
|
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->state = virDomainObjGetState(privdom, NULL);
|
||||||
info->memory = privdom->def->mem.cur_balloon;
|
info->memory = privdom->def->mem.cur_balloon;
|
||||||
info->maxMem = virDomainDefGetMemoryTotal(privdom->def);
|
info->maxMem = virDomainDefGetMemoryTotal(privdom->def);
|
||||||
info->nrVirtCpu = virDomainDefGetVcpus(privdom->def);
|
info->nrVirtCpu = virDomainDefGetVcpus(privdom->def);
|
||||||
info->cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
|
info->cpuTime = g_get_real_time() * 1000;
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virDomainObjEndAPI(&privdom);
|
virDomainObjEndAPI(&privdom);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2933,7 +2923,6 @@ static int testDomainGetVcpus(virDomainPtr domain,
|
|||||||
size_t i;
|
size_t i;
|
||||||
int hostcpus;
|
int hostcpus;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct timeval tv;
|
|
||||||
unsigned long long statbase;
|
unsigned long long statbase;
|
||||||
virBitmapPtr allcpumap = NULL;
|
virBitmapPtr allcpumap = NULL;
|
||||||
|
|
||||||
@ -2948,13 +2937,7 @@ static int testDomainGetVcpus(virDomainPtr domain,
|
|||||||
|
|
||||||
def = privdom->def;
|
def = privdom->def;
|
||||||
|
|
||||||
if (gettimeofday(&tv, NULL) < 0) {
|
statbase = g_get_real_time();
|
||||||
virReportSystemError(errno,
|
|
||||||
"%s", _("getting time of day"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
statbase = (tv.tv_sec * 1000UL * 1000UL) + tv.tv_usec;
|
|
||||||
|
|
||||||
hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo);
|
hostcpus = VIR_NODEINFO_MAXCPUS(privconn->nodeInfo);
|
||||||
if (!(allcpumap = virBitmapNew(hostcpus)))
|
if (!(allcpumap = virBitmapNew(hostcpus)))
|
||||||
@ -4963,7 +4946,6 @@ static int testDomainBlockStats(virDomainPtr domain,
|
|||||||
virDomainBlockStatsPtr stats)
|
virDomainBlockStatsPtr stats)
|
||||||
{
|
{
|
||||||
virDomainObjPtr privdom;
|
virDomainObjPtr privdom;
|
||||||
struct timeval tv;
|
|
||||||
unsigned long long statbase;
|
unsigned long long statbase;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
@ -4985,19 +4967,13 @@ static int testDomainBlockStats(virDomainPtr domain,
|
|||||||
goto error;
|
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*/
|
/* 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_req = statbase / 10;
|
||||||
stats->rd_bytes = statbase / 20;
|
stats->rd_bytes = statbase / 20;
|
||||||
stats->wr_req = statbase / 30;
|
stats->wr_req = statbase / 30;
|
||||||
stats->wr_bytes = statbase / 40;
|
stats->wr_bytes = statbase / 40;
|
||||||
stats->errs = tv.tv_sec / 2;
|
stats->errs = statbase / (1000LL * 1000LL * 2);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
error:
|
error:
|
||||||
@ -5136,7 +5112,6 @@ testDomainInterfaceStats(virDomainPtr domain,
|
|||||||
virDomainInterfaceStatsPtr stats)
|
virDomainInterfaceStatsPtr stats)
|
||||||
{
|
{
|
||||||
virDomainObjPtr privdom;
|
virDomainObjPtr privdom;
|
||||||
struct timeval tv;
|
|
||||||
unsigned long long statbase;
|
unsigned long long statbase;
|
||||||
virDomainNetDefPtr net = NULL;
|
virDomainNetDefPtr net = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -5151,22 +5126,16 @@ testDomainInterfaceStats(virDomainPtr domain,
|
|||||||
if (!(net = virDomainNetFind(privdom->def, device)))
|
if (!(net = virDomainNetFind(privdom->def, device)))
|
||||||
goto error;
|
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*/
|
/* 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_bytes = statbase / 10;
|
||||||
stats->rx_packets = statbase / 100;
|
stats->rx_packets = statbase / 100;
|
||||||
stats->rx_errs = tv.tv_sec / 1;
|
stats->rx_errs = statbase / (1000LL * 1000LL * 1);
|
||||||
stats->rx_drop = tv.tv_sec / 2;
|
stats->rx_drop = statbase / (1000LL * 1000LL * 2);
|
||||||
stats->tx_bytes = statbase / 20;
|
stats->tx_bytes = statbase / 20;
|
||||||
stats->tx_packets = statbase / 110;
|
stats->tx_packets = statbase / 110;
|
||||||
stats->tx_errs = tv.tv_sec / 3;
|
stats->tx_errs = statbase / (1000LL * 1000LL * 3);
|
||||||
stats->tx_drop = tv.tv_sec / 4;
|
stats->tx_drop = statbase / (1000LL * 1000LL * 4);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
error:
|
error:
|
||||||
|
@ -43,11 +43,6 @@
|
|||||||
|
|
||||||
VIR_LOG_INIT("util.time");
|
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:
|
* virTimeMillisNowRaw:
|
||||||
* @now: filled with current time in milliseconds
|
* @now: filled with current time in milliseconds
|
||||||
@ -59,22 +54,7 @@ VIR_LOG_INIT("util.time");
|
|||||||
*/
|
*/
|
||||||
int virTimeMillisNowRaw(unsigned long long *now)
|
int virTimeMillisNowRaw(unsigned long long *now)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CLOCK_GETTIME
|
*now = g_get_real_time() / 1000;
|
||||||
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
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,20 +262,14 @@ startJob(void)
|
|||||||
static int
|
static int
|
||||||
finishJob(const char *name, int handle, int timer)
|
finishJob(const char *name, int handle, int timer)
|
||||||
{
|
{
|
||||||
|
unsigned long long now_us;
|
||||||
struct timespec waitTime;
|
struct timespec waitTime;
|
||||||
int rc;
|
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);
|
now_us = g_get_real_time();
|
||||||
clock_get_time(cclock, &mts);
|
waitTime.tv_sec = now_us / (1000*1000);
|
||||||
mach_port_deallocate(mach_task_self(), cclock);
|
waitTime.tv_nsec = (now_us % ((now_us / (1000*1000)))) * 1000;
|
||||||
waitTime.tv_sec = mts.tv_sec;
|
|
||||||
waitTime.tv_nsec = mts.tv_nsec;
|
|
||||||
#else
|
|
||||||
clock_gettime(CLOCK_REALTIME, &waitTime);
|
|
||||||
#endif
|
|
||||||
waitTime.tv_sec += 5;
|
waitTime.tv_sec += 5;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
while (!eventThreadJobDone && rc == 0)
|
while (!eventThreadJobDone && rc == 0)
|
||||||
|
@ -4289,7 +4289,7 @@ virshWatchJob(vshControl *ctl,
|
|||||||
struct sigaction old_sig_action;
|
struct sigaction old_sig_action;
|
||||||
struct pollfd pollfd[2] = {{.fd = pipe_fd, .events = POLLIN, .revents = 0},
|
struct pollfd pollfd[2] = {{.fd = pipe_fd, .events = POLLIN, .revents = 0},
|
||||||
{.fd = STDIN_FILENO, .events = POLLIN, .revents = 0}};
|
{.fd = STDIN_FILENO, .events = POLLIN, .revents = 0}};
|
||||||
struct timeval start, curr;
|
unsigned long long start_us, curr_us;
|
||||||
virDomainJobInfo jobinfo;
|
virDomainJobInfo jobinfo;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char retchar;
|
char retchar;
|
||||||
@ -4311,7 +4311,7 @@ virshWatchJob(vshControl *ctl,
|
|||||||
if (!vshTTYAvailable(ctl))
|
if (!vshTTYAvailable(ctl))
|
||||||
npollfd = 1;
|
npollfd = 1;
|
||||||
|
|
||||||
GETTIMEOFDAY(&start);
|
start_us = g_get_real_time();
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = poll((struct pollfd *)&pollfd, npollfd, 500);
|
ret = poll((struct pollfd *)&pollfd, npollfd, 500);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
@ -4345,10 +4345,8 @@ virshWatchJob(vshControl *ctl,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
GETTIMEOFDAY(&curr);
|
curr_us = g_get_real_time();
|
||||||
if (timeout_ms && (((int)(curr.tv_sec - start.tv_sec) * 1000 +
|
if (timeout_ms && ((curr_us - start_us)/1000) > timeout_ms) {
|
||||||
(int)(curr.tv_usec - start.tv_usec) / 1000) >
|
|
||||||
timeout_ms)) {
|
|
||||||
/* suspend the domain when migration timeouts. */
|
/* suspend the domain when migration timeouts. */
|
||||||
vshDebug(ctl, VSH_ERR_DEBUG, "%s timeout", label);
|
vshDebug(ctl, VSH_ERR_DEBUG, "%s timeout", label);
|
||||||
if (timeout_func)
|
if (timeout_func)
|
||||||
|
11
tools/vsh.c
11
tools/vsh.c
@ -1286,11 +1286,10 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd)
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
while (cmd) {
|
while (cmd) {
|
||||||
struct timeval before, after;
|
gint64 before, after;
|
||||||
bool enable_timing = ctl->timing;
|
bool enable_timing = ctl->timing;
|
||||||
|
|
||||||
if (enable_timing)
|
before = g_get_real_time();
|
||||||
GETTIMEOFDAY(&before);
|
|
||||||
|
|
||||||
if ((cmd->def->flags & VSH_CMD_FLAG_NOCONNECT) ||
|
if ((cmd->def->flags & VSH_CMD_FLAG_NOCONNECT) ||
|
||||||
(hooks && hooks->connHandler && hooks->connHandler(ctl))) {
|
(hooks && hooks->connHandler && hooks->connHandler(ctl))) {
|
||||||
@ -1300,8 +1299,7 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd)
|
|||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable_timing)
|
after = g_get_real_time();
|
||||||
GETTIMEOFDAY(&after);
|
|
||||||
|
|
||||||
/* try to automatically catch disconnections */
|
/* try to automatically catch disconnections */
|
||||||
if (!ret &&
|
if (!ret &&
|
||||||
@ -1321,8 +1319,7 @@ vshCommandRun(vshControl *ctl, const vshCmd *cmd)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (enable_timing) {
|
if (enable_timing) {
|
||||||
double diff_ms = (((after.tv_sec - before.tv_sec) * 1000.0) +
|
double diff_ms = (after - before) / 1000.0;
|
||||||
((after.tv_usec - before.tv_usec) / 1000.0));
|
|
||||||
|
|
||||||
vshPrint(ctl, _("\n(Time: %.3f ms)\n\n"), diff_ms);
|
vshPrint(ctl, _("\n(Time: %.3f ms)\n\n"), diff_ms);
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
#define GETTIMEOFDAY(T) gettimeofday(T, NULL)
|
|
||||||
#define VSH_MAX_XML_FILE (10*1024*1024)
|
#define VSH_MAX_XML_FILE (10*1024*1024)
|
||||||
#define VSH_MATCH(FLAG) (flags & (FLAG))
|
#define VSH_MATCH(FLAG) (flags & (FLAG))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user