aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/itimer.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2009-07-29 06:15:26 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-03 08:48:35 -0400
commit42c4ab41a176ee784c0f28c0b29025a8fc34f05a (patch)
tree370393a0e02faa7a6a7d211205b31ceb74880359 /kernel/itimer.c
parented680c4ad478d0fee9740f7d029087f181346564 (diff)
itimers: Merge ITIMER_VIRT and ITIMER_PROF
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> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> LKML-Reference: <1248862529-6063-2-git-send-email-sgruszka@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/itimer.c')
-rw-r--r--kernel/itimer.c146
1 files changed, 68 insertions, 78 deletions
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 58762f7077ec..852c88ddd1f0 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -41,10 +41,43 @@ static struct timeval itimer_get_remtime(struct hrtimer *timer)
41 return ktime_to_timeval(rem); 41 return ktime_to_timeval(rem);
42} 42}
43 43
44static void get_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
45 struct itimerval *value)
46{
47 cputime_t cval, cinterval;
48 struct cpu_itimer *it = &tsk->signal->it[clock_id];
49
50 spin_lock_irq(&tsk->sighand->siglock);
51
52 cval = it->expires;
53 cinterval = it->incr;
54 if (!cputime_eq(cval, cputime_zero)) {
55 struct task_cputime cputime;
56 cputime_t t;
57
58 thread_group_cputimer(tsk, &cputime);
59 if (clock_id == CPUCLOCK_PROF)
60 t = cputime_add(cputime.utime, cputime.stime);
61 else
62 /* CPUCLOCK_VIRT */
63 t = cputime.utime;
64
65 if (cputime_le(cval, t))
66 /* about to fire */
67 cval = jiffies_to_cputime(1);
68 else
69 cval = cputime_sub(cval, t);
70 }
71
72 spin_unlock_irq(&tsk->sighand->siglock);
73
74 cputime_to_timeval(cval, &value->it_value);
75 cputime_to_timeval(cinterval, &value->it_interval);
76}
77
44int do_getitimer(int which, struct itimerval *value) 78int do_getitimer(int which, struct itimerval *value)
45{ 79{
46 struct task_struct *tsk = current; 80 struct task_struct *tsk = current;
47 cputime_t cinterval, cval;
48 81
49 switch (which) { 82 switch (which) {
50 case ITIMER_REAL: 83 case ITIMER_REAL:
@@ -55,44 +88,10 @@ int do_getitimer(int which, struct itimerval *value)
55 spin_unlock_irq(&tsk->sighand->siglock); 88 spin_unlock_irq(&tsk->sighand->siglock);
56 break; 89 break;
57 case ITIMER_VIRTUAL: 90 case ITIMER_VIRTUAL:
58 spin_lock_irq(&tsk->sighand->siglock); 91 get_cpu_itimer(tsk, CPUCLOCK_VIRT, value);
59 cval = tsk->signal->it_virt_expires;
60 cinterval = tsk->signal->it_virt_incr;
61 if (!cputime_eq(cval, cputime_zero)) {
62 struct task_cputime cputime;
63 cputime_t utime;
64
65 thread_group_cputimer(tsk, &cputime);
66 utime = cputime.utime;
67 if (cputime_le(cval, utime)) { /* about to fire */
68 cval = jiffies_to_cputime(1);
69 } else {
70 cval = cputime_sub(cval, utime);
71 }
72 }
73 spin_unlock_irq(&tsk->sighand->siglock);
74 cputime_to_timeval(cval, &value->it_value);
75 cputime_to_timeval(cinterval, &value->it_interval);
76 break; 92 break;
77 case ITIMER_PROF: 93 case ITIMER_PROF:
78 spin_lock_irq(&tsk->sighand->siglock); 94 get_cpu_itimer(tsk, CPUCLOCK_PROF, value);
79 cval = tsk->signal->it_prof_expires;
80 cinterval = tsk->signal->it_prof_incr;
81 if (!cputime_eq(cval, cputime_zero)) {
82 struct task_cputime times;
83 cputime_t ptime;
84
85 thread_group_cputimer(tsk, &times);
86 ptime = cputime_add(times.utime, times.stime);
87 if (cputime_le(cval, ptime)) { /* about to fire */
88 cval = jiffies_to_cputime(1);
89 } else {
90 cval = cputime_sub(cval, ptime);
91 }
92 }
93 spin_unlock_irq(&tsk->sighand->siglock);
94 cputime_to_timeval(cval, &value->it_value);
95 cputime_to_timeval(cinterval, &value->it_interval);
96 break; 95 break;
97 default: 96 default:
98 return(-EINVAL); 97 return(-EINVAL);
@@ -128,6 +127,36 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
128 return HRTIMER_NORESTART; 127 return HRTIMER_NORESTART;
129} 128}
130 129
130static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
131 struct itimerval *value, struct itimerval *ovalue)
132{
133 cputime_t cval, cinterval, nval, ninterval;
134 struct cpu_itimer *it = &tsk->signal->it[clock_id];
135
136 nval = timeval_to_cputime(&value->it_value);
137 ninterval = timeval_to_cputime(&value->it_interval);
138
139 spin_lock_irq(&tsk->sighand->siglock);
140
141 cval = it->expires;
142 cinterval = it->incr;
143 if (!cputime_eq(cval, cputime_zero) ||
144 !cputime_eq(nval, cputime_zero)) {
145 if (cputime_gt(nval, cputime_zero))
146 nval = cputime_add(nval, jiffies_to_cputime(1));
147 set_process_cpu_timer(tsk, clock_id, &nval, &cval);
148 }
149 it->expires = nval;
150 it->incr = ninterval;
151
152 spin_unlock_irq(&tsk->sighand->siglock);
153
154 if (ovalue) {
155 cputime_to_timeval(cval, &ovalue->it_value);
156 cputime_to_timeval(cinterval, &ovalue->it_interval);
157 }
158}
159
131/* 160/*
132 * Returns true if the timeval is in canonical form 161 * Returns true if the timeval is in canonical form
133 */ 162 */
@@ -139,7 +168,6 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
139 struct task_struct *tsk = current; 168 struct task_struct *tsk = current;
140 struct hrtimer *timer; 169 struct hrtimer *timer;
141 ktime_t expires; 170 ktime_t expires;
142 cputime_t cval, cinterval, nval, ninterval;
143 171
144 /* 172 /*
145 * Validate the timevals in value. 173 * Validate the timevals in value.
@@ -174,48 +202,10 @@ again:
174 spin_unlock_irq(&tsk->sighand->siglock); 202 spin_unlock_irq(&tsk->sighand->siglock);
175 break; 203 break;
176 case ITIMER_VIRTUAL: 204 case ITIMER_VIRTUAL:
177 nval = timeval_to_cputime(&value->it_value); 205 set_cpu_itimer(tsk, CPUCLOCK_VIRT, value, ovalue);
178 ninterval = timeval_to_cputime(&value->it_interval);
179 spin_lock_irq(&tsk->sighand->siglock);
180 cval = tsk->signal->it_virt_expires;
181 cinterval = tsk->signal->it_virt_incr;
182 if (!cputime_eq(cval, cputime_zero) ||
183 !cputime_eq(nval, cputime_zero)) {
184 if (cputime_gt(nval, cputime_zero))
185 nval = cputime_add(nval,
186 jiffies_to_cputime(1));
187 set_process_cpu_timer(tsk, CPUCLOCK_VIRT,
188 &nval, &cval);
189 }
190 tsk->signal->it_virt_expires = nval;
191 tsk->signal->it_virt_incr = ninterval;
192 spin_unlock_irq(&tsk->sighand->siglock);
193 if (ovalue) {
194 cputime_to_timeval(cval, &ovalue->it_value);
195 cputime_to_timeval(cinterval, &ovalue->it_interval);
196 }
197 break; 206 break;
198 case ITIMER_PROF: 207 case ITIMER_PROF:
199 nval = timeval_to_cputime(&value->it_value); 208 set_cpu_itimer(tsk, CPUCLOCK_PROF, value, ovalue);
200 ninterval = timeval_to_cputime(&value->it_interval);
201 spin_lock_irq(&tsk->sighand->siglock);
202 cval = tsk->signal->it_prof_expires;
203 cinterval = tsk->signal->it_prof_incr;
204 if (!cputime_eq(cval, cputime_zero) ||
205 !cputime_eq(nval, cputime_zero)) {
206 if (cputime_gt(nval, cputime_zero))
207 nval = cputime_add(nval,
208 jiffies_to_cputime(1));
209 set_process_cpu_timer(tsk, CPUCLOCK_PROF,
210 &nval, &cval);
211 }
212 tsk->signal->it_prof_expires = nval;
213 tsk->signal->it_prof_incr = ninterval;
214 spin_unlock_irq(&tsk->sighand->siglock);
215 if (ovalue) {
216 cputime_to_timeval(cval, &ovalue->it_value);
217 cputime_to_timeval(cinterval, &ovalue->it_interval);
218 }
219 break; 209 break;
220 default: 210 default:
221 return -EINVAL; 211 return -EINVAL;