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>
12 #include <linux/time.h>
14 #include <asm/uaccess.h>
16 int do_getitimer(int which
, struct itimerval
*value
)
18 register unsigned long val
, interval
;
22 interval
= current
->it_real_incr
;
25 * FIXME! This needs to be atomic, in case the kernel timer happens!
27 if (timer_pending(¤t
->real_timer
)) {
28 val
= current
->real_timer
.expires
- jiffies
;
30 /* look out for negative/zero itimer.. */
36 val
= current
->it_virt_value
;
37 interval
= current
->it_virt_incr
;
40 val
= current
->it_prof_value
;
41 interval
= current
->it_prof_incr
;
46 jiffies_to_timeval(val
, &value
->it_value
);
47 jiffies_to_timeval(interval
, &value
->it_interval
);
51 /* SMP: Only we modify our itimer values. */
52 asmlinkage
long sys_getitimer(int which
, struct itimerval __user
*value
)
55 struct itimerval get_buffer
;
58 error
= do_getitimer(which
, &get_buffer
);
60 copy_to_user(value
, &get_buffer
, sizeof(get_buffer
)))
66 void it_real_fn(unsigned long __data
)
68 struct task_struct
* p
= (struct task_struct
*) __data
;
69 unsigned long interval
;
71 send_group_sig_info(SIGALRM
, SEND_SIG_PRIV
, p
);
72 interval
= p
->it_real_incr
;
74 if (interval
> (unsigned long) LONG_MAX
)
76 p
->real_timer
.expires
= jiffies
+ interval
;
77 add_timer(&p
->real_timer
);
81 int do_setitimer(int which
, struct itimerval
*value
, struct itimerval
*ovalue
)
83 register unsigned long i
, j
;
86 i
= timeval_to_jiffies(&value
->it_interval
);
87 j
= timeval_to_jiffies(&value
->it_value
);
88 if (ovalue
&& (k
= do_getitimer(which
, ovalue
)) < 0)
92 del_timer_sync(¤t
->real_timer
);
93 current
->it_real_value
= j
;
94 current
->it_real_incr
= i
;
97 if (j
> (unsigned long) LONG_MAX
)
100 current
->real_timer
.expires
= i
;
101 add_timer(¤t
->real_timer
);
106 current
->it_virt_value
= j
;
107 current
->it_virt_incr
= i
;
112 current
->it_prof_value
= j
;
113 current
->it_prof_incr
= i
;
121 /* SMP: Again, only we play with our itimers, and signals are SMP safe
122 * now so that is not an issue at all anymore.
124 asmlinkage
long sys_setitimer(int which
,
125 struct itimerval __user
*value
,
126 struct itimerval __user
*ovalue
)
128 struct itimerval set_buffer
, get_buffer
;
132 if(copy_from_user(&set_buffer
, value
, sizeof(set_buffer
)))
135 memset((char *) &set_buffer
, 0, sizeof(set_buffer
));
137 error
= do_setitimer(which
, &set_buffer
, ovalue
? &get_buffer
: NULL
);
138 if (error
|| !ovalue
)
141 if (copy_to_user(ovalue
, &get_buffer
, sizeof(get_buffer
)))