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