2 * linux/kernel/itimer.c
4 * Copyright (C) 1992 Darren Senn
7 /* These are all the functions necessary to implement itimers */
10 #include <linux/smp_lock.h>
11 #include <linux/interrupt.h>
13 #include <asm/uaccess.h>
15 int do_getitimer(int which
, struct itimerval
*value
)
17 register unsigned long val
, interval
;
21 interval
= current
->it_real_incr
;
24 * FIXME! This needs to be atomic, in case the kernel timer happens!
26 if (timer_pending(¤t
->real_timer
)) {
27 val
= current
->real_timer
.expires
- jiffies
;
29 /* look out for negative/zero itimer.. */
35 val
= current
->it_virt_value
;
36 interval
= current
->it_virt_incr
;
39 val
= current
->it_prof_value
;
40 interval
= current
->it_prof_incr
;
45 jiffies_to_timeval(val
, &value
->it_value
);
46 jiffies_to_timeval(interval
, &value
->it_interval
);
50 /* SMP: Only we modify our itimer values. */
51 asmlinkage
long sys_getitimer(int which
, struct itimerval __user
*value
)
54 struct itimerval get_buffer
;
57 error
= do_getitimer(which
, &get_buffer
);
59 copy_to_user(value
, &get_buffer
, sizeof(get_buffer
)))
65 void it_real_fn(unsigned long __data
)
67 struct task_struct
* p
= (struct task_struct
*) __data
;
68 unsigned long interval
;
70 send_group_sig_info(SIGALRM
, SEND_SIG_PRIV
, p
);
71 interval
= p
->it_real_incr
;
73 if (interval
> (unsigned long) LONG_MAX
)
75 p
->real_timer
.expires
= jiffies
+ interval
;
76 add_timer(&p
->real_timer
);
80 int do_setitimer(int which
, struct itimerval
*value
, struct itimerval
*ovalue
)
82 register unsigned long i
, j
;
85 i
= timeval_to_jiffies(&value
->it_interval
);
86 j
= timeval_to_jiffies(&value
->it_value
);
87 if (ovalue
&& (k
= do_getitimer(which
, ovalue
)) < 0)
91 del_timer_sync(¤t
->real_timer
);
92 current
->it_real_value
= j
;
93 current
->it_real_incr
= i
;
96 if (j
> (unsigned long) LONG_MAX
)
99 current
->real_timer
.expires
= i
;
100 add_timer(¤t
->real_timer
);
105 current
->it_virt_value
= j
;
106 current
->it_virt_incr
= i
;
111 current
->it_prof_value
= j
;
112 current
->it_prof_incr
= i
;
120 /* SMP: Again, only we play with our itimers, and signals are SMP safe
121 * now so that is not an issue at all anymore.
123 asmlinkage
long sys_setitimer(int which
,
124 struct itimerval __user
*value
,
125 struct itimerval __user
*ovalue
)
127 struct itimerval set_buffer
, get_buffer
;
131 if(copy_from_user(&set_buffer
, value
, sizeof(set_buffer
)))
134 memset((char *) &set_buffer
, 0, sizeof(set_buffer
));
136 error
= do_setitimer(which
, &set_buffer
, ovalue
? &get_buffer
: 0);
137 if (error
|| !ovalue
)
140 if (copy_to_user(ovalue
, &get_buffer
, sizeof(get_buffer
)))