-----Original Message-----
From: Henrik Austad [mailto:[email protected]]
Sent: Tue 2/10/2009 12:18 AM
To: [email protected]
Cc: Himanshu Chauhan; Mulyadi Santosa; Sudheer Divakaran (WT01 - Product 
Engineering Services)
Subject: Re: query regarding scheduling
 
On Monday 09 February 2009 16:56:40 Himanshu Chauhan wrote:
> On Mon, 2009-02-09 at 21:16 +0700, Mulyadi Santosa wrote:
> > Hi...
> >
> > On Mon, Feb 9, 2009 at 2:57 PM,  <[email protected]> wrote:
> > > Hi All,
> > > Please look at the following code from the article Sleeping in the
> > > Kernel
> > >
> > > http://www.linuxjournal.com/node/8144/print
> > >
> > > 1  set_current_state(TASK_INTERRUPTIBLE);
> > > 2  spin_lock(&list_lock);
> > > 3  if(list_empty(&list_head)) {
> > > 4         spin_unlock(&list_lock);
> > > 5         schedule();
> > > 6         spin_lock(&list_lock);
> > > 7  }
> > > 8  set_current_state(TASK_RUNNING);
> > > 9
> > > 10 /* Rest of the code ... */
> > > 11 spin_unlock(&list_lock);
> > >
> > >
> > > Is there any chance for the process getting scheduled out of the
> >
> > run-queue
> >
> > > at Line# 2 (say the scheduler runs because of timer interrupt)??
>
> I don't think schedule() will put you off the runqueue. And I don't see
> the reason also. You didn't call sleep, neither are you doing any IO
> request or anything else that can put you off the runqueue. Schedule()
> is not supposed to put you off. But I might be wrong!

schedule won't put you off the run-queue (state will remain TASK_RUNNING), but 
it *may* pre-empt you, i.e. pick another task from the queue (and insert 
current into the queue).

You may, AFAIK, be pre-empted twice in this scenario, first on return from a 
possible interrupt (let's say a timer-interrupt happens whilst spinning for 
the lock), and then again at schedule(). 

If so, it is still fair, as other tasks are in graver need for running than 
current, and should be allowed to run anyway.

> - Himanshu


-- 
 -> henrik

Hi All,

Thanks for your comments..  I think, as Mulyadi has said, if the scheduler runs 
after setting the process state to TASK_INTERRUPTIBLE,  it will be removed from 
the run queue (as we can see in the 2nd code snippet given below, "Thread 
exiting" message will never be printed). 

In the previous example, assuming that the  process may miss the notification 
from other processes at Line#2 because of scheduling, my third question (best 
solution for preventing that?) was basically disabling preemption. So, if the 
code had taken the spinlock before setting the process state to 
TASK_INTERRUPTIBLE, it would have fixed the notification missing problem. 
Correct?

2  spin_lock(&list_lock);
1  set_current_state(TASK_INTERRUPTIBLE);

3  if(list_empty(&list_head)) {
4         spin_unlock(&list_lock);
5         schedule();
6         spin_lock(&list_lock);
7  }
8  set_current_state(TASK_RUNNING);
9
10 /* Rest of the code ... */
11 spin_unlock(&list_lock);



The following code shows that the process would be removed from the runqueue if 
the task state is set to TASK_INTERRUPTIBLE and scheduler runs afterwards. 
"Thread exiting" message will never be printed.

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>

static int ThreadFn(void *data)
{
        printk(KERN_INFO "In Thread\n");
        
        set_current_state(TASK_INTERRUPTIBLE);
        schedule();

        printk(KERN_INFO "Thread exiting\n");
        return 0;
}


static int __init Load(void)
{
        kthread_run(ThreadFn,NULL,"test1");
        return 0;
}

static void __exit Unload(void)
{
}

MODULE_LICENSE("GPL");
module_init(Load);
module_exit(Unload);


Thanks
Sudheer



Reply via email to