On 10/16/05, Jan Hudec <bulb@xxxxxx> wrote: > On Mon, Sep 19, 2005 at 15:13:10 +0900, linux lover wrote: > > You can use schedule_timeout like this > > current->state = TASK_UNINTERRUPTIBLE; > > schedule_timeout(X*HZ); /* Sleep for X seconds */ > > current->state = TASK_INTERRUPTIBLE; > > Um, no. Since preempt went in, this is exactly the one you _can't_ use. > Because a schedule can occur from preempt just between setting the state > to TASK_UNINTERRUPTIBLE and calling schedule_timeout. I don't know how > to operate the necessary preempt stuff though. Well, the code of: set_current_state(TASK_{,UN}INTERRUPTIBLE); schedule_timeout(x_secs*HZ); does work in the kernel, under preempt. But you would not manually keep the task in a sleeping state, that doesn't make sense (i.e. the current->state = TASK_INTERRUPTIBLE assignment after schedule_timeout), as schedule_timeout() guarantees to return in TASK_RUNNING and you're not sleeping again immediately. I guess your concern might be that we might sleep much longer than requested, since we could preempt then sleep the x seconds? Not much you can do there. Code should probably check that it should sleep before calling schedule_timeout, generally. Not to say it can't happen, but I haven't seen anyone report anything like that. But we've changed that anyways now, and you have schedule_timeout_{,un}interruptible(x_secs*HZ); that sets the state for you. You also have msleep{,interruptible}(x_secs*1000); and ssleep(); Plus wait-queues (using wait_event() & co., which sleep). When to use what? If you want to sleep: and are on a waitqueue: and want to wake-up on signals and wait-queue events: schedule_timeout_interruptible(); and want to wake-up on only wait-queue events: schedule_timeout_uninterruptible(); [notice, though, your loadavg is pegged at 1 per each such task] and are not on a waitqueue: and want to wake-up on signals: msleep_interruptible(); and don't want to sleep at least the requested time: msleep(); [again, loadavg gets upped by 1] Now, all sleeps are "at least" the requested anyways, except any early terminating events (the signals or wait-queue events mentioned above), since there may be rounding going on you don't see, and there may be high load when the corresponding kernel timer expires. > Um, and current->state = TASK_<whatever> is not correct either -- there > is a set_current_state macro, that must be used, because unlike the > assignment it's quaranteed to be atomic and block undesired > optimizations. We also have __set_current_state(), which is also atomic (I believe) but does not have an mb, e.g. it should be identical to current->state = TASK_{,UN}INTERRUPTIBLE. You are right, though, if you are calling schedule_timeout() immediately after, then you need the mb-version. > > On 9/19/05, raja <vnagaraju@xxxxxxxxxxxx> wrote: > > > > > > Hi, > > > Would you please tell me how can i sleep in kernel space. > > Um, the above, with schedule_timeout, does not seem to be correct > responese... In fact the correct response would be: In many ways (though > all of them end up calling schedule() underneath). What do you want it > for? > > By the way, TASK_INTERRUUPTIBLE is also sleep. When you > set_current_state(TASK_INTERRUPTIBLE), preempt may call schedule on you > and you won't wake up unless you get a signal. Not entirely true, see above. Thanks, Nish -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/