On Tue, 7 Aug 2007, Andrew Morton wrote:
> On Wed, 8 Aug 2007 01:16:49 +0200 (CEST) > Roman Zippel <[EMAIL PROTECTED]> wrote: > > > Hi, > > > > On Tue, 7 Aug 2007, Andrew Morton wrote: > > > > > I'd be surprised if there was significant overhead - the maximum frequency > > > at which msleep() can be called is 1000Hz. We'd need an awful lot of > > > overhead for that to cause problems, surely? > > > > > > <thinks he's missing something again> > > > > _Anybody_ has yet to answer what's wrong with adding a nanosleep() and > > using that instead. > > > > You mean that the implementation could be simplified if msleep() were to > simply call do_nanosleep()? The current msleep is fine and doesn't need any "fixing". Not all the world is i386, _please_ keep hrtimer usage where it's required. Simple timer should be given preference unless the higher resolution is really needed, which is not the case here. > That would work, although a bit of refactoring would be needed so that we > could implement the TASK_UNINTERRUPTIBLE msleep() that way. The function is not that big, so below is a nanosleep implementation based on Jonathan's patch. This will user give a choice, so there is no need to force all users to use hrtimer for a simple sleep. Please apply this patch instead. bye, Roman Signed-off-by: Roman Zippel <[EMAIL PROTECTED]> --- include/linux/delay.h | 5 +++++ kernel/timer.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) Index: linux-2.6/include/linux/delay.h =================================================================== --- linux-2.6.orig/include/linux/delay.h +++ linux-2.6/include/linux/delay.h @@ -9,6 +9,7 @@ extern unsigned long loops_per_jiffy; +#include <linux/ktime.h> #include <asm/delay.h> /* @@ -36,6 +37,10 @@ extern unsigned long loops_per_jiffy; #endif void calibrate_delay(void); + +void nanosleep(ktime_t time); +int nanosleep_interruptible(ktime_t *time); + void msleep(unsigned int msecs); unsigned long msleep_interruptible(unsigned int msecs); Index: linux-2.6/kernel/timer.c =================================================================== --- linux-2.6.orig/kernel/timer.c +++ linux-2.6/kernel/timer.c @@ -1377,3 +1377,52 @@ unsigned long msleep_interruptible(unsig } EXPORT_SYMBOL(msleep_interruptible); + +static int do_nanosleep(ktime_t *time, int sigs) +{ + enum hrtimer_mode mode = HRTIMER_MODE_REL; + int state = sigs ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; + struct hrtimer_sleeper sleeper; + + hrtimer_init_sleeper(&sleeper, current); + hrtimer_init(&sleeper.timer, CLOCK_MONOTONIC, mode); + sleeper.timer.expires = *time; + + do { + set_current_state(state); + hrtimer_start(&sleeper.timer, sleeper.timer.expires, mode); + if (sleeper.task) + schedule(); + hrtimer_cancel(&sleeper.timer); + mode = HRTIMER_MODE_ABS; + if (!sleeper.task) + return 1; + } while (!sigs || !signal_pending(current)); + + *time = sleeper.timer.expires; + return 0; +} + +/** + * nanosleep - sleep safely even with waitqueue interruptions + * @time: Time to sleep for + */ +void nanosleep(ktime_t time) +{ + do_nanosleep(&time, 0); +} +EXPORT_SYMBOL(nanosleep); + +/** + * nanosleep_interruptible - sleep waiting for signals + * @time: Time to sleep for + */ +int nanosleep_interruptible(ktime_t *time) +{ + if (do_nanosleep(time, 1)) + return 1; + + *time = ktime_sub(*time, ktime_get()); + return 0; +} +EXPORT_SYMBOL(nanosleep_interruptible); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/