* [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.