diff options
author | Bhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com> | 2017-11-28 22:02:06 +0000 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2017-11-28 15:53:23 -0800 |
commit | ca3cc1aad46ebc1d2ab653fb75b1affb67d8a6e8 (patch) | |
tree | 04755ac729c5d3587dc75c052047cb670bac16dd | |
parent | a89e91c6abbc7a509dc71fa66831af2f1c90c3df (diff) | |
download | openvswitch-ca3cc1aad46ebc1d2ab653fb75b1affb67d8a6e8.tar.gz |
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>
-rw-r--r-- | lib/timeval.c | 19 | ||||
-rw-r--r-- | lib/timeval.h | 1 | ||||
-rw-r--r-- | lib/util.c | 35 | ||||
-rw-r--r-- | lib/util.h | 1 |
4 files changed, 56 insertions, 0 deletions
diff --git a/lib/timeval.c b/lib/timeval.c index b60bf3067..193c7bab1 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 c3dbb5161..502f703d4 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 9e6edd27a..62f5fa2e0 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 3c43c2c35..d35531336 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); |