summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com>2017-11-28 22:02:06 +0000
committerBen Pfaff <blp@ovn.org>2017-11-28 15:53:23 -0800
commitca3cc1aad46ebc1d2ab653fb75b1affb67d8a6e8 (patch)
tree04755ac729c5d3587dc75c052047cb670bac16dd
parenta89e91c6abbc7a509dc71fa66831af2f1c90c3df (diff)
downloadopenvswitch-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.c19
-rw-r--r--lib/timeval.h1
-rw-r--r--lib/util.c35
-rw-r--r--lib/util.h1
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);