diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
| -rw-r--r-- | kernel/posix-cpu-timers.c | 20 | 
1 files changed, 17 insertions, 3 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 9b2d5e4dc8c..b60d644ea4b 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -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);  |