at v2.6.29 7.5 kB view raw
1/* 2 * linux/kernel/itimer.c 3 * 4 * Copyright (C) 1992 Darren Senn 5 */ 6 7/* These are all the functions necessary to implement itimers */ 8 9#include <linux/mm.h> 10#include <linux/interrupt.h> 11#include <linux/syscalls.h> 12#include <linux/time.h> 13#include <linux/posix-timers.h> 14#include <linux/hrtimer.h> 15 16#include <asm/uaccess.h> 17 18/** 19 * itimer_get_remtime - get remaining time for the timer 20 * 21 * @timer: the timer to read 22 * 23 * Returns the delta between the expiry time and now, which can be 24 * less than zero or 1usec for an pending expired timer 25 */ 26static struct timeval itimer_get_remtime(struct hrtimer *timer) 27{ 28 ktime_t rem = hrtimer_get_remaining(timer); 29 30 /* 31 * Racy but safe: if the itimer expires after the above 32 * hrtimer_get_remtime() call but before this condition 33 * then we return 0 - which is correct. 34 */ 35 if (hrtimer_active(timer)) { 36 if (rem.tv64 <= 0) 37 rem.tv64 = NSEC_PER_USEC; 38 } else 39 rem.tv64 = 0; 40 41 return ktime_to_timeval(rem); 42} 43 44int do_getitimer(int which, struct itimerval *value) 45{ 46 struct task_struct *tsk = current; 47 cputime_t cinterval, cval; 48 49 switch (which) { 50 case ITIMER_REAL: 51 spin_lock_irq(&tsk->sighand->siglock); 52 value->it_value = itimer_get_remtime(&tsk->signal->real_timer); 53 value->it_interval = 54 ktime_to_timeval(tsk->signal->it_real_incr); 55 spin_unlock_irq(&tsk->sighand->siglock); 56 break; 57 case ITIMER_VIRTUAL: 58 spin_lock_irq(&tsk->sighand->siglock); 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; 77 case ITIMER_PROF: 78 spin_lock_irq(&tsk->sighand->siglock); 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; 97 default: 98 return(-EINVAL); 99 } 100 return 0; 101} 102 103SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value) 104{ 105 int error = -EFAULT; 106 struct itimerval get_buffer; 107 108 if (value) { 109 error = do_getitimer(which, &get_buffer); 110 if (!error && 111 copy_to_user(value, &get_buffer, sizeof(get_buffer))) 112 error = -EFAULT; 113 } 114 return error; 115} 116 117 118/* 119 * The timer is automagically restarted, when interval != 0 120 */ 121enum hrtimer_restart it_real_fn(struct hrtimer *timer) 122{ 123 struct signal_struct *sig = 124 container_of(timer, struct signal_struct, real_timer); 125 126 kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid); 127 128 return HRTIMER_NORESTART; 129} 130 131/* 132 * Returns true if the timeval is in canonical form 133 */ 134#define timeval_valid(t) \ 135 (((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC)) 136 137int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) 138{ 139 struct task_struct *tsk = current; 140 struct hrtimer *timer; 141 ktime_t expires; 142 cputime_t cval, cinterval, nval, ninterval; 143 144 /* 145 * Validate the timevals in value. 146 */ 147 if (!timeval_valid(&value->it_value) || 148 !timeval_valid(&value->it_interval)) 149 return -EINVAL; 150 151 switch (which) { 152 case ITIMER_REAL: 153again: 154 spin_lock_irq(&tsk->sighand->siglock); 155 timer = &tsk->signal->real_timer; 156 if (ovalue) { 157 ovalue->it_value = itimer_get_remtime(timer); 158 ovalue->it_interval 159 = ktime_to_timeval(tsk->signal->it_real_incr); 160 } 161 /* We are sharing ->siglock with it_real_fn() */ 162 if (hrtimer_try_to_cancel(timer) < 0) { 163 spin_unlock_irq(&tsk->sighand->siglock); 164 goto again; 165 } 166 expires = timeval_to_ktime(value->it_value); 167 if (expires.tv64 != 0) { 168 tsk->signal->it_real_incr = 169 timeval_to_ktime(value->it_interval); 170 hrtimer_start(timer, expires, HRTIMER_MODE_REL); 171 } else 172 tsk->signal->it_real_incr.tv64 = 0; 173 174 spin_unlock_irq(&tsk->sighand->siglock); 175 break; 176 case ITIMER_VIRTUAL: 177 nval = timeval_to_cputime(&value->it_value); 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; 198 case ITIMER_PROF: 199 nval = timeval_to_cputime(&value->it_value); 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; 220 default: 221 return -EINVAL; 222 } 223 return 0; 224} 225 226/** 227 * alarm_setitimer - set alarm in seconds 228 * 229 * @seconds: number of seconds until alarm 230 * 0 disables the alarm 231 * 232 * Returns the remaining time in seconds of a pending timer or 0 when 233 * the timer is not active. 234 * 235 * On 32 bit machines the seconds value is limited to (INT_MAX/2) to avoid 236 * negative timeval settings which would cause immediate expiry. 237 */ 238unsigned int alarm_setitimer(unsigned int seconds) 239{ 240 struct itimerval it_new, it_old; 241 242#if BITS_PER_LONG < 64 243 if (seconds > INT_MAX) 244 seconds = INT_MAX; 245#endif 246 it_new.it_value.tv_sec = seconds; 247 it_new.it_value.tv_usec = 0; 248 it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; 249 250 do_setitimer(ITIMER_REAL, &it_new, &it_old); 251 252 /* 253 * We can't return 0 if we have an alarm pending ... And we'd 254 * better return too much than too little anyway 255 */ 256 if ((!it_old.it_value.tv_sec && it_old.it_value.tv_usec) || 257 it_old.it_value.tv_usec >= 500000) 258 it_old.it_value.tv_sec++; 259 260 return it_old.it_value.tv_sec; 261} 262 263SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, 264 struct itimerval __user *, ovalue) 265{ 266 struct itimerval set_buffer, get_buffer; 267 int error; 268 269 if (value) { 270 if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) 271 return -EFAULT; 272 } else 273 memset((char *) &set_buffer, 0, sizeof(set_buffer)); 274 275 error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); 276 if (error || !ovalue) 277 return error; 278 279 if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) 280 return -EFAULT; 281 return 0; 282}