X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fhrtimer.c;h=b7f0388bd71c80d32eb29f79b0c0319705a8bd7c;hb=1fb5fef9b80d9a3b5368e22031627afd1585487b;hp=0237a556eb1f03ab69b1187ce046ed5b6793d7de;hpb=0bb065f29bffc7895f0dbac1fc7d74b3a8d357a9;p=linux-2.6 diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 0237a556eb..b7f0388bd7 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -501,6 +501,7 @@ int hrtimer_cancel(struct hrtimer *timer) if (ret >= 0) return ret; + cpu_relax(); } } @@ -606,6 +607,9 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base) { struct rb_node *node; + if (!base->first) + return; + if (base->get_softirq_time) base->softirq_time = base->get_softirq_time(); @@ -655,29 +659,28 @@ void hrtimer_run_queues(void) /* * Sleep related functions: */ - -struct sleep_hrtimer { - struct hrtimer timer; - struct task_struct *task; - int expired; -}; - -static int nanosleep_wakeup(struct hrtimer *timer) +static int hrtimer_wakeup(struct hrtimer *timer) { - struct sleep_hrtimer *t = - container_of(timer, struct sleep_hrtimer, timer); + struct hrtimer_sleeper *t = + container_of(timer, struct hrtimer_sleeper, timer); + struct task_struct *task = t->task; - t->expired = 1; - wake_up_process(t->task); + t->task = NULL; + if (task) + wake_up_process(task); return HRTIMER_NORESTART; } -static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) +void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, task_t *task) { - t->timer.function = nanosleep_wakeup; - t->task = current; - t->expired = 0; + sl->timer.function = hrtimer_wakeup; + sl->task = task; +} + +static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) +{ + hrtimer_init_sleeper(t, current); do { set_current_state(TASK_INTERRUPTIBLE); @@ -685,18 +688,17 @@ static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) schedule(); - if (unlikely(!t->expired)) { - hrtimer_cancel(&t->timer); - mode = HRTIMER_ABS; - } - } while (!t->expired && !signal_pending(current)); + hrtimer_cancel(&t->timer); + mode = HRTIMER_ABS; + + } while (t->task && !signal_pending(current)); - return t->expired; + return t->task == NULL; } static long __sched nanosleep_restart(struct restart_block *restart) { - struct sleep_hrtimer t; + struct hrtimer_sleeper t; struct timespec __user *rmtp; struct timespec tu; ktime_t time; @@ -729,7 +731,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, const enum hrtimer_mode mode, const clockid_t clockid) { struct restart_block *restart; - struct sleep_hrtimer t; + struct hrtimer_sleeper t; struct timespec tu; ktime_t rem; @@ -834,7 +836,7 @@ static void migrate_hrtimers(int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __devinit hrtimer_cpu_notify(struct notifier_block *self, +static int hrtimer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { long cpu = (long)hcpu; @@ -858,7 +860,7 @@ static int __devinit hrtimer_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __devinitdata hrtimers_nb = { +static struct notifier_block hrtimers_nb = { .notifier_call = hrtimer_cpu_notify, };