mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] itimers: merge ITIMER_VIRT and ITIMER_PROF common code
@ 2009-04-02 12:11 Stanislaw Gruszka
  2009-04-02 16:45 ` Ingo Molnar
  0 siblings, 1 reply; 2+ messages in thread
From: Stanislaw Gruszka @ 2009-04-02 12:11 UTC (permalink / raw)
  To: linux-kernel

Both cpu itimers have same data flow in the few places, this patch make
unification of code related with VIRT and PROF itimers.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 include/linux/sched.h     |    6 +-
 kernel/fork.c             |    8 +-
 kernel/itimer.c           |  136 +++++++++++++++++++--------------------------
 kernel/posix-cpu-timers.c |   81 ++++++++++++++-------------
 4 files changed, 107 insertions(+), 124 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 29df637..b4c19c2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -440,6 +440,8 @@ struct pacct_struct {
 	unsigned long		ac_minflt, ac_majflt;
 };
 
+enum itimer_number {IT_VIRT = 0, IT_PROF = 1};
+
 /**
  * struct task_cputime - collected CPU time counts
  * @utime:		time spent in user mode, in &cputime_t units
@@ -526,8 +528,8 @@ struct signal_struct {
 	ktime_t it_real_incr;
 
 	/* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */
-	cputime_t it_prof_expires, it_virt_expires;
-	cputime_t it_prof_incr, it_virt_incr;
+	cputime_t it_expires[2];
+	cputime_t it_incr[2];
 
 	/*
 	 * Thread group totals for process CPU timers.
diff --git a/kernel/fork.c b/kernel/fork.c
index 47c1584..6c7044a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -803,10 +803,10 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
 	thread_group_cputime_init(sig);
 
 	/* Expiration times and increments. */
-	sig->it_virt_expires = cputime_zero;
-	sig->it_virt_incr = cputime_zero;
-	sig->it_prof_expires = cputime_zero;
-	sig->it_prof_incr = cputime_zero;
+	sig->it_expires[IT_VIRT] = cputime_zero;
+	sig->it_expires[IT_PROF] = cputime_zero;
+	sig->it_incr[IT_VIRT] = cputime_zero;
+	sig->it_incr[IT_PROF] = cputime_zero;
 
 	/* Cached expiration times. */
 	sig->cputime_expires.prof_exp = cputime_zero;
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 58762f7..ec64fea 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -41,10 +41,34 @@ static struct timeval itimer_get_remtime(struct hrtimer *timer)
 	return ktime_to_timeval(rem);
 }
 
+static void get_cpu_itimer(struct task_struct *tsk, enum itimer_number i,
+			   struct itimerval *value)
+{
+	cputime_t cval, cinterval;
+
+	spin_lock_irq(&tsk->sighand->siglock);
+	cval = tsk->signal->it_expires[i];
+	cinterval = tsk->signal->it_incr[i];
+	if (!cputime_eq(cval, cputime_zero)) {
+		struct task_cputime cputime;
+		cputime_t utime;
+
+		thread_group_cputimer(tsk, &cputime);
+		utime = cputime.utime;
+		if (cputime_le(cval, utime)) { /* about to fire */
+			cval = jiffies_to_cputime(1);
+		} else {
+			cval = cputime_sub(cval, utime);
+		}
+	}
+	spin_unlock_irq(&tsk->sighand->siglock);
+	cputime_to_timeval(cval, &value->it_value);
+	cputime_to_timeval(cinterval, &value->it_interval);
+}
+
 int do_getitimer(int which, struct itimerval *value)
 {
 	struct task_struct *tsk = current;
-	cputime_t cinterval, cval;
 
 	switch (which) {
 	case ITIMER_REAL:
@@ -55,44 +79,10 @@ int do_getitimer(int which, struct itimerval *value)
 		spin_unlock_irq(&tsk->sighand->siglock);
 		break;
 	case ITIMER_VIRTUAL:
-		spin_lock_irq(&tsk->sighand->siglock);
-		cval = tsk->signal->it_virt_expires;
-		cinterval = tsk->signal->it_virt_incr;
-		if (!cputime_eq(cval, cputime_zero)) {
-			struct task_cputime cputime;
-			cputime_t utime;
-
-			thread_group_cputimer(tsk, &cputime);
-			utime = cputime.utime;
-			if (cputime_le(cval, utime)) { /* about to fire */
-				cval = jiffies_to_cputime(1);
-			} else {
-				cval = cputime_sub(cval, utime);
-			}
-		}
-		spin_unlock_irq(&tsk->sighand->siglock);
-		cputime_to_timeval(cval, &value->it_value);
-		cputime_to_timeval(cinterval, &value->it_interval);
+		get_cpu_itimer(tsk, IT_VIRT, value);
 		break;
 	case ITIMER_PROF:
-		spin_lock_irq(&tsk->sighand->siglock);
-		cval = tsk->signal->it_prof_expires;
-		cinterval = tsk->signal->it_prof_incr;
-		if (!cputime_eq(cval, cputime_zero)) {
-			struct task_cputime times;
-			cputime_t ptime;
-
-			thread_group_cputimer(tsk, &times);
-			ptime = cputime_add(times.utime, times.stime);
-			if (cputime_le(cval, ptime)) { /* about to fire */
-				cval = jiffies_to_cputime(1);
-			} else {
-				cval = cputime_sub(cval, ptime);
-			}
-		}
-		spin_unlock_irq(&tsk->sighand->siglock);
-		cputime_to_timeval(cval, &value->it_value);
-		cputime_to_timeval(cinterval, &value->it_interval);
+		get_cpu_itimer(tsk, IT_PROF, value);
 		break;
 	default:
 		return(-EINVAL);
@@ -128,6 +118,35 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
 	return HRTIMER_NORESTART;
 }
 
+static void set_cpu_itimer(struct task_struct *tsk, enum itimer_number i,
+			   struct itimerval *value, struct itimerval *ovalue)
+{
+	cputime_t cval, cinterval, nval, ninterval;
+
+	nval = timeval_to_cputime(&value->it_value);
+	ninterval = timeval_to_cputime(&value->it_interval);
+
+	spin_lock_irq(&tsk->sighand->siglock);
+
+	cval = tsk->signal->it_expires[i];
+	cinterval = tsk->signal->it_incr[i];
+	if (!cputime_eq(cval, cputime_zero) ||
+	    !cputime_eq(nval, cputime_zero)) {
+		if (cputime_gt(nval, cputime_zero))
+			nval = cputime_add(nval, jiffies_to_cputime(1));
+		set_process_cpu_timer(tsk, i, &nval, &cval);
+	}
+	tsk->signal->it_expires[i] = nval;
+	tsk->signal->it_incr[i] = ninterval;
+
+	spin_unlock_irq(&tsk->sighand->siglock);
+
+	if (ovalue) {
+		cputime_to_timeval(cval, &ovalue->it_value);
+		cputime_to_timeval(cinterval, &ovalue->it_interval);
+	}
+}
+
 /*
  * Returns true if the timeval is in canonical form
  */
@@ -139,7 +158,6 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 	struct task_struct *tsk = current;
 	struct hrtimer *timer;
 	ktime_t expires;
-	cputime_t cval, cinterval, nval, ninterval;
 
 	/*
 	 * Validate the timevals in value.
@@ -174,48 +192,10 @@ again:
 		spin_unlock_irq(&tsk->sighand->siglock);
 		break;
 	case ITIMER_VIRTUAL:
-		nval = timeval_to_cputime(&value->it_value);
-		ninterval = timeval_to_cputime(&value->it_interval);
-		spin_lock_irq(&tsk->sighand->siglock);
-		cval = tsk->signal->it_virt_expires;
-		cinterval = tsk->signal->it_virt_incr;
-		if (!cputime_eq(cval, cputime_zero) ||
-		    !cputime_eq(nval, cputime_zero)) {
-			if (cputime_gt(nval, cputime_zero))
-				nval = cputime_add(nval,
-						   jiffies_to_cputime(1));
-			set_process_cpu_timer(tsk, CPUCLOCK_VIRT,
-					      &nval, &cval);
-		}
-		tsk->signal->it_virt_expires = nval;
-		tsk->signal->it_virt_incr = ninterval;
-		spin_unlock_irq(&tsk->sighand->siglock);
-		if (ovalue) {
-			cputime_to_timeval(cval, &ovalue->it_value);
-			cputime_to_timeval(cinterval, &ovalue->it_interval);
-		}
+		set_cpu_itimer(tsk, IT_VIRT, value, ovalue);
 		break;
 	case ITIMER_PROF:
-		nval = timeval_to_cputime(&value->it_value);
-		ninterval = timeval_to_cputime(&value->it_interval);
-		spin_lock_irq(&tsk->sighand->siglock);
-		cval = tsk->signal->it_prof_expires;
-		cinterval = tsk->signal->it_prof_incr;
-		if (!cputime_eq(cval, cputime_zero) ||
-		    !cputime_eq(nval, cputime_zero)) {
-			if (cputime_gt(nval, cputime_zero))
-				nval = cputime_add(nval,
-						   jiffies_to_cputime(1));
-			set_process_cpu_timer(tsk, CPUCLOCK_PROF,
-					      &nval, &cval);
-		}
-		tsk->signal->it_prof_expires = nval;
-		tsk->signal->it_prof_incr = ninterval;
-		spin_unlock_irq(&tsk->sighand->siglock);
-		if (ovalue) {
-			cputime_to_timeval(cval, &ovalue->it_value);
-			cputime_to_timeval(cinterval, &ovalue->it_interval);
-		}
+		set_cpu_itimer(tsk, IT_PROF, value, ovalue);
 		break;
 	default:
 		return -EINVAL;
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 8e5d9a6..76e125c 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -17,8 +17,8 @@ void update_rlimit_cpu(unsigned long rlim_new)
 	cputime_t cputime;
 
 	cputime = secs_to_cputime(rlim_new);
-	if (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
-	    cputime_lt(current->signal->it_prof_expires, cputime)) {
+	if (cputime_eq(current->signal->it_expires[IT_PROF], cputime_zero) ||
+	    cputime_lt(current->signal->it_expires[IT_PROF], cputime)) {
 		spin_lock_irq(&current->sighand->siglock);
 		set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
 		spin_unlock_irq(&current->sighand->siglock);
@@ -619,18 +619,18 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
 			default:
 				BUG();
 			case CPUCLOCK_VIRT:
-				if (!cputime_eq(p->signal->it_virt_expires,
+				if (!cputime_eq(p->signal->it_expires[IT_VIRT],
 						cputime_zero) &&
-				    cputime_lt(p->signal->it_virt_expires,
+				    cputime_lt(p->signal->it_expires[IT_VIRT],
 					       timer->it.cpu.expires.cpu))
 					break;
 				p->signal->cputime_expires.virt_exp =
 					timer->it.cpu.expires.cpu;
 				break;
 			case CPUCLOCK_PROF:
-				if (!cputime_eq(p->signal->it_prof_expires,
+				if (!cputime_eq(p->signal->it_expires[IT_PROF],
 						cputime_zero) &&
-				    cputime_lt(p->signal->it_prof_expires,
+				    cputime_lt(p->signal->it_expires[IT_PROF],
 					       timer->it.cpu.expires.cpu))
 					break;
 				i = p->signal->rlim[RLIMIT_CPU].rlim_cur;
@@ -1069,6 +1069,36 @@ static void stop_process_timers(struct task_struct *tsk)
 	spin_unlock_irqrestore(&cputimer->lock, flags);
 }
 
+static cputime_t check_cpu_itimer(struct task_struct *tsk, enum itimer_number i,
+				  cputime_t expires, cputime_t cur_time)
+{
+	struct signal_struct *const sig = tsk->signal;
+
+	if (cputime_eq(sig->it_expires[i], cputime_zero))
+		return expires;
+
+	if (cputime_ge(cur_time, sig->it_expires[i])) {
+		int signo;
+
+		sig->it_expires[i] = sig->it_incr[i];
+		if (!cputime_eq(sig->it_expires[i], cputime_zero)) {
+			sig->it_expires[i] = cputime_add(sig->it_expires[i],
+							 cur_time);
+		}
+
+		signo = (i == IT_VIRT) ? SIGVTALRM : SIGPROF;
+		__group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
+	}
+
+	if (!cputime_eq(sig->it_expires[i], cputime_zero) &&
+	    (cputime_eq(expires, cputime_zero) ||
+	     cputime_lt(sig->it_expires[i], expires))) {
+		expires = sig->it_expires[i];
+	}
+
+	return expires;
+}
+
 /*
  * Check for any per-thread CPU timers that have fired and move them
  * off the tsk->*_timers list onto the firing list.  Per-thread timers
@@ -1088,10 +1118,10 @@ static void check_process_timers(struct task_struct *tsk,
 	 * Don't sample the current process CPU clocks if there are no timers.
 	 */
 	if (list_empty(&timers[CPUCLOCK_PROF]) &&
-	    cputime_eq(sig->it_prof_expires, cputime_zero) &&
+	    cputime_eq(sig->it_expires[IT_PROF], cputime_zero) &&
 	    sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY &&
 	    list_empty(&timers[CPUCLOCK_VIRT]) &&
-	    cputime_eq(sig->it_virt_expires, cputime_zero) &&
+	    cputime_eq(sig->it_expires[IT_VIRT], cputime_zero) &&
 	    list_empty(&timers[CPUCLOCK_SCHED])) {
 		stop_process_timers(tsk);
 		return;
@@ -1151,38 +1181,9 @@ static void check_process_timers(struct task_struct *tsk,
 	/*
 	 * Check for the special case process timers.
 	 */
-	if (!cputime_eq(sig->it_prof_expires, cputime_zero)) {
-		if (cputime_ge(ptime, sig->it_prof_expires)) {
-			/* ITIMER_PROF fires and reloads.  */
-			sig->it_prof_expires = sig->it_prof_incr;
-			if (!cputime_eq(sig->it_prof_expires, cputime_zero)) {
-				sig->it_prof_expires = cputime_add(
-					sig->it_prof_expires, ptime);
-			}
-			__group_send_sig_info(SIGPROF, SEND_SIG_PRIV, tsk);
-		}
-		if (!cputime_eq(sig->it_prof_expires, cputime_zero) &&
-		    (cputime_eq(prof_expires, cputime_zero) ||
-		     cputime_lt(sig->it_prof_expires, prof_expires))) {
-			prof_expires = sig->it_prof_expires;
-		}
-	}
-	if (!cputime_eq(sig->it_virt_expires, cputime_zero)) {
-		if (cputime_ge(utime, sig->it_virt_expires)) {
-			/* ITIMER_VIRTUAL fires and reloads.  */
-			sig->it_virt_expires = sig->it_virt_incr;
-			if (!cputime_eq(sig->it_virt_expires, cputime_zero)) {
-				sig->it_virt_expires = cputime_add(
-					sig->it_virt_expires, utime);
-			}
-			__group_send_sig_info(SIGVTALRM, SEND_SIG_PRIV, tsk);
-		}
-		if (!cputime_eq(sig->it_virt_expires, cputime_zero) &&
-		    (cputime_eq(virt_expires, cputime_zero) ||
-		     cputime_lt(sig->it_virt_expires, virt_expires))) {
-			virt_expires = sig->it_virt_expires;
-		}
-	}
+	prof_expires = check_cpu_itimer(tsk, IT_PROF, prof_expires, ptime);
+	virt_expires = check_cpu_itimer(tsk, IT_VIRT, virt_expires, utime);
+
 	if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
 		unsigned long psecs = cputime_to_secs(ptime);
 		cputime_t x;
-- 
1.6.0.6


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 1/2] itimers: merge ITIMER_VIRT and ITIMER_PROF common code
  2009-04-02 12:11 [PATCH 1/2] itimers: merge ITIMER_VIRT and ITIMER_PROF common code Stanislaw Gruszka
@ 2009-04-02 16:45 ` Ingo Molnar
  0 siblings, 0 replies; 2+ messages in thread
