[patch] sleep_on() fixes, 2.2.3-1

Ingo Molnar (mingo@chiara.csoma.elte.hu)
Sat, 6 Mar 1999 09:46:54 +0100 (CET)


the attached patch fixes kernel/printk.c's usage of sleep_on(), and
introduces a macro framework to ease waiting for synchron/asynchron
events. (fixes for other, possibly buggy places will be introduced through
the apropriate maintainers). The framework changed a bit since the last
time, there are now 6 macros:

+#define __wait_event(wq, condition) \
+#define wait_event(wq, condition) \
+#define wait_event_cli(wq, condition) \
+#define __wait_event_interruptible(wq, condition) \
+#define wait_event_interruptible(wq, condition) \
+#define wait_event_interruptible_cli(wq, condition) \

the __ variants can be used in places that (for code bloat reasons)
introduce their own waiting functions. the _cli variants are not strictly
necessary, they can be done in the source as well.

-- mingo

--- linux/kernel/printk.c.orig Tue Dec 1 12:34:28 1998
+++ linux/kernel/printk.c Sat Mar 6 09:54:36 1999
@@ -137,15 +137,9 @@
error = verify_area(VERIFY_WRITE,buf,len);
if (error)
goto out;
- cli();
- error = -ERESTARTSYS;
- while (!log_size) {
- if (signal_pending(current)) {
- sti();
- goto out;
- }
- interruptible_sleep_on(&log_wait);
- }
+ error = wait_event_interruptible(log_wait, log_size);
+ if (error)
+ goto out;
i = 0;
while (log_size && i < len) {
c = *((char *) log_buf+log_start);
--- linux/include/linux/sched.h.orig Fri Mar 5 14:27:28 1999
+++ linux/include/linux/sched.h Sat Mar 6 09:56:43 1999
@@ -672,6 +672,82 @@
write_unlock_irqrestore(&waitqueue_lock, flags);
}

+#define __wait_event(wq, condition) \
+do { \
+ struct wait_queue __wait; \
+ \
+ __wait.task = current; \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ current->state = TASK_UNINTERRUPTIBLE; \
+ if (condition) \
+ break; \
+ schedule(); \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event(wq, condition) \
+do { \
+ if (condition) \
+ break; \
+ __wait_event(wq, condition); \
+} while (0)
+
+#define wait_event_cli(wq, condition) \
+ wait_event(wq, \
+ ({ \
+ int __ret; \
+ cli(); \
+ __ret = condition; \
+ sti(); \
+ __ret; \
+ }))
+
+#define __wait_event_interruptible(wq, condition) \
+({ \
+ int __ret = 0; \
+ struct wait_queue __wait; \
+ \
+ __wait.task = current; \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ current->state = TASK_INTERRUPTIBLE; \
+ if (condition) \
+ break; \
+ if (signal_pending(current)) { \
+ __ret = -ERESTARTSYS; \
+ break; \
+ } \
+ schedule(); \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+ __ret; \
+})
+
+#define wait_event_interruptible(wq, condition) \
+({ \
+ int __ret = 0; \
+ if (condition) \
+ goto __out; \
+ __ret = __wait_event_interruptible(wq, condition); \
+__out: \
+ __ret; \
+})
+
+#define wait_event_interruptible_cli(wq, condition) \
+ wait_event_interruptible(wq, \
+ ({ \
+ int __ret; \
+ cli(); \
+ __ret = condition; \
+ sti(); \
+ __ret; \
+ }))
+
+
#define REMOVE_LINKS(p) do { \
(p)->next_task->prev_task = (p)->prev_task; \
(p)->prev_task->next_task = (p)->next_task; \

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/