diff options
Diffstat (limited to 'kernel/posix-timers.c')
-rw-r--r-- | kernel/posix-timers.c | 53 |
1 files changed, 17 insertions, 36 deletions
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 197208b3aa2a..216f574b5ffb 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -194,9 +194,7 @@ static inline int common_clock_set(const clockid_t which_clock, | |||
194 | 194 | ||
195 | static int common_timer_create(struct k_itimer *new_timer) | 195 | static int common_timer_create(struct k_itimer *new_timer) |
196 | { | 196 | { |
197 | hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock); | 197 | hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); |
198 | new_timer->it.real.timer.data = new_timer; | ||
199 | new_timer->it.real.timer.function = posix_timer_fn; | ||
200 | return 0; | 198 | return 0; |
201 | } | 199 | } |
202 | 200 | ||
@@ -290,7 +288,8 @@ void do_schedule_next_timer(struct siginfo *info) | |||
290 | info->si_overrun = timr->it_overrun_last; | 288 | info->si_overrun = timr->it_overrun_last; |
291 | } | 289 | } |
292 | 290 | ||
293 | unlock_timer(timr, flags); | 291 | if (timr) |
292 | unlock_timer(timr, flags); | ||
294 | } | 293 | } |
295 | 294 | ||
296 | int posix_timer_event(struct k_itimer *timr,int si_private) | 295 | int posix_timer_event(struct k_itimer *timr,int si_private) |
@@ -692,6 +691,7 @@ common_timer_set(struct k_itimer *timr, int flags, | |||
692 | struct itimerspec *new_setting, struct itimerspec *old_setting) | 691 | struct itimerspec *new_setting, struct itimerspec *old_setting) |
693 | { | 692 | { |
694 | struct hrtimer *timer = &timr->it.real.timer; | 693 | struct hrtimer *timer = &timr->it.real.timer; |
694 | enum hrtimer_mode mode; | ||
695 | 695 | ||
696 | if (old_setting) | 696 | if (old_setting) |
697 | common_timer_get(timr, old_setting); | 697 | common_timer_get(timr, old_setting); |
@@ -713,14 +713,10 @@ common_timer_set(struct k_itimer *timr, int flags, | |||
713 | if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) | 713 | if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) |
714 | return 0; | 714 | return 0; |
715 | 715 | ||
716 | /* Posix madness. Only absolute CLOCK_REALTIME timers | 716 | mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL; |
717 | * are affected by clock sets. So we must reiniatilize | 717 | hrtimer_init(&timr->it.real.timer, timr->it_clock, mode); |
718 | * the timer. | 718 | timr->it.real.timer.data = timr; |
719 | */ | 719 | timr->it.real.timer.function = posix_timer_fn; |
720 | if (timr->it_clock == CLOCK_REALTIME && (flags & TIMER_ABSTIME)) | ||
721 | hrtimer_rebase(timer, CLOCK_REALTIME); | ||
722 | else | ||
723 | hrtimer_rebase(timer, CLOCK_MONOTONIC); | ||
724 | 720 | ||
725 | timer->expires = timespec_to_ktime(new_setting->it_value); | 721 | timer->expires = timespec_to_ktime(new_setting->it_value); |
726 | 722 | ||
@@ -728,11 +724,15 @@ common_timer_set(struct k_itimer *timr, int flags, | |||
728 | timr->it.real.interval = timespec_to_ktime(new_setting->it_interval); | 724 | timr->it.real.interval = timespec_to_ktime(new_setting->it_interval); |
729 | 725 | ||
730 | /* SIGEV_NONE timers are not queued ! See common_timer_get */ | 726 | /* SIGEV_NONE timers are not queued ! See common_timer_get */ |
731 | if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) | 727 | if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { |
728 | /* Setup correct expiry time for relative timers */ | ||
729 | if (mode == HRTIMER_REL) | ||
730 | timer->expires = ktime_add(timer->expires, | ||
731 | timer->base->get_time()); | ||
732 | return 0; | 732 | return 0; |
733 | } | ||
733 | 734 | ||
734 | hrtimer_start(timer, timer->expires, (flags & TIMER_ABSTIME) ? | 735 | hrtimer_start(timer, timer->expires, mode); |
735 | HRTIMER_ABS : HRTIMER_REL); | ||
736 | return 0; | 736 | return 0; |
737 | } | 737 | } |
738 | 738 | ||
@@ -875,12 +875,6 @@ int do_posix_clock_nosettime(const clockid_t clockid, struct timespec *tp) | |||
875 | } | 875 | } |
876 | EXPORT_SYMBOL_GPL(do_posix_clock_nosettime); | 876 | EXPORT_SYMBOL_GPL(do_posix_clock_nosettime); |
877 | 877 | ||
878 | int do_posix_clock_notimer_create(struct k_itimer *timer) | ||
879 | { | ||
880 | return -EINVAL; | ||
881 | } | ||
882 | EXPORT_SYMBOL_GPL(do_posix_clock_notimer_create); | ||
883 | |||
884 | int do_posix_clock_nonanosleep(const clockid_t clock, int flags, | 878 | int do_posix_clock_nonanosleep(const clockid_t clock, int flags, |
885 | struct timespec *t, struct timespec __user *r) | 879 | struct timespec *t, struct timespec __user *r) |
886 | { | 880 | { |
@@ -947,21 +941,8 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) | |||
947 | static int common_nsleep(const clockid_t which_clock, int flags, | 941 | static int common_nsleep(const clockid_t which_clock, int flags, |
948 | struct timespec *tsave, struct timespec __user *rmtp) | 942 | struct timespec *tsave, struct timespec __user *rmtp) |
949 | { | 943 | { |
950 | int mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL; | 944 | return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? |
951 | int clockid = which_clock; | 945 | HRTIMER_ABS : HRTIMER_REL, which_clock); |
952 | |||
953 | switch (which_clock) { | ||
954 | case CLOCK_REALTIME: | ||
955 | /* Posix madness. Only absolute timers on clock realtime | ||
956 | are affected by clock set. */ | ||
957 | if (mode != HRTIMER_ABS) | ||
958 | clockid = CLOCK_MONOTONIC; | ||
959 | case CLOCK_MONOTONIC: | ||
960 | break; | ||
961 | default: | ||
962 | return -EINVAL; | ||
963 | } | ||
964 | return hrtimer_nanosleep(tsave, rmtp, mode, clockid); | ||
965 | } | 946 | } |
966 | 947 | ||
967 | asmlinkage long | 948 | asmlinkage long |