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. CC: Aaron Conole <[email protected]> CC: Alin Gabriel Serdean <[email protected]> CC: Ben Pfaff <[email protected]> Signed-off-by: Bhanuprakash Bodireddy <[email protected]> --- lib/timeval.c | 19 +++++++++++++++++++ lib/timeval.h | 1 + lib/util.c | 35 +++++++++++++++++++++++++++++++++++ lib/util.h | 1 + 4 files changed, 56 insertions(+) diff --git a/lib/timeval.c b/lib/timeval.c index 567c26e..2fde90f 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -517,6 +517,25 @@ msec_to_timespec(long long int ms, struct timespec *ts) ts->tv_nsec = (ms % 1000) * NSEC_PER_MSEC; } +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 / NSEC_PER_SEC; + + nsec = nsec % NSEC_PER_SEC; + /* This is to handle dates before epoch. */ + if (OVS_UNLIKELY(nsec < 0)) { + nsec += NSEC_PER_SEC; + ts->tv_sec--; + } + + ts->tv_nsec = nsec; +} + static void timewarp_work(void) { diff --git a/lib/timeval.h b/lib/timeval.h index 5e2a731..095c334 100644 --- a/lib/timeval.h +++ b/lib/timeval.h @@ -80,6 +80,7 @@ size_t strftime_msec(char *s, size_t max, const char *format, const struct tm_msec *); void xgettimeofday(struct timeval *); void xclock_gettime(clock_t, struct timespec *); +void nsec_to_timespec(long long int , struct timespec *); int get_cpu_usage(void); diff --git a/lib/util.c b/lib/util.c index 17c2c99..2c184d9 100644 --- a/lib/util.c +++ b/lib/util.c @@ -2205,6 +2205,41 @@ xsleep(unsigned int seconds) 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 * whether to use color output or not when --color option for utilities is set * to `auto`. diff --git a/lib/util.h b/lib/util.h index 3c43c2c..d355313 100644 --- a/lib/util.h +++ b/lib/util.h @@ -502,6 +502,7 @@ ovs_u128_and(const ovs_u128 a, const ovs_u128 b) } void xsleep(unsigned int seconds); +void xnanosleep(uint64_t nanoseconds); bool is_stdout_a_tty(void); -- 2.4.11 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
