But if the state is anything other than TASK_RUNNING, schedule() is attempts to remove the task off run queue. Please see below (implementation of __schedule, called by schedule()) - 2671 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2671> */**2672 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2672> * * Make sure that signal_pending_state()->signal_pending() below*2673 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2673> * * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE)*2674 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2674> * * done by the caller to avoid the race with signal_wake_up().*2675 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2675> * */*2676 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2676> smp_mb__before_spinlock <http://lxr.free-electrons.com/ident?v=3.14;i=smp_mb__before_spinlock>();2677 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2677> raw_spin_lock_irq <http://lxr.free-electrons.com/ident?v=3.14;i=raw_spin_lock_irq>(&rq <http://lxr.free-electrons.com/ident?v=3.14;i=rq>->lock <http://lxr.free-electrons.com/ident?v=3.14;i=lock>);2678 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2678> 2679 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2679> switch_count = &prev->nivcsw;2680 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2680> if (prev->state <http://lxr.free-electrons.com/ident?v=3.14;i=state> && !(preempt_count <http://lxr.free-electrons.com/ident?v=3.14;i=preempt_count>() & PREEMPT_ACTIVE <http://lxr.free-electrons.com/ident?v=3.14;i=PREEMPT_ACTIVE>)) {2681 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2681> if (unlikely <http://lxr.free-electrons.com/ident?v=3.14;i=unlikely>(signal_pending_state <http://lxr.free-electrons.com/ident?v=3.14;i=signal_pending_state>(prev->state <http://lxr.free-electrons.com/ident?v=3.14;i=state>, prev))) {2682 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2682> prev->state <http://lxr.free-electrons.com/ident?v=3.14;i=state> = TASK_RUNNING <http://lxr.free-electrons.com/ident?v=3.14;i=TASK_RUNNING>;2683 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2683> } else {2684 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2684> deactivate_task <http://lxr.free-electrons.com/ident?v=3.14;i=deactivate_task>(rq <http://lxr.free-electrons.com/ident?v=3.14;i=rq>, prev, DEQUEUE_SLEEP <http://lxr.free-electrons.com/ident?v=3.14;i=DEQUEUE_SLEEP>);2685 <http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.14#L2685> prev->on_rq = 0; At line 2684 task is removed. So it will be suspended. However,as per line 2681, there seems to be a case when it may not put a task to sleep. But I am not sure when that can happen. Also comment at line 2672 talks about preventing a race-condition in the caller. I did not understand that. In the code-snippet(in my first post) I did not do anything special in caller to avoid any race condition! On Thu, Jun 12, 2014 at 12:15 AM, Jeff Haran <Jeff.Haran@citrix.com> wrote:
*From:* kernelnewbies-bounces@kernelnewbies.org [mailto: kernelnewbies-bounces@kernelnewbies.org] *On Behalf Of *Joshi *Sent:* Wednesday, June 11, 2014 11:33 AM *To:* Valdis.Kletnieks@vt.edu *Cc:* kernelnewbies@kernelnewbies.org *Subject:* Re: Putting a thread to sleep using schedule() is foolproof?
Is not changing the state to TASK_INTERRUPTIBLE before calling schedule() renders it not-schedulable? I thought task would be removed off run-queue by schedule() because it is in TASK_INTERRUPTIBLE state.
I was making a sort of task queue. Threads puts themselves into this queue when a resource(say memory-space) is not available. And other thread, post releasing the memory space, will wake the first thread in queue.
There are other means to achieve that, but I wondered why the above mentioned method did not succeed in making thread sleep.
I think TASK_INTERRUPTIBLE has to do with whether or not a task can be “interrupted” by a signal, as in wait_event_interruptible().
Jeff Haran
-- Joshi