]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - include/linux/wait.h
sched/wait: Make the __wait_event*() interface more friendly
[karo-tx-linux.git] / include / linux / wait.h
index a67fc1635592fd34717ef559049924b1add707ca..bd4bd7b479b62d42cf3ffae8e31bde3a98a5ea54 100644 (file)
@@ -179,18 +179,52 @@ wait_queue_head_t *bit_waitqueue(void *, int);
 #define wake_up_interruptible_sync_poll(x, m)                          \
        __wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, (void *) (m))
 
-#define __wait_event(wq, condition)                                    \
-do {                                                                   \
+#define ___wait_cond_timeout(condition)                                        \
+({                                                                     \
+       bool __cond = (condition);                                      \
+       if (__cond && !__ret)                                           \
+               __ret = 1;                                              \
+       __cond || !__ret;                                               \
+})
+
+#define ___wait_signal_pending(state)                                  \
+       ((state == TASK_INTERRUPTIBLE && signal_pending(current)) ||    \
+        (state == TASK_KILLABLE && fatal_signal_pending(current)))
+
+#define ___wait_event(wq, condition, state, exclusive, ret, cmd)       \
+({                                                                     \
+       __label__ __out;                                                \
        DEFINE_WAIT(__wait);                                            \
+       long __ret = ret;                                               \
                                                                        \
        for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
+               if (exclusive)                                          \
+                       prepare_to_wait_exclusive(&wq, &__wait, state); \
+               else                                                    \
+                       prepare_to_wait(&wq, &__wait, state);           \
+                                                                       \
                if (condition)                                          \
                        break;                                          \
-               schedule();                                             \
+                                                                       \
+               if (___wait_signal_pending(state)) {                    \
+                       __ret = -ERESTARTSYS;                           \
+                       if (exclusive) {                                \
+                               abort_exclusive_wait(&wq, &__wait,      \
+                                                    state, NULL);      \
+                               goto __out;                             \
+                       }                                               \
+                       break;                                          \
+               }                                                       \
+                                                                       \
+               cmd;                                                    \
        }                                                               \
        finish_wait(&wq, &__wait);                                      \
-} while (0)
+__out: __ret;                                                          \
+})
+
+#define __wait_event(wq, condition)                                    \
+       (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0,  \
+                           schedule())
 
 /**
  * wait_event - sleep until a condition gets true
@@ -211,22 +245,10 @@ do {                                                                      \
        __wait_event(wq, condition);                                    \
 } while (0)
 
-#define __wait_event_timeout(wq, condition, ret)                       \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
-               if (condition)                                          \
-                       break;                                          \
-               ret = schedule_timeout(ret);                            \
-               if (!ret)                                               \
-                       break;                                          \
-       }                                                               \
-       if (!ret && (condition))                                        \
-               ret = 1;                                                \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+#define __wait_event_timeout(wq, condition, timeout)                   \
+       ___wait_event(wq, ___wait_cond_timeout(condition),              \
+                     TASK_UNINTERRUPTIBLE, 0, timeout,                 \
+                     __ret = schedule_timeout(__ret))
 
 /**
  * wait_event_timeout - sleep until a condition gets true or a timeout elapses
@@ -249,27 +271,13 @@ do {                                                                      \
 ({                                                                     \
        long __ret = timeout;                                           \
        if (!(condition))                                               \
-               __wait_event_timeout(wq, condition, __ret);             \
+               __ret = __wait_event_timeout(wq, condition, timeout);   \
        __ret;                                                          \
 })
 
-#define __wait_event_interruptible(wq, condition, ret)                 \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);      \
-               if (condition)                                          \
-                       break;                                          \
-               if (!signal_pending(current)) {                         \
-                       schedule();                                     \
-                       continue;                                       \
-               }                                                       \
-               ret = -ERESTARTSYS;                                     \
-               break;                                                  \
-       }                                                               \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+#define __wait_event_interruptible(wq, condition)                      \
+       ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0,          \
+                     schedule())
 
 /**
  * wait_event_interruptible - sleep until a condition gets true
@@ -290,31 +298,14 @@ do {                                                                      \
 ({                                                                     \
        int __ret = 0;                                                  \
        if (!(condition))                                               \
-               __wait_event_interruptible(wq, condition, __ret);       \
+               __ret = __wait_event_interruptible(wq, condition);      \
        __ret;                                                          \
 })
 
-#define __wait_event_interruptible_timeout(wq, condition, ret)         \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);      \
-               if (condition)                                          \
-                       break;                                          \
-               if (!signal_pending(current)) {                         \
-                       ret = schedule_timeout(ret);                    \
-                       if (!ret)                                       \
-                               break;                                  \
-                       continue;                                       \
-               }                                                       \
-               ret = -ERESTARTSYS;                                     \
-               break;                                                  \
-       }                                                               \
-       if (!ret && (condition))                                        \
-               ret = 1;                                                \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+#define __wait_event_interruptible_timeout(wq, condition, timeout)     \
+       ___wait_event(wq, ___wait_cond_timeout(condition),              \
+                     TASK_INTERRUPTIBLE, 0, timeout,                   \
+                     __ret = schedule_timeout(__ret))
 
 /**
  * wait_event_interruptible_timeout - sleep until a condition gets true or a timeout elapses
@@ -338,14 +329,14 @@ do {                                                                      \
 ({                                                                     \
        long __ret = timeout;                                           \
        if (!(condition))                                               \
-               __wait_event_interruptible_timeout(wq, condition, __ret); \
+               __ret = __wait_event_interruptible_timeout(wq,          \
+                                               condition, timeout);    \
        __ret;                                                          \
 })
 
 #define __wait_event_hrtimeout(wq, condition, timeout, state)          \
 ({                                                                     \
        int __ret = 0;                                                  \
-       DEFINE_WAIT(__wait);                                            \
        struct hrtimer_sleeper __t;                                     \
                                                                        \
        hrtimer_init_on_stack(&__t.timer, CLOCK_MONOTONIC,              \
@@ -356,25 +347,15 @@ do {                                                                      \
                                       current->timer_slack_ns,         \
                                       HRTIMER_MODE_REL);               \
                                                                        \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, state);                   \
-               if (condition)                                          \
-                       break;                                          \
-               if (state == TASK_INTERRUPTIBLE &&                      \
-                   signal_pending(current)) {                          \
-                       __ret = -ERESTARTSYS;                           \
-                       break;                                          \
-               }                                                       \
+       __ret = ___wait_event(wq, condition, state, 0, 0,               \
                if (!__t.task) {                                        \
                        __ret = -ETIME;                                 \
                        break;                                          \
                }                                                       \
-               schedule();                                             \
-       }                                                               \
+               schedule());                                            \
                                                                        \
        hrtimer_cancel(&__t.timer);                                     \
        destroy_hrtimer_on_stack(&__t.timer);                           \
-       finish_wait(&wq, &__wait);                                      \
        __ret;                                                          \
 })
 
@@ -428,33 +409,15 @@ do {                                                                      \
        __ret;                                                          \
 })
 
-#define __wait_event_interruptible_exclusive(wq, condition, ret)       \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait_exclusive(&wq, &__wait,                 \
-                                       TASK_INTERRUPTIBLE);            \
-               if (condition) {                                        \
-                       finish_wait(&wq, &__wait);                      \
-                       break;                                          \
-               }                                                       \
-               if (!signal_pending(current)) {                         \
-                       schedule();                                     \
-                       continue;                                       \
-               }                                                       \
-               ret = -ERESTARTSYS;                                     \
-               abort_exclusive_wait(&wq, &__wait,                      \
-                               TASK_INTERRUPTIBLE, NULL);              \
-               break;                                                  \
-       }                                                               \
-} while (0)
+#define __wait_event_interruptible_exclusive(wq, condition)            \
+       ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 1, 0,          \
+                     schedule())
 
 #define wait_event_interruptible_exclusive(wq, condition)              \
 ({                                                                     \
        int __ret = 0;                                                  \
        if (!(condition))                                               \
-               __wait_event_interruptible_exclusive(wq, condition, __ret);\
+               __ret = __wait_event_interruptible_exclusive(wq, condition);\
        __ret;                                                          \
 })
 
@@ -607,23 +570,8 @@ do {                                                                       \
 
 
 
-#define __wait_event_killable(wq, condition, ret)                      \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_KILLABLE);           \
-               if (condition)                                          \
-                       break;                                          \
-               if (!fatal_signal_pending(current)) {                   \
-                       schedule();                                     \
-                       continue;                                       \
-               }                                                       \
-               ret = -ERESTARTSYS;                                     \
-               break;                                                  \
-       }                                                               \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+#define __wait_event_killable(wq, condition)                           \
+       ___wait_event(wq, condition, TASK_KILLABLE, 0, 0, schedule())
 
 /**
  * wait_event_killable - sleep until a condition gets true
@@ -644,26 +592,17 @@ do {                                                                      \
 ({                                                                     \
        int __ret = 0;                                                  \
        if (!(condition))                                               \
-               __wait_event_killable(wq, condition, __ret);            \
+               __ret = __wait_event_killable(wq, condition);           \
        __ret;                                                          \
 })
 
 
 #define __wait_event_lock_irq(wq, condition, lock, cmd)                        \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
-               if (condition)                                          \
-                       break;                                          \
-               spin_unlock_irq(&lock);                                 \
-               cmd;                                                    \
-               schedule();                                             \
-               spin_lock_irq(&lock);                                   \
-       }                                                               \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+       (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0,  \
+                           spin_unlock_irq(&lock);                     \
+                           cmd;                                        \
+                           schedule();                                 \
+                           spin_lock_irq(&lock))
 
 /**
  * wait_event_lock_irq_cmd - sleep until a condition gets true. The
@@ -723,26 +662,12 @@ do {                                                                      \
 } while (0)
 
 
-#define __wait_event_interruptible_lock_irq(wq, condition,             \
-                                           lock, ret, cmd)             \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);      \
-               if (condition)                                          \
-                       break;                                          \
-               if (signal_pending(current)) {                          \
-                       ret = -ERESTARTSYS;                             \
-                       break;                                          \
-               }                                                       \
-               spin_unlock_irq(&lock);                                 \
-               cmd;                                                    \
-               schedule();                                             \
-               spin_lock_irq(&lock);                                   \
-       }                                                               \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+#define __wait_event_interruptible_lock_irq(wq, condition, lock, cmd)  \
+       ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0,          \
+                     spin_unlock_irq(&lock);                           \
+                     cmd;                                              \
+                     schedule();                                       \
+                     spin_lock_irq(&lock))
 
 /**
  * wait_event_interruptible_lock_irq_cmd - sleep until a condition gets true.
@@ -772,10 +697,9 @@ do {                                                                       \
 #define wait_event_interruptible_lock_irq_cmd(wq, condition, lock, cmd)        \
 ({                                                                     \
        int __ret = 0;                                                  \
-                                                                       \
        if (!(condition))                                               \
-               __wait_event_interruptible_lock_irq(wq, condition,      \
-                                                   lock, __ret, cmd);  \
+               __ret = __wait_event_interruptible_lock_irq(wq,         \
+                                               condition, lock, cmd);  \
        __ret;                                                          \
 })
 
@@ -804,34 +728,19 @@ do {                                                                      \
 #define wait_event_interruptible_lock_irq(wq, condition, lock)         \
 ({                                                                     \
        int __ret = 0;                                                  \
-                                                                       \
        if (!(condition))                                               \
-               __wait_event_interruptible_lock_irq(wq, condition,      \
-                                                   lock, __ret, );     \
+               __ret = __wait_event_interruptible_lock_irq(wq,         \
+                                               condition, lock,)       \
        __ret;                                                          \
 })
 
-#define __wait_event_interruptible_lock_irq_timeout(wq, condition,     \
-                                                   lock, ret)          \
-do {                                                                   \
-       DEFINE_WAIT(__wait);                                            \
-                                                                       \
-       for (;;) {                                                      \
-               prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);      \
-               if (condition)                                          \
-                       break;                                          \
-               if (signal_pending(current)) {                          \
-                       ret = -ERESTARTSYS;                             \
-                       break;                                          \
-               }                                                       \
-               spin_unlock_irq(&lock);                                 \
-               ret = schedule_timeout(ret);                            \
-               spin_lock_irq(&lock);                                   \
-               if (!ret)                                               \
-                       break;                                          \
-       }                                                               \
-       finish_wait(&wq, &__wait);                                      \
-} while (0)
+#define __wait_event_interruptible_lock_irq_timeout(wq, condition,     \
+                                                   lock, timeout)      \
+       ___wait_event(wq, ___wait_cond_timeout(condition),              \
+                     TASK_INTERRUPTIBLE, 0, ret,                       \
+                     spin_unlock_irq(&lock);                           \
+                     __ret = schedule_timeout(__ret);                  \
+                     spin_lock_irq(&lock));
 
 /**
  * wait_event_interruptible_lock_irq_timeout - sleep until a condition gets true or a timeout elapses.
@@ -860,11 +769,10 @@ do {                                                                      \
 #define wait_event_interruptible_lock_irq_timeout(wq, condition, lock, \
                                                  timeout)              \
 ({                                                                     \
-       int __ret = timeout;                                            \
-                                                                       \
+       long __ret = timeout;                                           \
        if (!(condition))                                               \
-               __wait_event_interruptible_lock_irq_timeout(            \
-                                       wq, condition, lock, __ret);    \
+               __ret = __wait_event_interruptible_lock_irq_timeout(    \
+                                       wq, condition, lock, timeout);  \
        __ret;                                                          \
 })