2
0
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:
Bhanuprakash Bodireddy
2017-11-28 22:02:06 +00:00
committed by Ben Pfaff
parent a89e91c6ab
commit ca3cc1aad4
4 changed files with 56 additions and 0 deletions

View File

@@ -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)
{ {

View File

@@ -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);

View File

@@ -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`.

View File

@@ -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);