From: Ingo Molnar @ 2009-04-02 16:45 UTC (permalink / raw)
  To: Stanislaw Gruszka, Thomas Gleixner, Oleg Nesterov; +Cc: linux-kernel


(added more Cc:s)

* Stanislaw Gruszka <sgruszka@redhat.com> wrote:

> Both cpu itimers have same data flow in the few places, this patch make
> unification of code related with VIRT and PROF itimers.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  include/linux/sched.h     |    6 +-
>  kernel/fork.c             |    8 +-
>  kernel/itimer.c           |  136 +++++++++++++++++++--------------------------
>  kernel/posix-cpu-timers.c |   81 ++++++++++++++-------------
>  4 files changed, 107 insertions(+), 124 deletions(-)
> 
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 29df637..b4c19c2 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -440,6 +440,8 @@ struct pacct_struct {
>  	unsigned long		ac_minflt, ac_majflt;
>  };
>  
> +enum itimer_number {IT_VIRT = 0, IT_PROF = 1};
> +
>  /**
>   * struct task_cputime - collected CPU time counts
>   * @utime:		time spent in user mode, in &cputime_t units
> @@ -526,8 +528,8 @@ struct signal_struct {
>  	ktime_t it_real_incr;
>  
>  	/* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */
> -	cputime_t it_prof_expires, it_virt_expires;
> -	cputime_t it_prof_incr, it_virt_incr;
> +	cputime_t it_expires[2];
> +	cputime_t it_incr[2];
>  
>  	/*
>  	 * Thread group totals for process CPU timers.
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 47c1584..6c7044a 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -803,10 +803,10 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
>  	thread_group_cputime_init(sig);
>  
>  	/* Expiration times and increments. */
> -	sig->it_virt_expires = cputime_zero;
> -	sig->it_virt_incr = cputime_zero;
> -	sig->it_prof_expires = cputime_zero;
> -	sig->it_prof_incr = cputime_zero;
> +	sig->it_expires[IT_VIRT] = cputime_zero;
> +	sig->it_expires[IT_PROF] = cputime_zero;
> +	sig->it_incr[IT_VIRT] = cputime_zero;
> +	sig->it_incr[IT_PROF] = cputime_zero;
>  
>  	/* Cached expiration times. */
>  	sig->cputime_expires.prof_exp = cputime_zero;
> diff --git a/kernel/itimer.c b/kernel/itimer.c
> index 58762f7..ec64fea 100644
> --- a/kernel/itimer.c
> +++ b/kernel/itimer.c
> @@ -41,10 +41,34 @@ static struct timeval itimer_get_remtime(struct hrtimer *timer)
>  	return ktime_to_timeval(rem);
>  }
>  
> +static void get_cpu_itimer(struct task_struct *tsk, enum itimer_number i,
> +			   struct itimerval *value)
> +{
> +	cputime_t cval, cinterval;
> +
> +	spin_lock_irq(&tsk->sighand->siglock);
> +	cval = tsk->signal->it_expires[i];
> +	cinterval = tsk->signal->it_incr[i];
> +	if (!cputime_eq(cval, cputime_zero)) {
> +		struct task_cputime cputime;
> +		cputime_t utime;
> +
> +		thread_group_cputimer(tsk, &cputime);
> +		utime = cputime.utime;
> +		if (cputime_le(cval, utime)) { /* about to fire */
> +			cval = jiffies_to_cputime(1);
> +		} else {
> +			cval = cputime_sub(cval, utime);
> +		}
> +	}
> +	spin_unlock_irq(&tsk->sighand->siglock);
> +	cputime_to_timeval(cval, &value->it_value);
> +	cputime_to_timeval(cinterval, &value->it_interval);
> +}
> +
>  int do_getitimer(int which, struct itimerval *value)
>  {
>  	struct task_struct *tsk = current;
> -	cputime_t cinterval, cval;
>  
>  	switch (which) {
>  	case ITIMER_REAL:
> @@ -55,44 +79,10 @@ int do_getitimer(int which, struct itimerval *value)
>  		spin_unlock_irq(&tsk->sighand->siglock);
>  		break;
>  	case ITIMER_VIRTUAL:
> -		spin_lock_irq(&tsk->sighand->siglock);
> -		cval = tsk->signal->it_virt_expires;
> -		cinterval = tsk->signal->it_virt_incr;
> -		if (!cputime_eq(cval, cputime_zero)) {
> -			struct task_cputime cputime;
> -			cputime_t utime;
> -
> -			thread_group_cputimer(tsk, &cputime);
> -			utime = cputime.utime;
> -			if (cputime_le(cval, utime)) { /* about to fire */
> -				cval = jiffies_to_cputime(1);
> -			} else {
> -				cval = cputime_sub(cval, utime);
> -			}
> -		}
> -		spin_unlock_irq(&tsk->sighand->siglock);
> -		cputime_to_timeval(cval, &value->it_value);
> -		cputime_to_timeval(cinterval, &value->it_interval);
> +		get_cpu_itimer(tsk, IT_VIRT, value);
>  		break;
>  	case ITIMER_PROF:
> -		spin_lock_irq(&tsk->sighand->siglock);
> -		cval = tsk->signal->it_prof_expires;
> -		cinterval = tsk->signal->it_prof_incr;
> -		if (!cputime_eq(cval, cputime_zero)) {
> -			struct task_cputime times;
> -			cputime_t ptime;
> -
> -			thread_group_cputimer(tsk, &times);
> -			ptime = cputime_add(times.utime, times.stime);
> -			if (cputime_le(cval, ptime)) { /* about to fire */
> -				cval = jiffies_to_cputime(1);
> -			} else {
> -				cval = cputime_sub(cval, ptime);
> -			}
> -		}
> -		spin_unlock_irq(&tsk->sighand->siglock);
> -		cputime_to_timeval(cval, &value->it_value);
> -		cputime_to_timeval(cinterval, &value->it_interval);
> +		get_cpu_itimer(tsk, IT_PROF, value);
>  		break;
>  	default:
>  		return(-EINVAL);
> @@ -128,6 +118,35 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
>  	return HRTIMER_NORESTART;
>  }
>  
> +static void set_cpu_itimer(struct task_struct *tsk, enum itimer_number i,
> +			   struct itimerval *value, struct itimerval *ovalue)
> +{
> +	cputime_t cval, cinterval, nval, ninterval;
> +
> +	nval = timeval_to_cputime(&value->it_value);
> +	ninterval = timeval_to_cputime(&value->it_interval);
> +
> +	spin_lock_irq(&tsk->sighand->siglock);
> +
> +	cval = tsk->signal->it_expires[i];
> +	cinterval = tsk->signal->it_incr[i];
> +	if (!cputime_eq(cval, cputime_zero) ||
> +	    !cputime_eq(nval, cputime_zero)) {
> +		if (cputime_gt(nval, cputime_zero))
> +			nval = cputime_add(nval, jiffies_to_cputime(1));
> +		set_process_cpu_timer(tsk, i, &nval, &cval);
> +	}
> +	tsk->signal->it_expires[i] = nval;
> +	tsk->signal->it_incr[i] = ninterval;
> +
> +	spin_unlock_irq(&tsk->sighand->siglock);
> +
> +	if (ovalue) {
> +		cputime_to_timeval(cval, &ovalue->it_value);
> +		cputime_to_timeval(cinterval, &ovalue->it_interval);
> +	}
> +}
> +
>  /*
>   * Returns true if the timeval is in canonical form
>   */
> @@ -139,7 +158,6 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
>  	struct task_struct *tsk = current;
>  	struct hrtimer *timer;
>  	ktime_t expires;
> -	cputime_t cval, cinterval, nval, ninterval;
>  
>  	/*
>  	 * Validate the timevals in value.
> @@ -174,48 +192,10 @@ again:
>  		spin_unlock_irq(&tsk->sighand->siglock);
>  		break;
>  	case ITIMER_VIRTUAL:
> -		nval = timeval_to_cputime(&value->it_value);
> -		ninterval = timeval_to_cputime(&value->it_interval);
> -		spin_lock_irq(&tsk->sighand->siglock);
> -		cval = tsk->signal->it_virt_expires;
> -		cinterval = tsk->signal->it_virt_incr;
> -		if (!cputime_eq(cval, cputime_zero) ||
> -		    !cputime_eq(nval, cputime_zero)) {
> -			if (cputime_gt(nval, cputime_zero))
> -				nval = cputime_add(nval,
> -						   jiffies_to_cputime(1));
> -			set_process_cpu_timer(tsk, CPUCLOCK_VIRT,
> -					      &nval, &cval);
> -		}
> -		tsk->signal->it_virt_expires = nval;
> -		tsk->signal->it_virt_incr = ninterval;
> -		spin_unlock_irq(&tsk->sighand->siglock);
> -		if (ovalue) {
> -			cputime_to_timeval(cval, &ovalue->it_value);
> -			cputime_to_timeval(cinterval, &ovalue->it_interval);
> -		}
> +		set_cpu_itimer(tsk, IT_VIRT, value, ovalue);
>  		break;
>  	case ITIMER_PROF:
> -		nval = timeval_to_cputime(&value->it_value);
> -		ninterval = timeval_to_cputime(&value->it_interval);
> -		spin_lock_irq(&tsk->sighand->siglock);
> -		cval = tsk->signal->it_prof_expires;
> -		cinterval = tsk->signal->it_prof_incr;
> -		if (!cputime_eq(cval, cputime_zero) ||
> -		    !cputime_eq(nval, cputime_zero)) {
> -			if (cputime_gt(nval, cputime_zero))
> -				nval = cputime_add(nval,
> -						   jiffies_to_cputime(1));
> -			set_process_cpu_timer(tsk, CPUCLOCK_PROF,
> -					      &nval, &cval);
> -		}
> -		tsk->signal->it_prof_expires = nval;
> -		tsk->signal->it_prof_incr = ninterval;
> -		spin_unlock_irq(&tsk->sighand->siglock);
> -		if (ovalue) {
> -			cputime_to_timeval(cval, &ovalue->it_value);
> -			cputime_to_timeval(cinterval, &ovalue->it_interval);
> -		}
> +		set_cpu_itimer(tsk, IT_PROF, value, ovalue);
>  		break;
>  	default:
>  		return -EINVAL;
> diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
> index 8e5d9a6..76e125c 100644
> --- a/kernel/posix-cpu-timers.c
> +++ b/kernel/posix-cpu-timers.c
> @@ -17,8 +17,8 @@ void update_rlimit_cpu(unsigned long rlim_new)
>  	cputime_t cputime;
>  
>  	cputime = secs_to_cputime(rlim_new);
> -	if (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
> -	    cputime_lt(current->signal->it_prof_expires, cputime)) {
> +	if (cputime_eq(current->signal->it_expires[IT_PROF], cputime_zero) ||
> +	    cputime_lt(current->signal->it_expires[IT_PROF], cputime)) {
>  		spin_lock_irq(&current->sighand->siglock);
>  		set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
>  		spin_unlock_irq(&current->sighand->siglock);
> @@ -619,18 +619,18 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
>  			default:
>  				BUG();
>  			case CPUCLOCK_VIRT:
> -				if (!cputime_eq(p->signal->it_virt_expires,
> +				if (!cputime_eq(p->signal->it_expires[IT_VIRT],
>  						cputime_zero) &&
> -				    cputime_lt(p->signal->it_virt_expires,
> +				    cputime_lt(p->signal->it_expires[IT_VIRT],
>  					       timer->it.cpu.expires.cpu))
>  					break;
>  				p->signal->cputime_expires.virt_exp =
>  					timer->it.cpu.expires.cpu;
>  				break;
>  			case CPUCLOCK_PROF:
> -				if (!cputime_eq(p->signal->it_prof_expires,
> +				if (!cputime_eq(p->signal->it_expires[IT_PROF],
>  						cputime_zero) &&
> -				    cputime_lt(p->signal->it_prof_expires,
> +				    cputime_lt(p->signal->it_expires[IT_PROF],
>  					       timer->it.cpu.expires.cpu))
>  					break;
>  				i = p->signal->rlim[RLIMIT_CPU].rlim_cur;
> @@ -1069,6 +1069,36 @@ static void stop_process_timers(struct task_struct *tsk)
>  	spin_unlock_irqrestore(&cputimer->lock, flags);
>  }
>  
> +static cputime_t check_cpu_itimer(struct task_struct *tsk, enum itimer_number i,
> +				  cputime_t expires, cputime_t cur_time)
> +{
> +	struct signal_struct *const sig = tsk->signal;
> +
> +	if (cputime_eq(sig->it_expires[i], cputime_zero))
> +		return expires;
> +
> +	if (cputime_ge(cur_time, sig->it_expires[i])) {
> +		int signo;
> +
> +		sig->it_expires[i] = sig->it_incr[i];
> +		if (!cputime_eq(sig->it_expires[i], cputime_zero)) {
> +			sig->it_expires[i] = cputime_add(sig->it_expires[i],
> +							 cur_time);
> +		}
> +
> +		signo = (i == IT_VIRT) ? SIGVTALRM : SIGPROF;
> +		__group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
> +	}
> +
> +	if (!cputime_eq(sig->it_expires[i], cputime_zero) &&
> +	    (cputime_eq(expires, cputime_zero) ||
> +	     cputime_lt(sig->it_expires[i], expires))) {
> +		expires = sig->it_expires[i];
> +	}
> +
> +	return expires;
> +}
> +
>  /*
>   * Check for any per-thread CPU timers that have fired and move them
>   * off the tsk->*_timers list onto the firing list.  Per-thread timers
> @@ -1088,10 +1118,10 @@ static void check_process_timers(struct task_struct *tsk,
>  	 * Don't sample the current process CPU clocks if there are no timers.
>  	 */
>  	if (list_empty(&timers[CPUCLOCK_PROF]) &&
> -	    cputime_eq(sig->it_prof_expires, cputime_zero) &&
> +	    cputime_eq(sig->it_expires[IT_PROF], cputime_zero) &&
>  	    sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY &&
>  	    list_empty(&timers[CPUCLOCK_VIRT]) &&
> -	    cputime_eq(sig->it_virt_expires, cputime_zero) &&
> +	    cputime_eq(sig->it_expires[IT_VIRT], cputime_zero) &&
>  	    list_empty(&timers[CPUCLOCK_SCHED])) {
>  		stop_process_timers(tsk);
>  		return;
> @@ -1151,38 +1181,9 @@ static void check_process_timers(struct task_struct *tsk,
>  	/*
>  	 * Check for the special case process timers.
>  	 */
> -	if (!cputime_eq(sig->it_prof_expires, cputime_zero)) {
> -		if (cputime_ge(ptime, sig->it_prof_expires)) {
> -			/* ITIMER_PROF fires and reloads.  */
> -			sig->it_prof_expires = sig->it_prof_incr;
> -			if (!cputime_eq(sig->it_prof_expires, cputime_zero)) {
> -				sig->it_prof_expires = cputime_add(
> -					sig->it_prof_expires, ptime);
> -			}
> -			__group_send_sig_info(SIGPROF, SEND_SIG_PRIV, tsk);
> -		}
> -		if (!cputime_eq(sig->it_prof_expires, cputime_zero) &&
> -		    (cputime_eq(prof_expires, cputime_zero) ||
> -		     cputime_lt(sig->it_prof_expires, prof_expires))) {
> -			prof_expires = sig->it_prof_expires;
> -		}
> -	}
> -	if (!cputime_eq(sig->it_virt_expires, cputime_zero)) {
> -		if (cputime_ge(utime, sig->it_virt_expires)) {
> -			/* ITIMER_VIRTUAL fires and reloads.  */
> -			sig->it_virt_expires = sig->it_virt_incr;
> -			if (!cputime_eq(sig->it_virt_expires, cputime_zero)) {
> -				sig->it_virt_expires = cputime_add(
> -					sig->it_virt_expires, utime);
> -			}
> -			__group_send_sig_info(SIGVTALRM, SEND_SIG_PRIV, tsk);
> -		}
> -		if (!cputime_eq(sig->it_virt_expires, cputime_zero) &&
> -		    (cputime_eq(virt_expires, cputime_zero) ||
> -		     cputime_lt(sig->it_virt_expires, virt_expires))) {
> -			virt_expires = sig->it_virt_expires;
> -		}
> -	}
> +	prof_expires = check_cpu_itimer(tsk, IT_PROF, prof_expires, ptime);
> +	virt_expires = check_cpu_itimer(tsk, IT_VIRT, virt_expires, utime);
> +
>  	if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
>  		unsigned long psecs = cputime_to_secs(ptime);
>  		cputime_t x;
> -- 
> 1.6.0.6
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-04-02 16:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-02 12:11 [PATCH 1/2] itimers: merge ITIMER_VIRT and ITIMER_PROF common code Stanislaw Gruszka
2009-04-02 16:45 ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®