|
@@ -1070,6 +1070,8 @@ static void stop_process_timers(struct task_struct *tsk)
|
|
|
spin_unlock_irqrestore(&cputimer->lock, flags);
|
|
|
}
|
|
|
|
|
|
+static u32 onecputick;
|
|
|
+
|
|
|
static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
|
|
|
cputime_t *expires, cputime_t cur_time, int signo)
|
|
|
{
|
|
@@ -1077,9 +1079,16 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
|
|
|
return;
|
|
|
|
|
|
if (cputime_ge(cur_time, it->expires)) {
|
|
|
- it->expires = it->incr;
|
|
|
- if (!cputime_eq(it->expires, cputime_zero))
|
|
|
- it->expires = cputime_add(it->expires, cur_time);
|
|
|
+ if (!cputime_eq(it->incr, cputime_zero)) {
|
|
|
+ it->expires = cputime_add(it->expires, it->incr);
|
|
|
+ it->error += it->incr_error;
|
|
|
+ if (it->error >= onecputick) {
|
|
|
+ it->expires = cputime_sub(it->expires,
|
|
|
+ jiffies_to_cputime(1));
|
|
|
+ it->error -= onecputick;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ it->expires = cputime_zero;
|
|
|
|
|
|
__group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
|
|
|
}
|
|
@@ -1696,10 +1705,15 @@ static __init int init_posix_cpu_timers(void)
|
|
|
.nsleep = thread_cpu_nsleep,
|
|
|
.nsleep_restart = thread_cpu_nsleep_restart,
|
|
|
};
|
|
|
+ struct timespec ts;
|
|
|
|
|
|
register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process);
|
|
|
register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread);
|
|
|
|
|
|
+ cputime_to_timespec(jiffies_to_cputime(1), &ts);
|
|
|
+ onecputick = ts.tv_nsec;
|
|
|
+ WARN_ON(ts.tv_sec != 0);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
__initcall(init_posix_cpu_timers);
|