From fe781dcbf665ba726c7fcfa14586d6c6133f5e6d Mon Sep 17 00:00:00 2001 From: np Date: Thu, 31 Mar 2016 17:11:58 +0000 Subject: [PATCH] Add wait_event_interruptible_timeout to linuxkpi. Submitted by: Krishnamraju Eraparaju @ Chelsio Reviewed by: hselasky@ Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D5776 --- .../linuxkpi/common/include/linux/jiffies.h | 10 ++++ .../linuxkpi/common/include/linux/wait.h | 47 +++++++++++++++++++ sys/compat/linuxkpi/common/src/linux_compat.c | 10 ---- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/jiffies.h b/sys/compat/linuxkpi/common/include/linux/jiffies.h index f7bc5291634..33629ec86ee 100644 --- a/sys/compat/linuxkpi/common/include/linux/jiffies.h +++ b/sys/compat/linuxkpi/common/include/linux/jiffies.h @@ -95,4 +95,14 @@ get_jiffies_64(void) return ((u64)(unsigned)ticks); } +static inline int +linux_timer_jiffies_until(unsigned long expires) +{ + int delta = expires - jiffies; + /* guard against already expired values */ + if (delta < 1) + delta = 1; + return (delta); +} + #endif /* _LINUX_JIFFIES_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h index c62f73519e4..8afea0856bd 100644 --- a/sys/compat/linuxkpi/common/include/linux/wait.h +++ b/sys/compat/linuxkpi/common/include/linux/wait.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -113,6 +114,52 @@ do { \ -_error; \ }) +#define wait_event_interruptible_timeout(q, cond, timeout) \ +({ \ + void *c = &(q).wchan; \ + long end = jiffies + timeout; \ + int __ret = 0; \ + int __rc = 0; \ + \ + if (!(cond)) { \ + for (; __rc == 0;) { \ + sleepq_lock(c); \ + if (cond) { \ + sleepq_release(c); \ + __ret = 1; \ + break; \ + } \ + sleepq_add(c, NULL, "completion", \ + SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0); \ + sleepq_set_timeout(c, linux_timer_jiffies_until(end));\ + __rc = sleepq_timedwait_sig (c, 0); \ + if (__rc != 0) { \ + /* check for timeout or signal. \ + * 0 if the condition evaluated to false\ + * after the timeout elapsed, 1 if the \ + * condition evaluated to true after the\ + * timeout elapsed. \ + */ \ + if (__rc == EWOULDBLOCK) \ + __ret = (cond); \ + else \ + __ret = -ERESTARTSYS; \ + } \ + \ + } \ + } else { \ + /* return remaining jiffies (at least 1) if the \ + * condition evaluated to true before the timeout \ + * elapsed. \ + */ \ + __ret = (end - jiffies); \ + if( __ret < 1 ) \ + __ret = 1; \ + } \ + __ret; \ +}) + + static inline int waitqueue_active(wait_queue_head_t *q) { diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index b8a08015129..d85d4ad7b8e 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -894,16 +894,6 @@ kasprintf(gfp_t gfp, const char *fmt, ...) return (p); } -static int -linux_timer_jiffies_until(unsigned long expires) -{ - int delta = expires - jiffies; - /* guard against already expired values */ - if (delta < 1) - delta = 1; - return (delta); -} - static void linux_timer_callback_wrapper(void *context) { -- 2.45.0