aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r--kernel/hrtimer.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 0237a556eb1f..d2a7296c8251 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -501,6 +501,7 @@ int hrtimer_cancel(struct hrtimer *timer)
501 501
502 if (ret >= 0) 502 if (ret >= 0)
503 return ret; 503 return ret;
504 cpu_relax();
504 } 505 }
505} 506}
506 507
@@ -606,6 +607,9 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base)
606{ 607{
607 struct rb_node *node; 608 struct rb_node *node;
608 609
610 if (!base->first)
611 return;
612
609 if (base->get_softirq_time) 613 if (base->get_softirq_time)
610 base->softirq_time = base->get_softirq_time(); 614 base->softirq_time = base->get_softirq_time();
611 615
@@ -655,29 +659,28 @@ void hrtimer_run_queues(void)
655/* 659/*
656 * Sleep related functions: 660 * Sleep related functions:
657 */ 661 */
658 662static int hrtimer_wakeup(struct hrtimer *timer)
659struct sleep_hrtimer {
660 struct hrtimer timer;
661 struct task_struct *task;
662 int expired;
663};
664
665static int nanosleep_wakeup(struct hrtimer *timer)
666{ 663{
667 struct sleep_hrtimer *t = 664 struct hrtimer_sleeper *t =
668 container_of(timer, struct sleep_hrtimer, timer); 665 container_of(timer, struct hrtimer_sleeper, timer);
666 struct task_struct *task = t->task;
669 667
670 t->expired = 1; 668 t->task = NULL;
671 wake_up_process(t->task); 669 if (task)
670 wake_up_process(task);
672 671
673 return HRTIMER_NORESTART; 672 return HRTIMER_NORESTART;
674} 673}
675 674
676static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) 675void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, task_t *task)
677{ 676{
678 t->timer.function = nanosleep_wakeup; 677 sl->timer.function = hrtimer_wakeup;
679 t->task = current; 678 sl->task = task;
680 t->expired = 0; 679}
680
681static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
682{
683 hrtimer_init_sleeper(t, current);
681 684
682 do { 685 do {
683 set_current_state(TASK_INTERRUPTIBLE); 686 set_current_state(TASK_INTERRUPTIBLE);
@@ -685,18 +688,17 @@ static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode)
685 688
686 schedule(); 689 schedule();
687 690
688 if (unlikely(!t->expired)) { 691 hrtimer_cancel(&t->timer);
689 hrtimer_cancel(&t->timer); 692 mode = HRTIMER_ABS;
690 mode = HRTIMER_ABS; 693
691 } 694 } while (t->task && !signal_pending(current));
692 } while (!t->expired && !signal_pending(current));
693 695
694 return t->expired; 696 return t->task == NULL;
695} 697}
696 698
697static long __sched nanosleep_restart(struct restart_block *restart) 699static long __sched nanosleep_restart(struct restart_block *restart)
698{ 700{
699 struct sleep_hrtimer t; 701 struct hrtimer_sleeper t;
700 struct timespec __user *rmtp; 702 struct timespec __user *rmtp;
701 struct timespec tu; 703 struct timespec tu;
702 ktime_t time; 704 ktime_t time;
@@ -729,7 +731,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
729 const enum hrtimer_mode mode, const clockid_t clockid) 731 const enum hrtimer_mode mode, const clockid_t clockid)
730{ 732{
731 struct restart_block *restart; 733 struct restart_block *restart;
732 struct sleep_hrtimer t; 734 struct hrtimer_sleeper t;
733 struct timespec tu; 735 struct timespec tu;
734 ktime_t rem; 736 ktime_t rem;
735 737