mirror of
https://github.com/openvswitch/ovs
synced 2025-09-03 15:55:19 +00:00
util: Add high resolution sleep support.
This commit introduces xnanosleep() for the threads needing high resolution sleep timeouts. usleep() that provides microsecond granularity is deprecated and threads wanting sub-second(ms,us,ns) granularity can use this implementation. Signed-off-by: Bhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com> Acked-by: Alin Gabriel Serdean <aserdean@ovn.org> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
committed by
Ben Pfaff
parent
a89e91c6ab
commit
ca3cc1aad4
@@ -514,6 +514,25 @@ msec_to_timespec(long long int ms, struct timespec *ts)
|
|||||||
ts->tv_nsec = (ms % 1000) * 1000 * 1000;
|
ts->tv_nsec = (ms % 1000) * 1000 * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsec_to_timespec(long long int nsec, struct timespec *ts)
|
||||||
|
{
|
||||||
|
if (!nsec) {
|
||||||
|
ts->tv_sec = ts->tv_nsec = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ts->tv_sec = nsec / (1000 * 1000 * 1000);
|
||||||
|
|
||||||
|
nsec = nsec % (1000 * 1000 * 1000);
|
||||||
|
/* This is to handle dates before epoch. */
|
||||||
|
if (OVS_UNLIKELY(nsec < 0)) {
|
||||||
|
nsec += 1000 * 1000 * 1000;
|
||||||
|
ts->tv_sec--;
|
||||||
|
}
|
||||||
|
|
||||||
|
ts->tv_nsec = nsec;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
timewarp_work(void)
|
timewarp_work(void)
|
||||||
{
|
{
|
||||||
|
@@ -73,6 +73,7 @@ size_t strftime_msec(char *s, size_t max, const char *format,
|
|||||||
const struct tm_msec *);
|
const struct tm_msec *);
|
||||||
void xgettimeofday(struct timeval *);
|
void xgettimeofday(struct timeval *);
|
||||||
void xclock_gettime(clock_t, struct timespec *);
|
void xclock_gettime(clock_t, struct timespec *);
|
||||||
|
void nsec_to_timespec(long long int, struct timespec *);
|
||||||
|
|
||||||
int get_cpu_usage(void);
|
int get_cpu_usage(void);
|
||||||
|
|
||||||
|
35
lib/util.c
35
lib/util.c
@@ -2205,6 +2205,41 @@ xsleep(unsigned int seconds)
|
|||||||
ovsrcu_quiesce_end();
|
ovsrcu_quiesce_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* High resolution sleep. */
|
||||||
|
void
|
||||||
|
xnanosleep(uint64_t nanoseconds)
|
||||||
|
{
|
||||||
|
ovsrcu_quiesce_start();
|
||||||
|
#ifndef _WIN32
|
||||||
|
int retval;
|
||||||
|
struct timespec ts_sleep;
|
||||||
|
nsec_to_timespec(nanoseconds, &ts_sleep);
|
||||||
|
|
||||||
|
int error = 0;
|
||||||
|
do {
|
||||||
|
retval = nanosleep(&ts_sleep, NULL);
|
||||||
|
error = retval < 0 ? errno : 0;
|
||||||
|
} while (error == EINTR);
|
||||||
|
#else
|
||||||
|
HANDLE timer = CreateWaitableTimer(NULL, FALSE, NULL);
|
||||||
|
if (timer) {
|
||||||
|
LARGE_INTEGER duetime;
|
||||||
|
duetime.QuadPart = -nanoseconds;
|
||||||
|
if (SetWaitableTimer(timer, &duetime, 0, NULL, NULL, FALSE)) {
|
||||||
|
WaitForSingleObject(timer, INFINITE);
|
||||||
|
} else {
|
||||||
|
VLOG_ERR_ONCE("SetWaitableTimer Failed (%s)",
|
||||||
|
ovs_lasterror_to_string());
|
||||||
|
}
|
||||||
|
CloseHandle(timer);
|
||||||
|
} else {
|
||||||
|
VLOG_ERR_ONCE("CreateWaitableTimer Failed (%s)",
|
||||||
|
ovs_lasterror_to_string());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ovsrcu_quiesce_end();
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine whether standard output is a tty or not. This is useful to decide
|
/* Determine whether standard output is a tty or not. This is useful to decide
|
||||||
* whether to use color output or not when --color option for utilities is set
|
* whether to use color output or not when --color option for utilities is set
|
||||||
* to `auto`.
|
* to `auto`.
|
||||||
|
@@ -502,6 +502,7 @@ ovs_u128_and(const ovs_u128 a, const ovs_u128 b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void xsleep(unsigned int seconds);
|
void xsleep(unsigned int seconds);
|
||||||
|
void xnanosleep(uint64_t nanoseconds);
|
||||||
|
|
||||||
bool is_stdout_a_tty(void);
|
bool is_stdout_a_tty(void);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user