X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fhrtimer.c;h=01fa2ae98a8571d7e2d7a4e71c03a423792a0d67;hb=2697c5e1f799f201366d5fd7d25e96a21587f1a9;hp=0237a556eb1f03ab69b1187ce046ed5b6793d7de;hpb=e02a4cabfcb9a999b74a2e2e6f13ffcb7ff2d606;p=linux-2.6 diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 0237a556eb..01fa2ae98a 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -456,6 +456,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) return ret; } +EXPORT_SYMBOL_GPL(hrtimer_start); /** * hrtimer_try_to_cancel - try to deactivate a timer @@ -484,6 +485,7 @@ int hrtimer_try_to_cancel(struct hrtimer *timer) return ret; } +EXPORT_SYMBOL_GPL(hrtimer_try_to_cancel); /** * hrtimer_cancel - cancel a timer and wait for the handler to finish. @@ -501,8 +503,10 @@ int hrtimer_cancel(struct hrtimer *timer) if (ret >= 0) return ret; + cpu_relax(); } } +EXPORT_SYMBOL_GPL(hrtimer_cancel); /** * hrtimer_get_remaining - get remaining time for the timer @@ -521,6 +525,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) return rem; } +EXPORT_SYMBOL_GPL(hrtimer_get_remaining); #ifdef CONFIG_NO_IDLE_HZ /** @@ -579,6 +584,7 @@ void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, timer->base = &bases[clock_id]; timer->node.rb_parent = HRTIMER_INACTIVE; } +EXPORT_SYMBOL_GPL(hrtimer_init); /** * hrtimer_get_res - get the timer resolution for a clock @@ -598,6 +604,7 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp) return 0; } +EXPORT_SYMBOL_GPL(hrtimer_get_res); /* * Expire the per base hrtimer-queue: @@ -606,6 +613,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 +665,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 +694,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 +737,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 +842,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 +866,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, };