Putting a thread to sleep using schedule() is foolproof?

Joshi joshiiitr at gmail.com
Sat Jun 14 08:01:39 EDT 2014


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 at citrix.com> wrote:

>
>
>
>
> *From:* kernelnewbies-bounces at kernelnewbies.org [mailto:
> kernelnewbies-bounces at kernelnewbies.org] *On Behalf Of *Joshi
> *Sent:* Wednesday, June 11, 2014 11:33 AM
> *To:* Valdis.Kletnieks at vt.edu
> *Cc:* kernelnewbies at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140614/fd7bd82f/attachment-0001.html 


More information about the Kernelnewbies mailing list