aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/wait.h
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-10-07 12:18:24 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-16 08:22:18 -0400
commitc2d816443ef305aba8eaf0bf368f4d3d87494f06 (patch)
tree0331463c4ea621c1467e83894a9cebf3a91cb136 /include/linux/wait.h
parent8922915b38cd8b72f8e5af614b95be71d1d299d4 (diff)
sched/wait: Introduce prepare_to_wait_event()
Add the new helper, prepare_to_wait_event() which should only be used by ___wait_event(). prepare_to_wait_event() returns -ERESTARTSYS if signal_pending_state() is true, otherwise it does prepare_to_wait/exclusive. This allows to uninline the signal-pending checks in wait_event*() macros. Also, it can initialize wait->private/func. We do not care if they were already initialized, the values are the same. This also shaves a couple of insns from the inlined code. This obviously makes prepare_*() path a little bit slower, but we are likely going to sleep anyway, so I think it makes sense to shrink .text: text data bss dec hex filename =================================================== before: 5126092 2959248 10117120 18202460 115bf5c vmlinux after: 5124618 2955152 10117120 18196890 115a99a vmlinux on my build. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20131007161824.GA29757@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/wait.h')
-rw-r--r--include/linux/wait.h24
1 files changed, 14 insertions, 10 deletions
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 04c0260bda8f..ec099b03e11b 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -187,27 +187,30 @@ wait_queue_head_t *bit_waitqueue(void *, int);
187 __cond || !__ret; \ 187 __cond || !__ret; \
188}) 188})
189 189
190#define ___wait_signal_pending(state) \ 190#define ___wait_is_interruptible(state) \
191 ((state == TASK_INTERRUPTIBLE && signal_pending(current)) || \ 191 (!__builtin_constant_p(state) || \
192 (state == TASK_KILLABLE && fatal_signal_pending(current))) 192 state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE) \
193 193
194#define ___wait_event(wq, condition, state, exclusive, ret, cmd) \ 194#define ___wait_event(wq, condition, state, exclusive, ret, cmd) \
195({ \ 195({ \
196 __label__ __out; \ 196 __label__ __out; \
197 DEFINE_WAIT(__wait); \ 197 wait_queue_t __wait; \
198 long __ret = ret; \ 198 long __ret = ret; \
199 \ 199 \
200 INIT_LIST_HEAD(&__wait.task_list); \
201 if (exclusive) \
202 __wait.flags = WQ_FLAG_EXCLUSIVE; \
203 else \
204 __wait.flags = 0; \
205 \
200 for (;;) { \ 206 for (;;) { \
201 if (exclusive) \ 207 long __int = prepare_to_wait_event(&wq, &__wait, state);\
202 prepare_to_wait_exclusive(&wq, &__wait, state); \
203 else \
204 prepare_to_wait(&wq, &__wait, state); \
205 \ 208 \
206 if (condition) \ 209 if (condition) \
207 break; \ 210 break; \
208 \ 211 \
209 if (___wait_signal_pending(state)) { \ 212 if (___wait_is_interruptible(state) && __int) { \
210 __ret = -ERESTARTSYS; \ 213 __ret = __int; \
211 if (exclusive) { \ 214 if (exclusive) { \
212 abort_exclusive_wait(&wq, &__wait, \ 215 abort_exclusive_wait(&wq, &__wait, \
213 state, NULL); \ 216 state, NULL); \
@@ -791,6 +794,7 @@ extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long tim
791 */ 794 */
792void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); 795void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state);
793void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); 796void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state);
797long prepare_to_wait_event(wait_queue_head_t *q, wait_queue_t *wait, int state);
794void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); 798void finish_wait(wait_queue_head_t *q, wait_queue_t *wait);
795void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, unsigned int mode, void *key); 799void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, unsigned int mode, void *key);
796int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); 800int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);