All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [2.4] add wait_event_interruptible_timeout
@ 2002-09-20 13:45 Solomon Peachy
  0 siblings, 0 replies; only message in thread
From: Solomon Peachy @ 2002-09-20 13:45 UTC (permalink / raw)
  To: linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 832 bytes --]

The sleep_on* series of calls is unsafe, and prone to race conditions.
They've been unofficially deprecated for a while.  Instead, we're
supposed to use the wait_event* series of calls.

There's only one problem with this.  There's no equivalent of
sleep_on_timeout/interruptible_sleep_on_timeout.

So, the attached patch adds 'wait_event_timeout' and
'wait_event_interruptible_timeout'  The diff is generated against
2.4.20-pre7, but should apply cleanly to just about any 2.4/2.2 release,
and maybe even 2.5 as well.

Back to the bit mines..

 - Pizza
-- 
Solomon Peachy                        solomon@linux-wlan.com
AbsoluteValue Systems                 http://www.linux-wlan.com
715-D North Drive                     +1 (321) 259-0737  (office)
Melbourne, FL 32934                   +1 (321) 259-0286  (fax)

[-- Attachment #1.2: sched.diff --]
[-- Type: text/plain, Size: 4941 bytes --]

--- sched.h.old	Fri Sep 20 09:31:02 2002
+++ sched.h	Fri Sep 20 09:47:10 2002
@@ -855,6 +855,87 @@
 	__ret;								\
 })
 
+#define __wait_event_timeout(wq, condition, timeout, ret)   \
+do {                                                                      \
+        int __ret = 0;                                                    \
+        if (!(condition)) {                                               \
+          wait_queue_t __wait;                                            \
+          unsigned long expire;                                           \
+          init_waitqueue_entry(&__wait, current);                         \
+	                                                                  \
+          expire = timeout + jiffies;                                     \
+          add_wait_queue(&wq, &__wait);                                   \
+          for (;;) {                                                      \
+                  set_current_state(TASK_UNINTERRUPTIBLE);                \
+                  if (condition)                                          \
+                          break;                                          \
+                  if (jiffies > expire) {                                 \
+                          ret = jiffies - expire;                         \
+                          break;                                          \
+                  }                                                       \
+                  schedule_timeout(timeout);                              \
+          }                                                               \
+          current->state = TASK_RUNNING;                                  \
+          remove_wait_queue(&wq, &__wait);                                \
+	}                                                                 \
+} while (0)
+/*
+   retval == 0; condition met; we're good.
+   retval > 0; timed out.
+*/
+#define wait_event_timeout(wq, condition, timeout)    	                \
+({									\
+	int __ret = 0;							\
+	if (!(condition))						\
+		__wait_event_timeout(wq, condition,                     \
+						timeout, __ret);	\
+	__ret;								\
+})
+
+#define __wait_event_interruptible_timeout(wq, condition, timeout, ret)   \
+do {                                                                      \
+        int __ret = 0;                                                    \
+        if (!(condition)) {                                               \
+          wait_queue_t __wait;                                            \
+          unsigned long expire;                                           \
+          init_waitqueue_entry(&__wait, current);                         \
+	                                                                  \
+          expire = timeout + jiffies;                                     \
+          add_wait_queue(&wq, &__wait);                                   \
+          for (;;) {                                                      \
+                  set_current_state(TASK_INTERRUPTIBLE);                  \
+                  if (condition)                                          \
+                          break;                                          \
+                  if (jiffies > expire) {                                 \
+                          ret = jiffies - expire;                         \
+                          break;                                          \
+                  }                                                       \
+                  if (!signal_pending(current)) {                         \
+                          schedule_timeout(timeout);                      \
+                          continue;                                       \
+                  }                                                       \
+                  ret = -ERESTARTSYS;                                     \
+                  break;                                                  \
+          }                                                               \
+          current->state = TASK_RUNNING;                                  \
+          remove_wait_queue(&wq, &__wait);                                \
+	}                                                                 \
+} while (0)
+
+/*
+   retval == 0; condition met; we're good.
+   retval < 0; interrupted by signal.
+   retval > 0; timed out.
+*/
+#define wait_event_interruptible_timeout(wq, condition, timeout)	\
+({									\
+	int __ret = 0;							\
+	if (!(condition))						\
+		__wait_event_interruptible_timeout(wq, condition,	\
+						timeout, __ret);	\
+	__ret;								\
+})
+
 #define REMOVE_LINKS(p) do { \
 	(p)->next_task->prev_task = (p)->prev_task; \
 	(p)->prev_task->next_task = (p)->next_task; \

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-09-20 13:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-09-20 13:45 [PATCH] [2.4] add wait_event_interruptible_timeout Solomon Peachy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.