]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/posix-timers.c
[PATCH] n_r3964: fixed usage of HZ; removed bad include
[karo-tx-linux.git] / kernel / posix-timers.c
index 38798a2ff994e96c017010b8c2c62db578fe2002..5870efb3e2007e70ae577c76f4d71e71245914f2 100644 (file)
@@ -270,7 +270,7 @@ static void tstojiffie(struct timespec *tp, int res, u64 *jiff)
        long sec = tp->tv_sec;
        long nsec = tp->tv_nsec + res - 1;
 
-       if (nsec > NSEC_PER_SEC) {
+       if (nsec >= NSEC_PER_SEC) {
                sec++;
                nsec -= NSEC_PER_SEC;
        }
@@ -427,21 +427,23 @@ int posix_timer_event(struct k_itimer *timr,int si_private)
        timr->sigq->info.si_code = SI_TIMER;
        timr->sigq->info.si_tid = timr->it_id;
        timr->sigq->info.si_value = timr->it_sigev_value;
+
        if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
-               if (unlikely(timr->it_process->flags & PF_EXITING)) {
-                       timr->it_sigev_notify = SIGEV_SIGNAL;
-                       put_task_struct(timr->it_process);
-                       timr->it_process = timr->it_process->group_leader;
-                       goto group;
-               }
-               return send_sigqueue(timr->it_sigev_signo, timr->sigq,
-                       timr->it_process);
-       }
-       else {
-       group:
-               return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
-                       timr->it_process);
+               struct task_struct *leader;
+               int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
+                                       timr->it_process);
+
+               if (likely(ret >= 0))
+                       return ret;
+
+               timr->it_sigev_notify = SIGEV_SIGNAL;
+               leader = timr->it_process->group_leader;
+               put_task_struct(timr->it_process);
+               timr->it_process = leader;
        }
+
+       return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
+                                  timr->it_process);
 }
 EXPORT_SYMBOL_GPL(posix_timer_event);
 
@@ -1155,7 +1157,7 @@ retry_delete:
 }
 
 /*
- * This is called by __exit_signal, only when there are no more
+ * This is called by do_exit or de_thread, only when there are no more
  * references to the shared signal_struct.
  */
 void exit_itimers(struct signal_struct *sig)
@@ -1207,13 +1209,9 @@ static int do_posix_clock_monotonic_get(clockid_t clock, struct timespec *tp)
 
        do_posix_clock_monotonic_gettime_parts(tp, &wall_to_mono);
 
-       tp->tv_sec += wall_to_mono.tv_sec;
-       tp->tv_nsec += wall_to_mono.tv_nsec;
+       set_normalized_timespec(tp, tp->tv_sec + wall_to_mono.tv_sec,
+                               tp->tv_nsec + wall_to_mono.tv_nsec);
 
-       if ((tp->tv_nsec - NSEC_PER_SEC) > 0) {
-               tp->tv_nsec -= NSEC_PER_SEC;
-               tp->tv_sec++;
-       }
        return 0;
 }
 
@@ -1293,13 +1291,6 @@ sys_clock_getres(clockid_t which_clock, struct timespec __user *tp)
        return error;
 }
 
-static void nanosleep_wake_up(unsigned long __data)
-{
-       struct task_struct *p = (struct task_struct *) __data;
-
-       wake_up_process(p);
-}
-
 /*
  * The standard says that an absolute nanosleep call MUST wake up at
  * the requested time in spite of clock settings.  Here is what we do:
@@ -1440,7 +1431,6 @@ static int common_nsleep(clockid_t which_clock,
                         int flags, struct timespec *tsave)
 {
        struct timespec t, dum;
-       struct timer_list new_timer;
        DECLARE_WAITQUEUE(abs_wqueue, current);
        u64 rq_time = (u64)0;
        s64 left;
@@ -1449,10 +1439,6 @@ static int common_nsleep(clockid_t which_clock,
            &current_thread_info()->restart_block;
 
        abs_wqueue.flags = 0;
-       init_timer(&new_timer);
-       new_timer.expires = 0;
-       new_timer.data = (unsigned long) current;
-       new_timer.function = nanosleep_wake_up;
        abs = flags & TIMER_ABSTIME;
 
        if (restart_block->fn == clock_nanosleep_restart) {
@@ -1488,13 +1474,8 @@ static int common_nsleep(clockid_t which_clock,
                if (left < (s64)0)
                        break;
 
-               new_timer.expires = jiffies + left;
-               __set_current_state(TASK_INTERRUPTIBLE);
-               add_timer(&new_timer);
-
-               schedule();
+               schedule_timeout_interruptible(left);
 
-               del_timer_sync(&new_timer);
                left = rq_time - get_jiffies_64();
        } while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));