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 <[email protected]> Acked-by: Alin Gabriel Serdean <[email protected]> --- v2 -> v3 * Replace NSEC_PER_SEC Macro with (1000 * 1000 * 1000) 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 b60bf30..193c7ba 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -514,6 +514,25 @@ msec_to_timespec(long long int ms, struct timespec *ts) 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 timewarp_work(void) { diff --git a/lib/timeval.h b/lib/timeval.h index c3dbb51..08d7a9e 100644 --- a/lib/timeval.h +++ b/lib/timeval.h @@ -73,6 +73,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 9e6edd2..62f5fa2 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
