Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] set_current_state() commentary

Explain the mysteries of set_current_state().

Quoth Linus:

The scheduler itself never needs the memory barrier at all.

The barrier is needed only if the user itself ends up testing some other
thing afterwards, ie if you have

set_process_state(TASK_INTERRUPTIBLE);
if (still_need_to_sleep())
schedule();

then the "still_need_to_sleep()" thing may test flags and wakeup events,
and then you _may_ want to (and often do) make sure that the write of
TASK_INTERRUPTIBLE is serialized wrt the reads of any wakeup data (since
the wakeup may have happened on another CPU).

So the comment is somewhat wrong. We don't really _care_ whether the state
propagates out to other CPU's since all of our actions are purely local,
and there is nothing we do that is conditional on any other CPU: we're
going to sleep unconditionally, and the scheduler only cares about _our_
state, not about somebody elses state.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Andrew Morton and committed by
Linus Torvalds
498d0c57 921717a2

+11
+11
include/linux/sched.h
··· 121 121 #define set_task_state(tsk, state_value) \ 122 122 set_mb((tsk)->state, (state_value)) 123 123 124 + /* 125 + * set_current_state() includes a barrier so that the write of current->state 126 + * is correctly serialised wrt the caller's subsequent test of whether to 127 + * actually sleep: 128 + * 129 + * set_current_state(TASK_UNINTERRUPTIBLE); 130 + * if (do_i_need_to_sleep()) 131 + * schedule(); 132 + * 133 + * If the caller does not need such serialisation then use __set_current_state() 134 + */ 124 135 #define __set_current_state(state_value) \ 125 136 do { current->state = (state_value); } while (0) 126 137 #define set_current_state(state_value) \