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 |
