1139804Simp/*-
21541Srgrimes * Copyright (c) 1982, 1986, 1989, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 4. Neither the name of the University nor the names of its contributors
141541Srgrimes *    may be used to endorse or promote products derived from this software
151541Srgrimes *    without specific prior written permission.
161541Srgrimes *
171541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271541Srgrimes * SUCH DAMAGE.
281541Srgrimes *
291541Srgrimes *	@(#)kern_time.c	8.1 (Berkeley) 6/10/93
301541Srgrimes */
311541Srgrimes
32116182Sobrien#include <sys/cdefs.h>
33116182Sobrien__FBSDID("$FreeBSD: stable/10/sys/kern/kern_time.c 330422 2018-03-04 23:31:25Z bdrewery $");
34116182Sobrien
35303093Skib#include "opt_ktrace.h"
36303093Skib
371541Srgrimes#include <sys/param.h>
3848274Speter#include <sys/systm.h>
39160910Sdavidxu#include <sys/limits.h>
40162954Sphk#include <sys/clock.h>
4176166Smarkm#include <sys/lock.h>
4276166Smarkm#include <sys/mutex.h>
4312221Sbde#include <sys/sysproto.h>
44153259Sdavidxu#include <sys/eventhandler.h>
451541Srgrimes#include <sys/resourcevar.h>
463308Sphk#include <sys/signalvar.h>
471541Srgrimes#include <sys/kernel.h>
48247797Sdavide#include <sys/sleepqueue.h>
49140483Sps#include <sys/syscallsubr.h>
50152983Sdavidxu#include <sys/sysctl.h>
5125583Speter#include <sys/sysent.h>
52164033Srwatson#include <sys/priv.h>
531541Srgrimes#include <sys/proc.h>
54164184Strhodes#include <sys/posix4.h>
5525656Speter#include <sys/time.h>
56151576Sdavidxu#include <sys/timers.h>
5758377Sphk#include <sys/timetc.h>
581541Srgrimes#include <sys/vnode.h>
59303093Skib#ifdef KTRACE
60303093Skib#include <sys/ktrace.h>
61303093Skib#endif
6276166Smarkm
6326335Speter#include <vm/vm.h>
6426335Speter#include <vm/vm_extern.h>
651541Srgrimes
66151576Sdavidxu#define MAX_CLOCKS 	(CLOCK_MONOTONIC+1)
67239347Sdavidxu#define CPUCLOCK_BIT		0x80000000
68239347Sdavidxu#define CPUCLOCK_PROCESS_BIT	0x40000000
69239347Sdavidxu#define CPUCLOCK_ID_MASK	(~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT))
70239347Sdavidxu#define MAKE_THREAD_CPUCLOCK(tid)	(CPUCLOCK_BIT|(tid))
71239347Sdavidxu#define MAKE_PROCESS_CPUCLOCK(pid)	\
72239347Sdavidxu	(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid))
73151576Sdavidxu
74151576Sdavidxustatic struct kclock	posix_clocks[MAX_CLOCKS];
75151576Sdavidxustatic uma_zone_t	itimer_zone = NULL;
76151576Sdavidxu
778876Srgrimes/*
781541Srgrimes * Time of day and interval timer support.
791541Srgrimes *
801541Srgrimes * These routines provide the kernel entry points to get and set
811541Srgrimes * the time-of-day and per-process interval timers.  Subroutines
821541Srgrimes * here provide support for adding and subtracting timeval structures
831541Srgrimes * and decrementing interval timers, optionally reloading the interval
841541Srgrimes * timers when they expire.
851541Srgrimes */
861541Srgrimes
8794343Sjhbstatic int	settime(struct thread *, struct timeval *);
8892723Salfredstatic void	timevalfix(struct timeval *);
8913016Sbde
90151576Sdavidxustatic void	itimer_start(void);
91151576Sdavidxustatic int	itimer_init(void *, int, int);
92151576Sdavidxustatic void	itimer_fini(void *, int);
93151576Sdavidxustatic void	itimer_enter(struct itimer *);
94151576Sdavidxustatic void	itimer_leave(struct itimer *);
95164713Sdavidxustatic struct itimer *itimer_find(struct proc *, int);
96151576Sdavidxustatic void	itimers_alloc(struct proc *);
97161302Snetchildstatic void	itimers_event_hook_exec(void *arg, struct proc *p, struct image_params *imgp);
98161302Snetchildstatic void	itimers_event_hook_exit(void *arg, struct proc *p);
99151576Sdavidxustatic int	realtimer_create(struct itimer *);
100151576Sdavidxustatic int	realtimer_gettime(struct itimer *, struct itimerspec *);
101151576Sdavidxustatic int	realtimer_settime(struct itimer *, int,
102151576Sdavidxu			struct itimerspec *, struct itimerspec *);
103151576Sdavidxustatic int	realtimer_delete(struct itimer *);
104151869Sdavidxustatic void	realtimer_clocktime(clockid_t, struct timespec *);
105151576Sdavidxustatic void	realtimer_expire(void *);
106151576Sdavidxu
107151576Sdavidxuint		register_posix_clock(int, struct kclock *);
108151576Sdavidxuvoid		itimer_fire(struct itimer *it);
109151869Sdavidxuint		itimespecfix(struct timespec *ts);
110151576Sdavidxu
111151576Sdavidxu#define CLOCK_CALL(clock, call, arglist)		\
112151576Sdavidxu	((*posix_clocks[clock].call) arglist)
113151576Sdavidxu
114151576SdavidxuSYSINIT(posix_timer, SI_SUB_P1003_1B, SI_ORDER_FIRST+4, itimer_start, NULL);
115151576Sdavidxu
116151576Sdavidxu
11725583Speterstatic int
118102074Sphksettime(struct thread *td, struct timeval *tv)
11925583Speter{
12045433Snsayer	struct timeval delta, tv1, tv2;
12145438Snsayer	static struct timeval maxtime, laststep;
12233690Sphk	struct timespec ts;
12325583Speter	int s;
12425583Speter
12525656Speter	s = splclock();
12633818Sbde	microtime(&tv1);
12735029Sphk	delta = *tv;
12835029Sphk	timevalsub(&delta, &tv1);
12925583Speter
13025583Speter	/*
13133818Sbde	 * If the system is secure, we do not allow the time to be
13245433Snsayer	 * set to a value earlier than 1 second less than the highest
13345433Snsayer	 * time we have yet seen. The worst a miscreant can do in
13445433Snsayer	 * this circumstance is "freeze" time. He couldn't go
13545433Snsayer	 * back to the past.
13645438Snsayer	 *
13745438Snsayer	 * We similarly do not allow the clock to be stepped more
13845438Snsayer	 * than one second, nor more than once per second. This allows
13945438Snsayer	 * a miscreant to make the clock march double-time, but no worse.
14025583Speter	 */
14194343Sjhb	if (securelevel_gt(td->td_ucred, 1) != 0) {
14245433Snsayer		if (delta.tv_sec < 0 || delta.tv_usec < 0) {
14345437Smjacob			/*
14445438Snsayer			 * Update maxtime to latest time we've seen.
14545437Smjacob			 */
14645437Smjacob			if (tv1.tv_sec > maxtime.tv_sec)
14745437Smjacob				maxtime = tv1;
14845437Smjacob			tv2 = *tv;
14945437Smjacob			timevalsub(&tv2, &maxtime);
15045437Smjacob			if (tv2.tv_sec < -1) {
15145437Smjacob				tv->tv_sec = maxtime.tv_sec - 1;
15245433Snsayer				printf("Time adjustment clamped to -1 second\n");
15345433Snsayer			}
15445437Smjacob		} else {
15545438Snsayer			if (tv1.tv_sec == laststep.tv_sec) {
15645438Snsayer				splx(s);
15745438Snsayer				return (EPERM);
15845438Snsayer			}
15945438Snsayer			if (delta.tv_sec > 1) {
16045438Snsayer				tv->tv_sec = tv1.tv_sec + 1;
16145438Snsayer				printf("Time adjustment clamped to +1 second\n");
16245438Snsayer			}
16345438Snsayer			laststep = *tv;
16445433Snsayer		}
16533818Sbde	}
16633818Sbde
16733690Sphk	ts.tv_sec = tv->tv_sec;
16833690Sphk	ts.tv_nsec = tv->tv_usec * 1000;
16994343Sjhb	mtx_lock(&Giant);
17058377Sphk	tc_setclock(&ts);
17125583Speter	resettodr();
17294343Sjhb	mtx_unlock(&Giant);
17325583Speter	return (0);
17425583Speter}
17525583Speter
17612221Sbde#ifndef _SYS_SYSPROTO_H_
177239347Sdavidxustruct clock_getcpuclockid2_args {
178239347Sdavidxu	id_t id;
179239347Sdavidxu	int which,
180239347Sdavidxu	clockid_t *clock_id;
181239347Sdavidxu};
182239347Sdavidxu#endif
183239347Sdavidxu/* ARGSUSED */
184239347Sdavidxuint
185239347Sdavidxusys_clock_getcpuclockid2(struct thread *td, struct clock_getcpuclockid2_args *uap)
186239347Sdavidxu{
187239347Sdavidxu	clockid_t clk_id;
188253494Skib	int error;
189253494Skib
190253494Skib	error = kern_clock_getcpuclockid2(td, uap->id, uap->which, &clk_id);
191253494Skib	if (error == 0)
192253494Skib		error = copyout(&clk_id, uap->clock_id, sizeof(clockid_t));
193253494Skib	return (error);
194253494Skib}
195253494Skib
196253494Skibint
197253494Skibkern_clock_getcpuclockid2(struct thread *td, id_t id, int which,
198253494Skib    clockid_t *clk_id)
199253494Skib{
200239347Sdavidxu	struct proc *p;
201239347Sdavidxu	pid_t pid;
202239347Sdavidxu	lwpid_t tid;
203239347Sdavidxu	int error;
204239347Sdavidxu
205253494Skib	switch (which) {
206239347Sdavidxu	case CPUCLOCK_WHICH_PID:
207253494Skib		if (id != 0) {
208277287Sdchagin			error = pget(id, PGET_CANSEE | PGET_NOTID, &p);
209253494Skib			if (error != 0)
210239347Sdavidxu				return (error);
211277287Sdchagin			PROC_UNLOCK(p);
212253494Skib			pid = id;
213239347Sdavidxu		} else {
214239347Sdavidxu			pid = td->td_proc->p_pid;
215239347Sdavidxu		}
216253494Skib		*clk_id = MAKE_PROCESS_CPUCLOCK(pid);
217253494Skib		return (0);
218239347Sdavidxu	case CPUCLOCK_WHICH_TID:
219253494Skib		tid = id == 0 ? td->td_tid : id;
220253494Skib		*clk_id = MAKE_THREAD_CPUCLOCK(tid);
221253494Skib		return (0);
222239347Sdavidxu	default:
223239347Sdavidxu		return (EINVAL);
224239347Sdavidxu	}
225239347Sdavidxu}
226239347Sdavidxu
227239347Sdavidxu#ifndef _SYS_SYSPROTO_H_
22825583Speterstruct clock_gettime_args {
22925583Speter	clockid_t clock_id;
23025583Speter	struct	timespec *tp;
23125583Speter};
23225583Speter#endif
23325583Speter/* ARGSUSED */
23425583Speterint
235225617Skmacysys_clock_gettime(struct thread *td, struct clock_gettime_args *uap)
23625583Speter{
23725583Speter	struct timespec ats;
238151357Sps	int error;
239151357Sps
240151357Sps	error = kern_clock_gettime(td, uap->clock_id, &ats);
241151357Sps	if (error == 0)
242151357Sps		error = copyout(&ats, uap->tp, sizeof(ats));
243151357Sps
244151357Sps	return (error);
245151357Sps}
246151357Sps
247239347Sdavidxustatic inline void
248239347Sdavidxucputick2timespec(uint64_t runtime, struct timespec *ats)
249239347Sdavidxu{
250239347Sdavidxu	runtime = cputick2usec(runtime);
251239347Sdavidxu	ats->tv_sec = runtime / 1000000;
252239347Sdavidxu	ats->tv_nsec = runtime % 1000000 * 1000;
253239347Sdavidxu}
254239347Sdavidxu
255239347Sdavidxustatic void
256239347Sdavidxuget_thread_cputime(struct thread *targettd, struct timespec *ats)
257239347Sdavidxu{
258239347Sdavidxu	uint64_t runtime, curtime, switchtime;
259239347Sdavidxu
260239347Sdavidxu	if (targettd == NULL) { /* current thread */
261239347Sdavidxu		critical_enter();
262239347Sdavidxu		switchtime = PCPU_GET(switchtime);
263239347Sdavidxu		curtime = cpu_ticks();
264239347Sdavidxu		runtime = curthread->td_runtime;
265239347Sdavidxu		critical_exit();
266239347Sdavidxu		runtime += curtime - switchtime;
267239347Sdavidxu	} else {
268239347Sdavidxu		thread_lock(targettd);
269239347Sdavidxu		runtime = targettd->td_runtime;
270239347Sdavidxu		thread_unlock(targettd);
271239347Sdavidxu	}
272239347Sdavidxu	cputick2timespec(runtime, ats);
273239347Sdavidxu}
274239347Sdavidxu
275239347Sdavidxustatic void
276239347Sdavidxuget_process_cputime(struct proc *targetp, struct timespec *ats)
277239347Sdavidxu{
278239347Sdavidxu	uint64_t runtime;
279239347Sdavidxu	struct rusage ru;
280239347Sdavidxu
281293473Sdchagin	PROC_STATLOCK(targetp);
282239347Sdavidxu	rufetch(targetp, &ru);
283239347Sdavidxu	runtime = targetp->p_rux.rux_runtime;
284293473Sdchagin	PROC_STATUNLOCK(targetp);
285239347Sdavidxu	cputick2timespec(runtime, ats);
286239347Sdavidxu}
287239347Sdavidxu
288239347Sdavidxustatic int
289239347Sdavidxuget_cputime(struct thread *td, clockid_t clock_id, struct timespec *ats)
290239347Sdavidxu{
291239347Sdavidxu	struct proc *p, *p2;
292239347Sdavidxu	struct thread *td2;
293239347Sdavidxu	lwpid_t tid;
294239347Sdavidxu	pid_t pid;
295239347Sdavidxu	int error;
296239347Sdavidxu
297239347Sdavidxu	p = td->td_proc;
298239347Sdavidxu	if ((clock_id & CPUCLOCK_PROCESS_BIT) == 0) {
299239347Sdavidxu		tid = clock_id & CPUCLOCK_ID_MASK;
300239347Sdavidxu		td2 = tdfind(tid, p->p_pid);
301239347Sdavidxu		if (td2 == NULL)
302239347Sdavidxu			return (EINVAL);
303239347Sdavidxu		get_thread_cputime(td2, ats);
304239347Sdavidxu		PROC_UNLOCK(td2->td_proc);
305239347Sdavidxu	} else {
306239347Sdavidxu		pid = clock_id & CPUCLOCK_ID_MASK;
307253325Skib		error = pget(pid, PGET_CANSEE, &p2);
308253325Skib		if (error != 0)
309239347Sdavidxu			return (EINVAL);
310239347Sdavidxu		get_process_cputime(p2, ats);
311239347Sdavidxu		PROC_UNLOCK(p2);
312239347Sdavidxu	}
313239347Sdavidxu	return (0);
314239347Sdavidxu}
315239347Sdavidxu
316151357Spsint
317151357Spskern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats)
318151357Sps{
319130884Skbyanc	struct timeval sys, user;
320136152Sjhb	struct proc *p;
32125583Speter
322136152Sjhb	p = td->td_proc;
323151357Sps	switch (clock_id) {
324152844Srwatson	case CLOCK_REALTIME:		/* Default to precise. */
325152844Srwatson	case CLOCK_REALTIME_PRECISE:
326151357Sps		nanotime(ats);
327130654Skbyanc		break;
328152844Srwatson	case CLOCK_REALTIME_FAST:
329152844Srwatson		getnanotime(ats);
330152844Srwatson		break;
331130654Skbyanc	case CLOCK_VIRTUAL:
332136152Sjhb		PROC_LOCK(p);
333293473Sdchagin		PROC_STATLOCK(p);
334136152Sjhb		calcru(p, &user, &sys);
335293473Sdchagin		PROC_STATUNLOCK(p);
336136152Sjhb		PROC_UNLOCK(p);
337151357Sps		TIMEVAL_TO_TIMESPEC(&user, ats);
338130654Skbyanc		break;
339130654Skbyanc	case CLOCK_PROF:
340136152Sjhb		PROC_LOCK(p);
341293473Sdchagin		PROC_STATLOCK(p);
342136152Sjhb		calcru(p, &user, &sys);
343293473Sdchagin		PROC_STATUNLOCK(p);
344136152Sjhb		PROC_UNLOCK(p);
345130884Skbyanc		timevaladd(&user, &sys);
346151357Sps		TIMEVAL_TO_TIMESPEC(&user, ats);
347130654Skbyanc		break;
348152844Srwatson	case CLOCK_MONOTONIC:		/* Default to precise. */
349152844Srwatson	case CLOCK_MONOTONIC_PRECISE:
350152585Sandre	case CLOCK_UPTIME:
351152844Srwatson	case CLOCK_UPTIME_PRECISE:
352151357Sps		nanouptime(ats);
353130884Skbyanc		break;
354152844Srwatson	case CLOCK_UPTIME_FAST:
355152844Srwatson	case CLOCK_MONOTONIC_FAST:
356152844Srwatson		getnanouptime(ats);
357152844Srwatson		break;
358152844Srwatson	case CLOCK_SECOND:
359152844Srwatson		ats->tv_sec = time_second;
360152844Srwatson		ats->tv_nsec = 0;
361152844Srwatson		break;
362175429Sdavidxu	case CLOCK_THREAD_CPUTIME_ID:
363239347Sdavidxu		get_thread_cputime(NULL, ats);
364175429Sdavidxu		break;
365239347Sdavidxu	case CLOCK_PROCESS_CPUTIME_ID:
366239347Sdavidxu		PROC_LOCK(p);
367239347Sdavidxu		get_process_cputime(p, ats);
368239347Sdavidxu		PROC_UNLOCK(p);
369239347Sdavidxu		break;
370130654Skbyanc	default:
371239347Sdavidxu		if ((int)clock_id >= 0)
372239347Sdavidxu			return (EINVAL);
373239347Sdavidxu		return (get_cputime(td, clock_id, ats));
374130654Skbyanc	}
375151357Sps	return (0);
37625583Speter}
37725583Speter
37825583Speter#ifndef _SYS_SYSPROTO_H_
37925583Speterstruct clock_settime_args {
38025583Speter	clockid_t clock_id;
38125583Speter	const struct	timespec *tp;
38225583Speter};
38325583Speter#endif
38425583Speter/* ARGSUSED */
38525583Speterint
386225617Skmacysys_clock_settime(struct thread *td, struct clock_settime_args *uap)
38725583Speter{
38825583Speter	struct timespec ats;
38925583Speter	int error;
39025583Speter
391151357Sps	if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
392151357Sps		return (error);
393151357Sps	return (kern_clock_settime(td, uap->clock_id, &ats));
394151357Sps}
395151357Sps
396151357Spsint
397151357Spskern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats)
398151357Sps{
399151357Sps	struct timeval atv;
400151357Sps	int error;
401151357Sps
402164033Srwatson	if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0)
40394343Sjhb		return (error);
404151357Sps	if (clock_id != CLOCK_REALTIME)
40594343Sjhb		return (EINVAL);
406151357Sps	if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000)
40794343Sjhb		return (EINVAL);
40834901Sphk	/* XXX Don't convert nsec->usec and back */
409151357Sps	TIMESPEC_TO_TIMEVAL(&atv, ats);
41094343Sjhb	error = settime(td, &atv);
41182746Sdillon	return (error);
41225583Speter}
41325583Speter
41425583Speter#ifndef _SYS_SYSPROTO_H_
41525583Speterstruct clock_getres_args {
41625583Speter	clockid_t clock_id;
41725583Speter	struct	timespec *tp;
41825583Speter};
41925583Speter#endif
42025583Speterint
421225617Skmacysys_clock_getres(struct thread *td, struct clock_getres_args *uap)
42225583Speter{
42325583Speter	struct timespec ts;
424151357Sps	int error;
42525583Speter
426151357Sps	if (uap->tp == NULL)
427151357Sps		return (0);
428151357Sps
429151357Sps	error = kern_clock_getres(td, uap->clock_id, &ts);
430151357Sps	if (error == 0)
431151357Sps		error = copyout(&ts, uap->tp, sizeof(ts));
432151357Sps	return (error);
433151357Sps}
434151357Sps
435151357Spsint
436151357Spskern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts)
437151357Sps{
438151357Sps
439151357Sps	ts->tv_sec = 0;
440151357Sps	switch (clock_id) {
441130654Skbyanc	case CLOCK_REALTIME:
442152844Srwatson	case CLOCK_REALTIME_FAST:
443152844Srwatson	case CLOCK_REALTIME_PRECISE:
444130654Skbyanc	case CLOCK_MONOTONIC:
445152844Srwatson	case CLOCK_MONOTONIC_FAST:
446152844Srwatson	case CLOCK_MONOTONIC_PRECISE:
447152585Sandre	case CLOCK_UPTIME:
448152844Srwatson	case CLOCK_UPTIME_FAST:
449152844Srwatson	case CLOCK_UPTIME_PRECISE:
450103964Sbde		/*
451103964Sbde		 * Round up the result of the division cheaply by adding 1.
452103964Sbde		 * Rounding up is especially important if rounding down
453103964Sbde		 * would give 0.  Perfect rounding is unimportant.
454103964Sbde		 */
455151357Sps		ts->tv_nsec = 1000000000 / tc_getfrequency() + 1;
456130654Skbyanc		break;
457130654Skbyanc	case CLOCK_VIRTUAL:
458130654Skbyanc	case CLOCK_PROF:
459130654Skbyanc		/* Accurately round up here because we can do so cheaply. */
460151357Sps		ts->tv_nsec = (1000000000 + hz - 1) / hz;
461130654Skbyanc		break;
462152844Srwatson	case CLOCK_SECOND:
463152844Srwatson		ts->tv_sec = 1;
464152844Srwatson		ts->tv_nsec = 0;
465152844Srwatson		break;
466175429Sdavidxu	case CLOCK_THREAD_CPUTIME_ID:
467239347Sdavidxu	case CLOCK_PROCESS_CPUTIME_ID:
468239347Sdavidxu	cputime:
469175429Sdavidxu		/* sync with cputick2usec */
470175429Sdavidxu		ts->tv_nsec = 1000000 / cpu_tickrate();
471175429Sdavidxu		if (ts->tv_nsec == 0)
472175429Sdavidxu			ts->tv_nsec = 1000;
473175429Sdavidxu		break;
474130654Skbyanc	default:
475239347Sdavidxu		if ((int)clock_id < 0)
476239347Sdavidxu			goto cputime;
477130654Skbyanc		return (EINVAL);
478130654Skbyanc	}
479151357Sps	return (0);
48025583Speter}
48125583Speter
482248186Smavstatic uint8_t nanowait[MAXCPU];
48325656Speter
484140481Spsint
485140481Spskern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
48625583Speter{
487247797Sdavide	struct timespec ts;
488247797Sdavide	sbintime_t sbt, sbtt, prec, tmp;
489247898Smav	time_t over;
49035042Sphk	int error;
49125583Speter
49228773Sbde	if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
49325656Speter		return (EINVAL);
49443301Sdillon	if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
49528773Sbde		return (0);
496247898Smav	ts = *rqt;
497247898Smav	if (ts.tv_sec > INT32_MAX / 2) {
498247898Smav		over = ts.tv_sec - INT32_MAX / 2;
499247898Smav		ts.tv_sec -= over;
500247898Smav	} else
501247898Smav		over = 0;
502247898Smav	tmp = tstosbt(ts);
503247797Sdavide	prec = tmp;
504247797Sdavide	prec >>= tc_precexp;
505247797Sdavide	if (TIMESEL(&sbt, tmp))
506247797Sdavide		sbt += tc_tick_sbt;
507247797Sdavide	sbt += tmp;
508248186Smav	error = tsleep_sbt(&nanowait[curcpu], PWAIT | PCATCH, "nanslp",
509248186Smav	    sbt, prec, C_ABSOLUTE);
510247797Sdavide	if (error != EWOULDBLOCK) {
511247797Sdavide		if (error == ERESTART)
512247797Sdavide			error = EINTR;
513330422Sbdrewery		if (TIMESEL(&sbtt, tmp))
514330422Sbdrewery			sbtt += tc_tick_sbt;
515247797Sdavide		if (rmt != NULL) {
516247797Sdavide			ts = sbttots(sbt - sbtt);
517247898Smav			ts.tv_sec += over;
518247797Sdavide			if (ts.tv_sec < 0)
519247797Sdavide				timespecclear(&ts);
520247797Sdavide			*rmt = ts;
52135042Sphk		}
522247797Sdavide		if (sbtt >= sbt)
52335042Sphk			return (0);
524247797Sdavide		return (error);
52526335Speter	}
526247797Sdavide	return (0);
52726335Speter}
52825583Speter
52926335Speter#ifndef _SYS_SYSPROTO_H_
53026335Speterstruct nanosleep_args {
53126335Speter	struct	timespec *rqtp;
53226335Speter	struct	timespec *rmtp;
53326335Speter};
53426335Speter#endif
53526335Speter/* ARGSUSED */
53626335Speterint
537225617Skmacysys_nanosleep(struct thread *td, struct nanosleep_args *uap)
53826335Speter{
53926335Speter	struct timespec rmt, rqt;
54082746Sdillon	int error;
54126335Speter
542107849Salfred	error = copyin(uap->rqtp, &rqt, sizeof(rqt));
54326335Speter	if (error)
54426335Speter		return (error);
54582746Sdillon
546109521Salfred	if (uap->rmtp &&
547109521Salfred	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
548109521Salfred			return (EFAULT);
549140481Sps	error = kern_nanosleep(td, &rqt, &rmt);
550315658Svangyzen	if (error == EINTR && uap->rmtp) {
55182746Sdillon		int error2;
55282746Sdillon
553107849Salfred		error2 = copyout(&rmt, uap->rmtp, sizeof(rmt));
554109521Salfred		if (error2)
55582746Sdillon			error = error2;
55625583Speter	}
55725656Speter	return (error);
55825583Speter}
55925583Speter
56026335Speter#ifndef _SYS_SYSPROTO_H_
5611541Srgrimesstruct gettimeofday_args {
5621541Srgrimes	struct	timeval *tp;
5631541Srgrimes	struct	timezone *tzp;
5641541Srgrimes};
56512221Sbde#endif
5661541Srgrimes/* ARGSUSED */
5671549Srgrimesint
568225617Skmacysys_gettimeofday(struct thread *td, struct gettimeofday_args *uap)
5691541Srgrimes{
5701541Srgrimes	struct timeval atv;
571110286Stjr	struct timezone rtz;
5721541Srgrimes	int error = 0;
5731541Srgrimes
5741541Srgrimes	if (uap->tp) {
5751541Srgrimes		microtime(&atv);
57699012Salfred		error = copyout(&atv, uap->tp, sizeof (atv));
5771541Srgrimes	}
57890836Sphk	if (error == 0 && uap->tzp != NULL) {
579110299Sphk		rtz.tz_minuteswest = tz_minuteswest;
580110299Sphk		rtz.tz_dsttime = tz_dsttime;
581110286Stjr		error = copyout(&rtz, uap->tzp, sizeof (rtz));
58282746Sdillon	}
5831541Srgrimes	return (error);
5841541Srgrimes}
5851541Srgrimes
58612221Sbde#ifndef _SYS_SYSPROTO_H_
5871541Srgrimesstruct settimeofday_args {
5881541Srgrimes	struct	timeval *tv;
5891541Srgrimes	struct	timezone *tzp;
5901541Srgrimes};
59112221Sbde#endif
5921541Srgrimes/* ARGSUSED */
5931549Srgrimesint
594225617Skmacysys_settimeofday(struct thread *td, struct settimeofday_args *uap)
5951541Srgrimes{
596144445Sjhb	struct timeval atv, *tvp;
597144445Sjhb	struct timezone atz, *tzp;
598144445Sjhb	int error;
5991541Srgrimes
600144445Sjhb	if (uap->tv) {
601144445Sjhb		error = copyin(uap->tv, &atv, sizeof(atv));
602144445Sjhb		if (error)
603144445Sjhb			return (error);
604144445Sjhb		tvp = &atv;
605144445Sjhb	} else
606144445Sjhb		tvp = NULL;
607144445Sjhb	if (uap->tzp) {
608144445Sjhb		error = copyin(uap->tzp, &atz, sizeof(atz));
609144445Sjhb		if (error)
610144445Sjhb			return (error);
611144445Sjhb		tzp = &atz;
612144445Sjhb	} else
613144445Sjhb		tzp = NULL;
614144445Sjhb	return (kern_settimeofday(td, tvp, tzp));
615144445Sjhb}
616144445Sjhb
617144445Sjhbint
618144445Sjhbkern_settimeofday(struct thread *td, struct timeval *tv, struct timezone *tzp)
619144445Sjhb{
620144445Sjhb	int error;
621144445Sjhb
622164033Srwatson	error = priv_check(td, PRIV_SETTIMEOFDAY);
623144445Sjhb	if (error)
62494343Sjhb		return (error);
6251541Srgrimes	/* Verify all parameters before changing time. */
626144445Sjhb	if (tv) {
627144445Sjhb		if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
62894343Sjhb			return (EINVAL);
629144445Sjhb		error = settime(td, tv);
63025656Speter	}
631144445Sjhb	if (tzp && error == 0) {
632144445Sjhb		tz_minuteswest = tzp->tz_minuteswest;
633144445Sjhb		tz_dsttime = tzp->tz_dsttime;
63482746Sdillon	}
63582746Sdillon	return (error);
6361541Srgrimes}
637144445Sjhb
63882746Sdillon/*
639167232Srwatson * Get value of an interval timer.  The process virtual and profiling virtual
640167232Srwatson * time timers are kept in the p_stats area, since they can be swapped out.
641167232Srwatson * These are kept internally in the way they are specified externally: in
642167232Srwatson * time until they expire.
6431541Srgrimes *
644167232Srwatson * The real time interval timer is kept in the process table slot for the
645167232Srwatson * process, and its value (it_value) is kept as an absolute time rather than
646167232Srwatson * as a delta, so that it is easy to keep periodic real-time signals from
647167232Srwatson * drifting.
6481541Srgrimes *
6491541Srgrimes * Virtual time timers are processed in the hardclock() routine of
650167232Srwatson * kern_clock.c.  The real time timer is processed by a timeout routine,
651167232Srwatson * called from the softclock() routine.  Since a callout may be delayed in
652167232Srwatson * real time due to interrupt processing in the system, it is possible for
653167232Srwatson * the real time timeout routine (realitexpire, given below), to be delayed
654167232Srwatson * in real time past when it is supposed to occur.  It does not suffice,
655167232Srwatson * therefore, to reload the real timer .it_value from the real time timers
656167232Srwatson * .it_interval.  Rather, we compute the next time in absolute time the timer
657167232Srwatson * should go off.
6581541Srgrimes */
65912221Sbde#ifndef _SYS_SYSPROTO_H_
6601541Srgrimesstruct getitimer_args {
6611541Srgrimes	u_int	which;
6621541Srgrimes	struct	itimerval *itv;
6631541Srgrimes};
66412221Sbde#endif
6651549Srgrimesint
666225617Skmacysys_getitimer(struct thread *td, struct getitimer_args *uap)
6671541Srgrimes{
668141470Sjhb	struct itimerval aitv;
669140832Ssobomax	int error;
670140832Ssobomax
671140832Ssobomax	error = kern_getitimer(td, uap->which, &aitv);
672140832Ssobomax	if (error != 0)
673140832Ssobomax		return (error);
674140832Ssobomax	return (copyout(&aitv, uap->itv, sizeof (struct itimerval)));
675140832Ssobomax}
676140832Ssobomax
677140832Ssobomaxint
678140832Ssobomaxkern_getitimer(struct thread *td, u_int which, struct itimerval *aitv)
679140832Ssobomax{
68083366Sjulian	struct proc *p = td->td_proc;
68134961Sphk	struct timeval ctv;
6821541Srgrimes
683140832Ssobomax	if (which > ITIMER_PROF)
6841541Srgrimes		return (EINVAL);
68582746Sdillon
686140832Ssobomax	if (which == ITIMER_REAL) {
6871541Srgrimes		/*
68836128Sbde		 * Convert from absolute to relative time in .it_value
6891541Srgrimes		 * part of real time timer.  If time for real time timer
6901541Srgrimes		 * has passed return 0, else return difference between
6911541Srgrimes		 * current time and time for the timer to go off.
6921541Srgrimes		 */
693111034Stjr		PROC_LOCK(p);
694140832Ssobomax		*aitv = p->p_realtimer;
695111034Stjr		PROC_UNLOCK(p);
696140832Ssobomax		if (timevalisset(&aitv->it_value)) {
697247903Smav			microuptime(&ctv);
698140832Ssobomax			if (timevalcmp(&aitv->it_value, &ctv, <))
699140832Ssobomax				timevalclear(&aitv->it_value);
7001541Srgrimes			else
701140832Ssobomax				timevalsub(&aitv->it_value, &ctv);
70234961Sphk		}
70382746Sdillon	} else {
704293473Sdchagin		PROC_ITIMLOCK(p);
705140832Ssobomax		*aitv = p->p_stats->p_timer[which];
706293473Sdchagin		PROC_ITIMUNLOCK(p);
70782746Sdillon	}
708303093Skib#ifdef KTRACE
709303093Skib	if (KTRPOINT(td, KTR_STRUCT))
710303093Skib		ktritimerval(aitv);
711303093Skib#endif
712140832Ssobomax	return (0);
7131541Srgrimes}
7141541Srgrimes
71512221Sbde#ifndef _SYS_SYSPROTO_H_
7161541Srgrimesstruct setitimer_args {
7171541Srgrimes	u_int	which;
7181541Srgrimes	struct	itimerval *itv, *oitv;
7191541Srgrimes};
72012221Sbde#endif
7211549Srgrimesint
722225617Skmacysys_setitimer(struct thread *td, struct setitimer_args *uap)
7231541Srgrimes{
724141470Sjhb	struct itimerval aitv, oitv;
725140832Ssobomax	int error;
7261541Srgrimes
727111034Stjr	if (uap->itv == NULL) {
728111034Stjr		uap->itv = uap->oitv;
729225617Skmacy		return (sys_getitimer(td, (struct getitimer_args *)uap));
730111034Stjr	}
731111034Stjr
732111034Stjr	if ((error = copyin(uap->itv, &aitv, sizeof(struct itimerval))))
7331541Srgrimes		return (error);
734140832Ssobomax	error = kern_setitimer(td, uap->which, &aitv, &oitv);
735140832Ssobomax	if (error != 0 || uap->oitv == NULL)
736140832Ssobomax		return (error);
737140832Ssobomax	return (copyout(&oitv, uap->oitv, sizeof(struct itimerval)));
738140832Ssobomax}
739140832Ssobomax
740140832Ssobomaxint
741141470Sjhbkern_setitimer(struct thread *td, u_int which, struct itimerval *aitv,
742141470Sjhb    struct itimerval *oitv)
743140832Ssobomax{
744140832Ssobomax	struct proc *p = td->td_proc;
745140832Ssobomax	struct timeval ctv;
746247903Smav	sbintime_t sbt, pr;
747140832Ssobomax
748141483Sjhb	if (aitv == NULL)
749141483Sjhb		return (kern_getitimer(td, which, oitv));
750141483Sjhb
751140832Ssobomax	if (which > ITIMER_PROF)
752111034Stjr		return (EINVAL);
753303093Skib#ifdef KTRACE
754303093Skib	if (KTRPOINT(td, KTR_STRUCT))
755303093Skib		ktritimerval(aitv);
756303093Skib#endif
757247903Smav	if (itimerfix(&aitv->it_value) ||
758247903Smav	    aitv->it_value.tv_sec > INT32_MAX / 2)
759111034Stjr		return (EINVAL);
760140832Ssobomax	if (!timevalisset(&aitv->it_value))
761140832Ssobomax		timevalclear(&aitv->it_interval);
762247903Smav	else if (itimerfix(&aitv->it_interval) ||
763247903Smav	    aitv->it_interval.tv_sec > INT32_MAX / 2)
764140832Ssobomax		return (EINVAL);
76582746Sdillon
766140832Ssobomax	if (which == ITIMER_REAL) {
767111034Stjr		PROC_LOCK(p);
76835058Sphk		if (timevalisset(&p->p_realtimer.it_value))
76969286Sjake			callout_stop(&p->p_itcallout);
770247903Smav		microuptime(&ctv);
771140832Ssobomax		if (timevalisset(&aitv->it_value)) {
772247903Smav			pr = tvtosbt(aitv->it_value) >> tc_precexp;
773140832Ssobomax			timevaladd(&aitv->it_value, &ctv);
774247903Smav			sbt = tvtosbt(aitv->it_value);
775247903Smav			callout_reset_sbt(&p->p_itcallout, sbt, pr,
776247903Smav			    realitexpire, p, C_ABSOLUTE);
777114980Sjhb		}
778140832Ssobomax		*oitv = p->p_realtimer;
779140832Ssobomax		p->p_realtimer = *aitv;
780111034Stjr		PROC_UNLOCK(p);
781140832Ssobomax		if (timevalisset(&oitv->it_value)) {
782140832Ssobomax			if (timevalcmp(&oitv->it_value, &ctv, <))
783140832Ssobomax				timevalclear(&oitv->it_value);
784111034Stjr			else
785140832Ssobomax				timevalsub(&oitv->it_value, &ctv);
786111034Stjr		}
78782746Sdillon	} else {
788264821Smav		if (aitv->it_interval.tv_sec == 0 &&
789264821Smav		    aitv->it_interval.tv_usec != 0 &&
790264821Smav		    aitv->it_interval.tv_usec < tick)
791264821Smav			aitv->it_interval.tv_usec = tick;
792264821Smav		if (aitv->it_value.tv_sec == 0 &&
793264821Smav		    aitv->it_value.tv_usec != 0 &&
794264821Smav		    aitv->it_value.tv_usec < tick)
795264821Smav			aitv->it_value.tv_usec = tick;
796293473Sdchagin		PROC_ITIMLOCK(p);
797140832Ssobomax		*oitv = p->p_stats->p_timer[which];
798140832Ssobomax		p->p_stats->p_timer[which] = *aitv;
799293473Sdchagin		PROC_ITIMUNLOCK(p);
80082746Sdillon	}
801303093Skib#ifdef KTRACE
802303093Skib	if (KTRPOINT(td, KTR_STRUCT))
803303093Skib		ktritimerval(oitv);
804303093Skib#endif
805140832Ssobomax	return (0);
8061541Srgrimes}
8071541Srgrimes
8081541Srgrimes/*
8091541Srgrimes * Real interval timer expired:
8101541Srgrimes * send process whose timer expired an alarm signal.
8111541Srgrimes * If time is not set up to reload, then just return.
8121541Srgrimes * Else compute next time timer should go off which is > current time.
8131541Srgrimes * This is where delay in processing this timeout causes multiple
8141541Srgrimes * SIGALRM calls to be compressed into one.
81536127Sbde * tvtohz() always adds 1 to allow for the time until the next clock
8169327Sbde * interrupt being strictly less than 1 clock tick, but we don't want
8179327Sbde * that here since we want to appear to be in sync with the clock
8189327Sbde * interrupt even when we're delayed.
8191541Srgrimes */
8201541Srgrimesvoid
821102074Sphkrealitexpire(void *arg)
8221541Srgrimes{
823102074Sphk	struct proc *p;
824247903Smav	struct timeval ctv;
825247903Smav	sbintime_t isbt;
8261541Srgrimes
8271541Srgrimes	p = (struct proc *)arg;
828225617Skmacy	kern_psignal(p, SIGALRM);
82935058Sphk	if (!timevalisset(&p->p_realtimer.it_interval)) {
83035058Sphk		timevalclear(&p->p_realtimer.it_value);
831116123Sjhb		if (p->p_flag & P_WEXIT)
832116123Sjhb			wakeup(&p->p_itcallout);
8331541Srgrimes		return;
8341541Srgrimes	}
835247903Smav	isbt = tvtosbt(p->p_realtimer.it_interval);
836247903Smav	if (isbt >= sbt_timethreshold)
837247903Smav		getmicrouptime(&ctv);
838247903Smav	else
839247903Smav		microuptime(&ctv);
840247903Smav	do {
8411541Srgrimes		timevaladd(&p->p_realtimer.it_value,
8421541Srgrimes		    &p->p_realtimer.it_interval);
843247903Smav	} while (timevalcmp(&p->p_realtimer.it_value, &ctv, <=));
844247903Smav	callout_reset_sbt(&p->p_itcallout, tvtosbt(p->p_realtimer.it_value),
845247903Smav	    isbt >> tc_precexp, realitexpire, p, C_ABSOLUTE);
8461541Srgrimes}
8471541Srgrimes
8481541Srgrimes/*
8491541Srgrimes * Check that a proposed value to load into the .it_value or
8501541Srgrimes * .it_interval part of an interval timer is acceptable, and
8511541Srgrimes * fix it to have at least minimal value (i.e. if it is less
8521541Srgrimes * than the resolution of the clock, round it up.)
8531541Srgrimes */
8541549Srgrimesint
855102074Sphkitimerfix(struct timeval *tv)
8561541Srgrimes{
8571541Srgrimes
858151576Sdavidxu	if (tv->tv_sec < 0 || tv->tv_usec < 0 || tv->tv_usec >= 1000000)
8591541Srgrimes		return (EINVAL);
860247903Smav	if (tv->tv_sec == 0 && tv->tv_usec != 0 &&
861247903Smav	    tv->tv_usec < (u_int)tick / 16)
862247903Smav		tv->tv_usec = (u_int)tick / 16;
8631541Srgrimes	return (0);
8641541Srgrimes}
8651541Srgrimes
8661541Srgrimes/*
8671541Srgrimes * Decrement an interval timer by a specified number
8681541Srgrimes * of microseconds, which must be less than a second,
8691541Srgrimes * i.e. < 1000000.  If the timer expires, then reload
8701541Srgrimes * it.  In this case, carry over (usec - old value) to
8711541Srgrimes * reduce the value reloaded into the timer so that
8721541Srgrimes * the timer does not drift.  This routine assumes
8731541Srgrimes * that it is called in a context where the timers
8741541Srgrimes * on which it is operating cannot change in value.
8751541Srgrimes */
8761549Srgrimesint
877102074Sphkitimerdecr(struct itimerval *itp, int usec)
8781541Srgrimes{
8791541Srgrimes
8801541Srgrimes	if (itp->it_value.tv_usec < usec) {
8811541Srgrimes		if (itp->it_value.tv_sec == 0) {
8821541Srgrimes			/* expired, and already in next interval */
8831541Srgrimes			usec -= itp->it_value.tv_usec;
8841541Srgrimes			goto expire;
8851541Srgrimes		}
8861541Srgrimes		itp->it_value.tv_usec += 1000000;
8871541Srgrimes		itp->it_value.tv_sec--;
8881541Srgrimes	}
8891541Srgrimes	itp->it_value.tv_usec -= usec;
8901541Srgrimes	usec = 0;
89135058Sphk	if (timevalisset(&itp->it_value))
8921541Srgrimes		return (1);
8931541Srgrimes	/* expired, exactly at end of interval */
8941541Srgrimesexpire:
89535058Sphk	if (timevalisset(&itp->it_interval)) {
8961541Srgrimes		itp->it_value = itp->it_interval;
8971541Srgrimes		itp->it_value.tv_usec -= usec;
8981541Srgrimes		if (itp->it_value.tv_usec < 0) {
8991541Srgrimes			itp->it_value.tv_usec += 1000000;
9001541Srgrimes			itp->it_value.tv_sec--;
9011541Srgrimes		}
9021541Srgrimes	} else
9031541Srgrimes		itp->it_value.tv_usec = 0;		/* sec is already 0 */
9041541Srgrimes	return (0);
9051541Srgrimes}
9061541Srgrimes
9071541Srgrimes/*
9081541Srgrimes * Add and subtract routines for timevals.
9091541Srgrimes * N.B.: subtract routine doesn't deal with
9101541Srgrimes * results which are before the beginning,
9111541Srgrimes * it just gets very confused in this case.
9121541Srgrimes * Caveat emptor.
9131541Srgrimes */
9141549Srgrimesvoid
915121523Salfredtimevaladd(struct timeval *t1, const struct timeval *t2)
9161541Srgrimes{
9171541Srgrimes
9181541Srgrimes	t1->tv_sec += t2->tv_sec;
9191541Srgrimes	t1->tv_usec += t2->tv_usec;
9201541Srgrimes	timevalfix(t1);
9211541Srgrimes}
9221541Srgrimes
9231549Srgrimesvoid
924121523Salfredtimevalsub(struct timeval *t1, const struct timeval *t2)
9251541Srgrimes{
9261541Srgrimes
9271541Srgrimes	t1->tv_sec -= t2->tv_sec;
9281541Srgrimes	t1->tv_usec -= t2->tv_usec;
9291541Srgrimes	timevalfix(t1);
9301541Srgrimes}
9311541Srgrimes
93212819Sphkstatic void
933102074Sphktimevalfix(struct timeval *t1)
9341541Srgrimes{
9351541Srgrimes
9361541Srgrimes	if (t1->tv_usec < 0) {
9371541Srgrimes		t1->tv_sec--;
9381541Srgrimes		t1->tv_usec += 1000000;
9391541Srgrimes	}
9401541Srgrimes	if (t1->tv_usec >= 1000000) {
9411541Srgrimes		t1->tv_sec++;
9421541Srgrimes		t1->tv_usec -= 1000000;
9431541Srgrimes	}
9441541Srgrimes}
945108142Ssam
946108142Ssam/*
947108511Ssam * ratecheck(): simple time-based rate-limit checking.
948108142Ssam */
949108142Ssamint
950108142Ssamratecheck(struct timeval *lasttime, const struct timeval *mininterval)
951108142Ssam{
952108142Ssam	struct timeval tv, delta;
953108142Ssam	int rv = 0;
954108142Ssam
955108511Ssam	getmicrouptime(&tv);		/* NB: 10ms precision */
956108511Ssam	delta = tv;
957108511Ssam	timevalsub(&delta, lasttime);
958108142Ssam
959108142Ssam	/*
960108142Ssam	 * check for 0,0 is so that the message will be seen at least once,
961108142Ssam	 * even if interval is huge.
962108142Ssam	 */
963108142Ssam	if (timevalcmp(&delta, mininterval, >=) ||
964108142Ssam	    (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) {
965108142Ssam		*lasttime = tv;
966108142Ssam		rv = 1;
967108142Ssam	}
968108142Ssam
969108142Ssam	return (rv);
970108142Ssam}
971108142Ssam
972108142Ssam/*
973108142Ssam * ppsratecheck(): packets (or events) per second limitation.
974108511Ssam *
975108511Ssam * Return 0 if the limit is to be enforced (e.g. the caller
976108511Ssam * should drop a packet because of the rate limitation).
977108511Ssam *
978111558Ssam * maxpps of 0 always causes zero to be returned.  maxpps of -1
979111558Ssam * always causes 1 to be returned; this effectively defeats rate
980111558Ssam * limiting.
981111558Ssam *
982108511Ssam * Note that we maintain the struct timeval for compatibility
983108511Ssam * with other bsd systems.  We reuse the storage and just monitor
984108511Ssam * clock ticks for minimal overhead.
985108142Ssam */
986108142Ssamint
987108142Ssamppsratecheck(struct timeval *lasttime, int *curpps, int maxpps)
988108142Ssam{
989108511Ssam	int now;
990108142Ssam
991108142Ssam	/*
992108511Ssam	 * Reset the last time and counter if this is the first call
993108511Ssam	 * or more than a second has passed since the last update of
994108511Ssam	 * lasttime.
995108142Ssam	 */
996108511Ssam	now = ticks;
997108511Ssam	if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) {
998108511Ssam		lasttime->tv_sec = now;
999108511Ssam		*curpps = 1;
1000111558Ssam		return (maxpps != 0);
1001108511Ssam	} else {
1002108511Ssam		(*curpps)++;		/* NB: ignore potential overflow */
1003278686Sian		return (maxpps < 0 || *curpps <= maxpps);
1004108511Ssam	}
1005108142Ssam}
1006151576Sdavidxu
1007151576Sdavidxustatic void
1008151576Sdavidxuitimer_start(void)
1009151576Sdavidxu{
1010151576Sdavidxu	struct kclock rt_clock = {
1011151576Sdavidxu		.timer_create  = realtimer_create,
1012151576Sdavidxu		.timer_delete  = realtimer_delete,
1013151576Sdavidxu		.timer_settime = realtimer_settime,
1014151576Sdavidxu		.timer_gettime = realtimer_gettime,
1015164713Sdavidxu		.event_hook    = NULL
1016151576Sdavidxu	};
1017151576Sdavidxu
1018151576Sdavidxu	itimer_zone = uma_zcreate("itimer", sizeof(struct itimer),
1019151576Sdavidxu		NULL, NULL, itimer_init, itimer_fini, UMA_ALIGN_PTR, 0);
1020151576Sdavidxu	register_posix_clock(CLOCK_REALTIME,  &rt_clock);
1021151576Sdavidxu	register_posix_clock(CLOCK_MONOTONIC, &rt_clock);
1022152983Sdavidxu	p31b_setcfg(CTL_P1003_1B_TIMERS, 200112L);
1023152983Sdavidxu	p31b_setcfg(CTL_P1003_1B_DELAYTIMER_MAX, INT_MAX);
1024152983Sdavidxu	p31b_setcfg(CTL_P1003_1B_TIMER_MAX, TIMER_MAX);
1025161302Snetchild	EVENTHANDLER_REGISTER(process_exit, itimers_event_hook_exit,
1026153259Sdavidxu		(void *)ITIMER_EV_EXIT, EVENTHANDLER_PRI_ANY);
1027161302Snetchild	EVENTHANDLER_REGISTER(process_exec, itimers_event_hook_exec,
1028153259Sdavidxu		(void *)ITIMER_EV_EXEC, EVENTHANDLER_PRI_ANY);
1029151576Sdavidxu}
1030151576Sdavidxu
1031151576Sdavidxuint
1032151576Sdavidxuregister_posix_clock(int clockid, struct kclock *clk)
1033151576Sdavidxu{
1034151576Sdavidxu	if ((unsigned)clockid >= MAX_CLOCKS) {
1035151576Sdavidxu		printf("%s: invalid clockid\n", __func__);
1036151576Sdavidxu		return (0);
1037151576Sdavidxu	}
1038151576Sdavidxu	posix_clocks[clockid] = *clk;
1039151576Sdavidxu	return (1);
1040151576Sdavidxu}
1041151576Sdavidxu
1042151576Sdavidxustatic int
1043151576Sdavidxuitimer_init(void *mem, int size, int flags)
1044151576Sdavidxu{
1045151576Sdavidxu	struct itimer *it;
1046151576Sdavidxu
1047151576Sdavidxu	it = (struct itimer *)mem;
1048151576Sdavidxu	mtx_init(&it->it_mtx, "itimer lock", NULL, MTX_DEF);
1049151576Sdavidxu	return (0);
1050151576Sdavidxu}
1051151576Sdavidxu
1052151576Sdavidxustatic void
1053151576Sdavidxuitimer_fini(void *mem, int size)
1054151576Sdavidxu{
1055151576Sdavidxu	struct itimer *it;
1056151576Sdavidxu
1057151576Sdavidxu	it = (struct itimer *)mem;
1058151576Sdavidxu	mtx_destroy(&it->it_mtx);
1059151576Sdavidxu}
1060151576Sdavidxu
1061151576Sdavidxustatic void
1062151576Sdavidxuitimer_enter(struct itimer *it)
1063151576Sdavidxu{
1064151576Sdavidxu
1065151576Sdavidxu	mtx_assert(&it->it_mtx, MA_OWNED);
1066151576Sdavidxu	it->it_usecount++;
1067151576Sdavidxu}
1068151576Sdavidxu
1069151576Sdavidxustatic void
1070151576Sdavidxuitimer_leave(struct itimer *it)
1071151576Sdavidxu{
1072151576Sdavidxu
1073151576Sdavidxu	mtx_assert(&it->it_mtx, MA_OWNED);
1074151576Sdavidxu	KASSERT(it->it_usecount > 0, ("invalid it_usecount"));
1075151576Sdavidxu
1076151576Sdavidxu	if (--it->it_usecount == 0 && (it->it_flags & ITF_WANTED) != 0)
1077151576Sdavidxu		wakeup(it);
1078151576Sdavidxu}
1079151576Sdavidxu
1080151576Sdavidxu#ifndef _SYS_SYSPROTO_H_
1081156134Sdavidxustruct ktimer_create_args {
1082151576Sdavidxu	clockid_t clock_id;
1083151576Sdavidxu	struct sigevent * evp;
1084156134Sdavidxu	int * timerid;
1085151576Sdavidxu};
1086151576Sdavidxu#endif
1087151576Sdavidxuint
1088225617Skmacysys_ktimer_create(struct thread *td, struct ktimer_create_args *uap)
1089151576Sdavidxu{
1090253530Skib	struct sigevent *evp, ev;
1091156134Sdavidxu	int id;
1092151576Sdavidxu	int error;
1093151576Sdavidxu
1094253530Skib	if (uap->evp == NULL) {
1095253530Skib		evp = NULL;
1096253530Skib	} else {
1097151576Sdavidxu		error = copyin(uap->evp, &ev, sizeof(ev));
1098151576Sdavidxu		if (error != 0)
1099151576Sdavidxu			return (error);
1100253530Skib		evp = &ev;
1101253530Skib	}
1102253530Skib	error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
1103151576Sdavidxu	if (error == 0) {
1104156134Sdavidxu		error = copyout(&id, uap->timerid, sizeof(int));
1105151576Sdavidxu		if (error != 0)
1106253530Skib			kern_ktimer_delete(td, id);
1107151576Sdavidxu	}
1108151576Sdavidxu	return (error);
1109151576Sdavidxu}
1110151576Sdavidxu
1111253530Skibint
1112253530Skibkern_ktimer_create(struct thread *td, clockid_t clock_id, struct sigevent *evp,
1113253530Skib    int *timerid, int preset_id)
1114151576Sdavidxu{
1115151576Sdavidxu	struct proc *p = td->td_proc;
1116151576Sdavidxu	struct itimer *it;
1117151576Sdavidxu	int id;
1118151576Sdavidxu	int error;
1119151576Sdavidxu
1120151576Sdavidxu	if (clock_id < 0 || clock_id >= MAX_CLOCKS)
1121151576Sdavidxu		return (EINVAL);
1122151576Sdavidxu
1123151576Sdavidxu	if (posix_clocks[clock_id].timer_create == NULL)
1124151576Sdavidxu		return (EINVAL);
1125151576Sdavidxu
1126151576Sdavidxu	if (evp != NULL) {
1127151576Sdavidxu		if (evp->sigev_notify != SIGEV_NONE &&
1128151869Sdavidxu		    evp->sigev_notify != SIGEV_SIGNAL &&
1129151869Sdavidxu		    evp->sigev_notify != SIGEV_THREAD_ID)
1130151576Sdavidxu			return (EINVAL);
1131151869Sdavidxu		if ((evp->sigev_notify == SIGEV_SIGNAL ||
1132151869Sdavidxu		     evp->sigev_notify == SIGEV_THREAD_ID) &&
1133151576Sdavidxu			!_SIG_VALID(evp->sigev_signo))
1134151576Sdavidxu			return (EINVAL);
1135151576Sdavidxu	}
1136151576Sdavidxu
1137151585Sdavidxu	if (p->p_itimers == NULL)
1138151576Sdavidxu		itimers_alloc(p);
1139151576Sdavidxu
1140151576Sdavidxu	it = uma_zalloc(itimer_zone, M_WAITOK);
1141151576Sdavidxu	it->it_flags = 0;
1142151576Sdavidxu	it->it_usecount = 0;
1143151576Sdavidxu	it->it_active = 0;
1144151869Sdavidxu	timespecclear(&it->it_time.it_value);
1145151869Sdavidxu	timespecclear(&it->it_time.it_interval);
1146151576Sdavidxu	it->it_overrun = 0;
1147151576Sdavidxu	it->it_overrun_last = 0;
1148151576Sdavidxu	it->it_clockid = clock_id;
1149151576Sdavidxu	it->it_timerid = -1;
1150151576Sdavidxu	it->it_proc = p;
1151151576Sdavidxu	ksiginfo_init(&it->it_ksi);
1152151576Sdavidxu	it->it_ksi.ksi_flags |= KSI_INS | KSI_EXT;
1153151576Sdavidxu	error = CLOCK_CALL(clock_id, timer_create, (it));
1154151576Sdavidxu	if (error != 0)
1155151576Sdavidxu		goto out;
1156151576Sdavidxu
1157151576Sdavidxu	PROC_LOCK(p);
1158151576Sdavidxu	if (preset_id != -1) {
1159151576Sdavidxu		KASSERT(preset_id >= 0 && preset_id < 3, ("invalid preset_id"));
1160151576Sdavidxu		id = preset_id;
1161151585Sdavidxu		if (p->p_itimers->its_timers[id] != NULL) {
1162151576Sdavidxu			PROC_UNLOCK(p);
1163151576Sdavidxu			error = 0;
1164151576Sdavidxu			goto out;
1165151576Sdavidxu		}
1166151576Sdavidxu	} else {
1167151576Sdavidxu		/*
1168151576Sdavidxu		 * Find a free timer slot, skipping those reserved
1169151576Sdavidxu		 * for setitimer().
1170151576Sdavidxu		 */
1171151576Sdavidxu		for (id = 3; id < TIMER_MAX; id++)
1172151585Sdavidxu			if (p->p_itimers->its_timers[id] == NULL)
1173151576Sdavidxu				break;
1174151576Sdavidxu		if (id == TIMER_MAX) {
1175151576Sdavidxu			PROC_UNLOCK(p);
1176151576Sdavidxu			error = EAGAIN;
1177151576Sdavidxu			goto out;
1178151576Sdavidxu		}
1179151576Sdavidxu	}
1180151576Sdavidxu	it->it_timerid = id;
1181151585Sdavidxu	p->p_itimers->its_timers[id] = it;
1182151576Sdavidxu	if (evp != NULL)
1183151576Sdavidxu		it->it_sigev = *evp;
1184151576Sdavidxu	else {
1185151576Sdavidxu		it->it_sigev.sigev_notify = SIGEV_SIGNAL;
1186151576Sdavidxu		switch (clock_id) {
1187151576Sdavidxu		default:
1188151576Sdavidxu		case CLOCK_REALTIME:
1189151576Sdavidxu			it->it_sigev.sigev_signo = SIGALRM;
1190151576Sdavidxu			break;
1191151576Sdavidxu		case CLOCK_VIRTUAL:
1192151576Sdavidxu 			it->it_sigev.sigev_signo = SIGVTALRM;
1193151576Sdavidxu			break;
1194151576Sdavidxu		case CLOCK_PROF:
1195151576Sdavidxu			it->it_sigev.sigev_signo = SIGPROF;
1196151576Sdavidxu			break;
1197151576Sdavidxu		}
1198152029Sdavidxu		it->it_sigev.sigev_value.sival_int = id;
1199151576Sdavidxu	}
1200151576Sdavidxu
1201151869Sdavidxu	if (it->it_sigev.sigev_notify == SIGEV_SIGNAL ||
1202151869Sdavidxu	    it->it_sigev.sigev_notify == SIGEV_THREAD_ID) {
1203151576Sdavidxu		it->it_ksi.ksi_signo = it->it_sigev.sigev_signo;
1204151576Sdavidxu		it->it_ksi.ksi_code = SI_TIMER;
1205151576Sdavidxu		it->it_ksi.ksi_value = it->it_sigev.sigev_value;
1206151576Sdavidxu		it->it_ksi.ksi_timerid = id;
1207151576Sdavidxu	}
1208151576Sdavidxu	PROC_UNLOCK(p);
1209151576Sdavidxu	*timerid = id;
1210151576Sdavidxu	return (0);
1211151576Sdavidxu
1212151576Sdavidxuout:
1213151576Sdavidxu	ITIMER_LOCK(it);
1214151576Sdavidxu	CLOCK_CALL(it->it_clockid, timer_delete, (it));
1215151576Sdavidxu	ITIMER_UNLOCK(it);
1216151576Sdavidxu	uma_zfree(itimer_zone, it);
1217151576Sdavidxu	return (error);
1218151576Sdavidxu}
1219151576Sdavidxu
1220151576Sdavidxu#ifndef _SYS_SYSPROTO_H_
1221156134Sdavidxustruct ktimer_delete_args {
1222156134Sdavidxu	int timerid;
1223151576Sdavidxu};
1224151576Sdavidxu#endif
1225151576Sdavidxuint
1226225617Skmacysys_ktimer_delete(struct thread *td, struct ktimer_delete_args *uap)
1227151576Sdavidxu{
1228253530Skib
1229253530Skib	return (kern_ktimer_delete(td, uap->timerid));
1230151576Sdavidxu}
1231151576Sdavidxu
1232151576Sdavidxustatic struct itimer *
1233164713Sdavidxuitimer_find(struct proc *p, int timerid)
1234151576Sdavidxu{
1235151576Sdavidxu	struct itimer *it;
1236151576Sdavidxu
1237151576Sdavidxu	PROC_LOCK_ASSERT(p, MA_OWNED);
1238190301Scperciva	if ((p->p_itimers == NULL) ||
1239190301Scperciva	    (timerid < 0) || (timerid >= TIMER_MAX) ||
1240151585Sdavidxu	    (it = p->p_itimers->its_timers[timerid]) == NULL) {
1241151576Sdavidxu		return (NULL);
1242151576Sdavidxu	}
1243151576Sdavidxu	ITIMER_LOCK(it);
1244164713Sdavidxu	if ((it->it_flags & ITF_DELETING) != 0) {
1245151576Sdavidxu		ITIMER_UNLOCK(it);
1246151576Sdavidxu		it = NULL;
1247151576Sdavidxu	}
1248151576Sdavidxu	return (it);
1249151576Sdavidxu}
1250151576Sdavidxu
1251253530Skibint
1252253530Skibkern_ktimer_delete(struct thread *td, int timerid)
1253151576Sdavidxu{
1254151576Sdavidxu	struct proc *p = td->td_proc;
1255151576Sdavidxu	struct itimer *it;
1256151576Sdavidxu
1257151576Sdavidxu	PROC_LOCK(p);
1258164713Sdavidxu	it = itimer_find(p, timerid);
1259151576Sdavidxu	if (it == NULL) {
1260151576Sdavidxu		PROC_UNLOCK(p);
1261151576Sdavidxu		return (EINVAL);
1262151576Sdavidxu	}
1263151576Sdavidxu	PROC_UNLOCK(p);
1264151576Sdavidxu
1265151576Sdavidxu	it->it_flags |= ITF_DELETING;
1266151576Sdavidxu	while (it->it_usecount > 0) {
1267151576Sdavidxu		it->it_flags |= ITF_WANTED;
1268151576Sdavidxu		msleep(it, &it->it_mtx, PPAUSE, "itimer", 0);
1269151576Sdavidxu	}
1270151576Sdavidxu	it->it_flags &= ~ITF_WANTED;
1271151576Sdavidxu	CLOCK_CALL(it->it_clockid, timer_delete, (it));
1272151576Sdavidxu	ITIMER_UNLOCK(it);
1273151576Sdavidxu
1274151576Sdavidxu	PROC_LOCK(p);
1275151576Sdavidxu	if (KSI_ONQ(&it->it_ksi))
1276151576Sdavidxu		sigqueue_take(&it->it_ksi);
1277151585Sdavidxu	p->p_itimers->its_timers[timerid] = NULL;
1278151576Sdavidxu	PROC_UNLOCK(p);
1279151576Sdavidxu	uma_zfree(itimer_zone, it);
1280151576Sdavidxu	return (0);
1281151576Sdavidxu}
1282151576Sdavidxu
1283151576Sdavidxu#ifndef _SYS_SYSPROTO_H_
1284156134Sdavidxustruct ktimer_settime_args {
1285156134Sdavidxu	int timerid;
1286151576Sdavidxu	int flags;
1287151576Sdavidxu	const struct itimerspec * value;
1288151576Sdavidxu	struct itimerspec * ovalue;
1289151576Sdavidxu};
1290151576Sdavidxu#endif
1291151576Sdavidxuint
1292225617Skmacysys_ktimer_settime(struct thread *td, struct ktimer_settime_args *uap)
1293151576Sdavidxu{
1294151576Sdavidxu	struct itimerspec val, oval, *ovalp;
1295151576Sdavidxu	int error;
1296151576Sdavidxu
1297151576Sdavidxu	error = copyin(uap->value, &val, sizeof(val));
1298151576Sdavidxu	if (error != 0)
1299151576Sdavidxu		return (error);
1300253530Skib	ovalp = uap->ovalue != NULL ? &oval : NULL;
1301253530Skib	error = kern_ktimer_settime(td, uap->timerid, uap->flags, &val, ovalp);
1302253530Skib	if (error == 0 && uap->ovalue != NULL)
1303253530Skib		error = copyout(ovalp, uap->ovalue, sizeof(*ovalp));
1304253530Skib	return (error);
1305253530Skib}
1306151576Sdavidxu
1307253530Skibint
1308253530Skibkern_ktimer_settime(struct thread *td, int timer_id, int flags,
1309253530Skib    struct itimerspec *val, struct itimerspec *oval)
1310253530Skib{
1311253530Skib	struct proc *p;
1312253530Skib	struct itimer *it;
1313253530Skib	int error;
1314253530Skib
1315253530Skib	p = td->td_proc;
1316151576Sdavidxu	PROC_LOCK(p);
1317253530Skib	if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) {
1318151576Sdavidxu		PROC_UNLOCK(p);
1319151576Sdavidxu		error = EINVAL;
1320151576Sdavidxu	} else {
1321151576Sdavidxu		PROC_UNLOCK(p);
1322151576Sdavidxu		itimer_enter(it);
1323253530Skib		error = CLOCK_CALL(it->it_clockid, timer_settime, (it,
1324253530Skib		    flags, val, oval));
1325151576Sdavidxu		itimer_leave(it);
1326151576Sdavidxu		ITIMER_UNLOCK(it);
1327151576Sdavidxu	}
1328151576Sdavidxu	return (error);
1329151576Sdavidxu}
1330151576Sdavidxu
1331151576Sdavidxu#ifndef _SYS_SYSPROTO_H_
1332156134Sdavidxustruct ktimer_gettime_args {
1333156134Sdavidxu	int timerid;
1334151576Sdavidxu	struct itimerspec * value;
1335151576Sdavidxu};
1336151576Sdavidxu#endif
1337151576Sdavidxuint
1338225617Skmacysys_ktimer_gettime(struct thread *td, struct ktimer_gettime_args *uap)
1339151576Sdavidxu{
1340151576Sdavidxu	struct itimerspec val;
1341151576Sdavidxu	int error;
1342151576Sdavidxu
1343253530Skib	error = kern_ktimer_gettime(td, uap->timerid, &val);
1344253530Skib	if (error == 0)
1345253530Skib		error = copyout(&val, uap->value, sizeof(val));
1346253530Skib	return (error);
1347253530Skib}
1348253530Skib
1349253530Skibint
1350253530Skibkern_ktimer_gettime(struct thread *td, int timer_id, struct itimerspec *val)
1351253530Skib{
1352253530Skib	struct proc *p;
1353253530Skib	struct itimer *it;
1354253530Skib	int error;
1355253530Skib
1356253530Skib	p = td->td_proc;
1357151576Sdavidxu	PROC_LOCK(p);
1358253530Skib	if (timer_id < 3 || (it = itimer_find(p, timer_id)) == NULL) {
1359151576Sdavidxu		PROC_UNLOCK(p);
1360151576Sdavidxu		error = EINVAL;
1361151576Sdavidxu	} else {
1362151576Sdavidxu		PROC_UNLOCK(p);
1363151576Sdavidxu		itimer_enter(it);
1364253530Skib		error = CLOCK_CALL(it->it_clockid, timer_gettime, (it, val));
1365151576Sdavidxu		itimer_leave(it);
1366151576Sdavidxu		ITIMER_UNLOCK(it);
1367151576Sdavidxu	}
1368151576Sdavidxu	return (error);
1369151576Sdavidxu}
1370151576Sdavidxu
1371151576Sdavidxu#ifndef _SYS_SYSPROTO_H_
1372151576Sdavidxustruct timer_getoverrun_args {
1373156134Sdavidxu	int timerid;
1374151576Sdavidxu};
1375151576Sdavidxu#endif
1376151576Sdavidxuint
1377225617Skmacysys_ktimer_getoverrun(struct thread *td, struct ktimer_getoverrun_args *uap)
1378151576Sdavidxu{
1379270042Sbz
1380270042Sbz	return (kern_ktimer_getoverrun(td, uap->timerid));
1381270042Sbz}
1382270042Sbz
1383270042Sbzint
1384270042Sbzkern_ktimer_getoverrun(struct thread *td, int timer_id)
1385270042Sbz{
1386151576Sdavidxu	struct proc *p = td->td_proc;
1387151576Sdavidxu	struct itimer *it;
1388151576Sdavidxu	int error ;
1389151576Sdavidxu
1390151576Sdavidxu	PROC_LOCK(p);
1391270042Sbz	if (timer_id < 3 ||
1392270042Sbz	    (it = itimer_find(p, timer_id)) == NULL) {
1393151576Sdavidxu		PROC_UNLOCK(p);
1394151576Sdavidxu		error = EINVAL;
1395151576Sdavidxu	} else {
1396151576Sdavidxu		td->td_retval[0] = it->it_overrun_last;
1397151576Sdavidxu		ITIMER_UNLOCK(it);
1398151869Sdavidxu		PROC_UNLOCK(p);
1399151576Sdavidxu		error = 0;
1400151576Sdavidxu	}
1401151576Sdavidxu	return (error);
1402151576Sdavidxu}
1403151576Sdavidxu
1404151576Sdavidxustatic int
1405151576Sdavidxurealtimer_create(struct itimer *it)
1406151576Sdavidxu{
1407151576Sdavidxu	callout_init_mtx(&it->it_callout, &it->it_mtx, 0);
1408151576Sdavidxu	return (0);
1409151576Sdavidxu}
1410151576Sdavidxu
1411151576Sdavidxustatic int
1412151576Sdavidxurealtimer_delete(struct itimer *it)
1413151576Sdavidxu{
1414151576Sdavidxu	mtx_assert(&it->it_mtx, MA_OWNED);
1415164713Sdavidxu
1416184067Sdavidxu	/*
1417184067Sdavidxu	 * clear timer's value and interval to tell realtimer_expire
1418184067Sdavidxu	 * to not rearm the timer.
1419184067Sdavidxu	 */
1420184067Sdavidxu	timespecclear(&it->it_time.it_value);
1421184067Sdavidxu	timespecclear(&it->it_time.it_interval);
1422164713Sdavidxu	ITIMER_UNLOCK(it);
1423164713Sdavidxu	callout_drain(&it->it_callout);
1424164713Sdavidxu	ITIMER_LOCK(it);
1425151576Sdavidxu	return (0);
1426151576Sdavidxu}
1427151576Sdavidxu
1428151576Sdavidxustatic int
1429151576Sdavidxurealtimer_gettime(struct itimer *it, struct itimerspec *ovalue)
1430151576Sdavidxu{
1431151869Sdavidxu	struct timespec cts;
1432151576Sdavidxu
1433151576Sdavidxu	mtx_assert(&it->it_mtx, MA_OWNED);
1434151576Sdavidxu
1435151869Sdavidxu	realtimer_clocktime(it->it_clockid, &cts);
1436151869Sdavidxu	*ovalue = it->it_time;
1437151576Sdavidxu	if (ovalue->it_value.tv_sec != 0 || ovalue->it_value.tv_nsec != 0) {
1438151869Sdavidxu		timespecsub(&ovalue->it_value, &cts);
1439151576Sdavidxu		if (ovalue->it_value.tv_sec < 0 ||
1440151576Sdavidxu		    (ovalue->it_value.tv_sec == 0 &&
1441151576Sdavidxu		     ovalue->it_value.tv_nsec == 0)) {
1442151576Sdavidxu			ovalue->it_value.tv_sec  = 0;
1443151576Sdavidxu			ovalue->it_value.tv_nsec = 1;
1444151576Sdavidxu		}
1445151576Sdavidxu	}
1446151576Sdavidxu	return (0);
1447151576Sdavidxu}
1448151576Sdavidxu
1449151576Sdavidxustatic int
1450151576Sdavidxurealtimer_settime(struct itimer *it, int flags,
1451151576Sdavidxu	struct itimerspec *value, struct itimerspec *ovalue)
1452151576Sdavidxu{
1453151869Sdavidxu	struct timespec cts, ts;
1454151869Sdavidxu	struct timeval tv;
1455151869Sdavidxu	struct itimerspec val;
1456151576Sdavidxu
1457151576Sdavidxu	mtx_assert(&it->it_mtx, MA_OWNED);
1458151576Sdavidxu
1459151869Sdavidxu	val = *value;
1460151869Sdavidxu	if (itimespecfix(&val.it_value))
1461151576Sdavidxu		return (EINVAL);
1462151576Sdavidxu
1463151869Sdavidxu	if (timespecisset(&val.it_value)) {
1464151869Sdavidxu		if (itimespecfix(&val.it_interval))
1465151576Sdavidxu			return (EINVAL);
1466151576Sdavidxu	} else {
1467151869Sdavidxu		timespecclear(&val.it_interval);
1468151576Sdavidxu	}
1469151576Sdavidxu
1470151576Sdavidxu	if (ovalue != NULL)
1471151576Sdavidxu		realtimer_gettime(it, ovalue);
1472151576Sdavidxu
1473151576Sdavidxu	it->it_time = val;
1474151869Sdavidxu	if (timespecisset(&val.it_value)) {
1475151869Sdavidxu		realtimer_clocktime(it->it_clockid, &cts);
1476151869Sdavidxu		ts = val.it_value;
1477151576Sdavidxu		if ((flags & TIMER_ABSTIME) == 0) {
1478151576Sdavidxu			/* Convert to absolute time. */
1479151869Sdavidxu			timespecadd(&it->it_time.it_value, &cts);
1480151576Sdavidxu		} else {
1481151869Sdavidxu			timespecsub(&ts, &cts);
1482151576Sdavidxu			/*
1483151869Sdavidxu			 * We don't care if ts is negative, tztohz will
1484151576Sdavidxu			 * fix it.
1485151576Sdavidxu			 */
1486151576Sdavidxu		}
1487151869Sdavidxu		TIMESPEC_TO_TIMEVAL(&tv, &ts);
1488151869Sdavidxu		callout_reset(&it->it_callout, tvtohz(&tv),
1489151576Sdavidxu			realtimer_expire, it);
1490151576Sdavidxu	} else {
1491151576Sdavidxu		callout_stop(&it->it_callout);
1492151576Sdavidxu	}
1493151576Sdavidxu
1494151576Sdavidxu	return (0);
1495151576Sdavidxu}
1496151576Sdavidxu
1497151576Sdavidxustatic void
1498151869Sdavidxurealtimer_clocktime(clockid_t id, struct timespec *ts)
1499151576Sdavidxu{
1500151576Sdavidxu	if (id == CLOCK_REALTIME)
1501151869Sdavidxu		getnanotime(ts);
1502151576Sdavidxu	else	/* CLOCK_MONOTONIC */
1503151869Sdavidxu		getnanouptime(ts);
1504151576Sdavidxu}
1505151576Sdavidxu
1506151869Sdavidxuint
1507156134Sdavidxuitimer_accept(struct proc *p, int timerid, ksiginfo_t *ksi)
1508151869Sdavidxu{
1509151869Sdavidxu	struct itimer *it;
1510151869Sdavidxu
1511151869Sdavidxu	PROC_LOCK_ASSERT(p, MA_OWNED);
1512164713Sdavidxu	it = itimer_find(p, timerid);
1513151869Sdavidxu	if (it != NULL) {
1514151869Sdavidxu		ksi->ksi_overrun = it->it_overrun;
1515151869Sdavidxu		it->it_overrun_last = it->it_overrun;
1516151869Sdavidxu		it->it_overrun = 0;
1517151869Sdavidxu		ITIMER_UNLOCK(it);
1518151869Sdavidxu		return (0);
1519151869Sdavidxu	}
1520151869Sdavidxu	return (EINVAL);
1521151869Sdavidxu}
1522151869Sdavidxu
1523151869Sdavidxuint
1524151869Sdavidxuitimespecfix(struct timespec *ts)
1525151869Sdavidxu{
1526151869Sdavidxu
1527151869Sdavidxu	if (ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000)
1528151869Sdavidxu		return (EINVAL);
1529151869Sdavidxu	if (ts->tv_sec == 0 && ts->tv_nsec != 0 && ts->tv_nsec < tick * 1000)
1530151869Sdavidxu		ts->tv_nsec = tick * 1000;
1531151869Sdavidxu	return (0);
1532151869Sdavidxu}
1533151869Sdavidxu
1534151576Sdavidxu/* Timeout callback for realtime timer */
1535151576Sdavidxustatic void
1536151576Sdavidxurealtimer_expire(void *arg)
1537151576Sdavidxu{
1538151869Sdavidxu	struct timespec cts, ts;
1539151869Sdavidxu	struct timeval tv;
1540151576Sdavidxu	struct itimer *it;
1541151576Sdavidxu
1542151576Sdavidxu	it = (struct itimer *)arg;
1543151576Sdavidxu
1544151869Sdavidxu	realtimer_clocktime(it->it_clockid, &cts);
1545151576Sdavidxu	/* Only fire if time is reached. */
1546151869Sdavidxu	if (timespeccmp(&cts, &it->it_time.it_value, >=)) {
1547151869Sdavidxu		if (timespecisset(&it->it_time.it_interval)) {
1548151869Sdavidxu			timespecadd(&it->it_time.it_value,
1549151869Sdavidxu				    &it->it_time.it_interval);
1550151869Sdavidxu			while (timespeccmp(&cts, &it->it_time.it_value, >=)) {
1551152983Sdavidxu				if (it->it_overrun < INT_MAX)
1552152983Sdavidxu					it->it_overrun++;
1553152983Sdavidxu				else
1554152983Sdavidxu					it->it_ksi.ksi_errno = ERANGE;
1555151869Sdavidxu				timespecadd(&it->it_time.it_value,
1556151869Sdavidxu					    &it->it_time.it_interval);
1557151576Sdavidxu			}
1558151576Sdavidxu		} else {
1559151576Sdavidxu			/* single shot timer ? */
1560151869Sdavidxu			timespecclear(&it->it_time.it_value);
1561151576Sdavidxu		}
1562151869Sdavidxu		if (timespecisset(&it->it_time.it_value)) {
1563151869Sdavidxu			ts = it->it_time.it_value;
1564151869Sdavidxu			timespecsub(&ts, &cts);
1565151869Sdavidxu			TIMESPEC_TO_TIMEVAL(&tv, &ts);
1566151869Sdavidxu			callout_reset(&it->it_callout, tvtohz(&tv),
1567151576Sdavidxu				 realtimer_expire, it);
1568151576Sdavidxu		}
1569184067Sdavidxu		itimer_enter(it);
1570151576Sdavidxu		ITIMER_UNLOCK(it);
1571151576Sdavidxu		itimer_fire(it);
1572151576Sdavidxu		ITIMER_LOCK(it);
1573184067Sdavidxu		itimer_leave(it);
1574151869Sdavidxu	} else if (timespecisset(&it->it_time.it_value)) {
1575151869Sdavidxu		ts = it->it_time.it_value;
1576151869Sdavidxu		timespecsub(&ts, &cts);
1577151869Sdavidxu		TIMESPEC_TO_TIMEVAL(&tv, &ts);
1578151869Sdavidxu		callout_reset(&it->it_callout, tvtohz(&tv), realtimer_expire,
1579151576Sdavidxu 			it);
1580151576Sdavidxu	}
1581151576Sdavidxu}
1582151576Sdavidxu
1583151576Sdavidxuvoid
1584151576Sdavidxuitimer_fire(struct itimer *it)
1585151576Sdavidxu{
1586151576Sdavidxu	struct proc *p = it->it_proc;
1587213642Sdavidxu	struct thread *td;
1588151576Sdavidxu
1589151869Sdavidxu	if (it->it_sigev.sigev_notify == SIGEV_SIGNAL ||
1590151869Sdavidxu	    it->it_sigev.sigev_notify == SIGEV_THREAD_ID) {
1591213642Sdavidxu		if (sigev_findtd(p, &it->it_sigev, &td) != 0) {
1592213642Sdavidxu			ITIMER_LOCK(it);
1593213642Sdavidxu			timespecclear(&it->it_time.it_value);
1594213642Sdavidxu			timespecclear(&it->it_time.it_interval);
1595213642Sdavidxu			callout_stop(&it->it_callout);
1596213642Sdavidxu			ITIMER_UNLOCK(it);
1597213642Sdavidxu			return;
1598213642Sdavidxu		}
1599151993Sdavidxu		if (!KSI_ONQ(&it->it_ksi)) {
1600152983Sdavidxu			it->it_ksi.ksi_errno = 0;
1601213642Sdavidxu			ksiginfo_set_sigev(&it->it_ksi, &it->it_sigev);
1602213642Sdavidxu			tdsendsignal(p, td, it->it_ksi.ksi_signo, &it->it_ksi);
1603151993Sdavidxu		} else {
1604152983Sdavidxu			if (it->it_overrun < INT_MAX)
1605152983Sdavidxu				it->it_overrun++;
1606152983Sdavidxu			else
1607152983Sdavidxu				it->it_ksi.ksi_errno = ERANGE;
1608151576Sdavidxu		}
1609151576Sdavidxu		PROC_UNLOCK(p);
1610151576Sdavidxu	}
1611151576Sdavidxu}
1612151576Sdavidxu
1613151576Sdavidxustatic void
1614151576Sdavidxuitimers_alloc(struct proc *p)
1615151576Sdavidxu{
1616151585Sdavidxu	struct itimers *its;
1617151585Sdavidxu	int i;
1618151576Sdavidxu
1619151585Sdavidxu	its = malloc(sizeof (struct itimers), M_SUBPROC, M_WAITOK | M_ZERO);
1620151585Sdavidxu	LIST_INIT(&its->its_virtual);
1621151585Sdavidxu	LIST_INIT(&its->its_prof);
1622151585Sdavidxu	TAILQ_INIT(&its->its_worklist);
1623151585Sdavidxu	for (i = 0; i < TIMER_MAX; i++)
1624151585Sdavidxu		its->its_timers[i] = NULL;
1625151576Sdavidxu	PROC_LOCK(p);
1626151585Sdavidxu	if (p->p_itimers == NULL) {
1627151585Sdavidxu		p->p_itimers = its;
1628151576Sdavidxu		PROC_UNLOCK(p);
1629151585Sdavidxu	}
1630151585Sdavidxu	else {
1631151576Sdavidxu		PROC_UNLOCK(p);
1632151585Sdavidxu		free(its, M_SUBPROC);
1633151576Sdavidxu	}
1634151576Sdavidxu}
1635151576Sdavidxu
1636161302Snetchildstatic void
1637161302Snetchilditimers_event_hook_exec(void *arg, struct proc *p, struct image_params *imgp __unused)
1638161302Snetchild{
1639164713Sdavidxu	itimers_event_hook_exit(arg, p);
1640161302Snetchild}
1641161302Snetchild
1642151576Sdavidxu/* Clean up timers when some process events are being triggered. */
1643153259Sdavidxustatic void
1644161302Snetchilditimers_event_hook_exit(void *arg, struct proc *p)
1645151576Sdavidxu{
1646151576Sdavidxu	struct itimers *its;
1647151576Sdavidxu	struct itimer *it;
1648153267Sdavidxu	int event = (int)(intptr_t)arg;
1649151576Sdavidxu	int i;
1650151576Sdavidxu
1651151585Sdavidxu	if (p->p_itimers != NULL) {
1652151585Sdavidxu		its = p->p_itimers;
1653151576Sdavidxu		for (i = 0; i < MAX_CLOCKS; ++i) {
1654151576Sdavidxu			if (posix_clocks[i].event_hook != NULL)
1655151576Sdavidxu				CLOCK_CALL(i, event_hook, (p, i, event));
1656151576Sdavidxu		}
1657151576Sdavidxu		/*
1658151576Sdavidxu		 * According to susv3, XSI interval timers should be inherited
1659151576Sdavidxu		 * by new image.
1660151576Sdavidxu		 */
1661151576Sdavidxu		if (event == ITIMER_EV_EXEC)
1662151576Sdavidxu			i = 3;
1663151576Sdavidxu		else if (event == ITIMER_EV_EXIT)
1664151576Sdavidxu			i = 0;
1665151576Sdavidxu		else
1666151576Sdavidxu			panic("unhandled event");
1667151576Sdavidxu		for (; i < TIMER_MAX; ++i) {
1668164713Sdavidxu			if ((it = its->its_timers[i]) != NULL)
1669253530Skib				kern_ktimer_delete(curthread, i);
1670151576Sdavidxu		}
1671151576Sdavidxu		if (its->its_timers[0] == NULL &&
1672151576Sdavidxu		    its->its_timers[1] == NULL &&
1673151576Sdavidxu		    its->its_timers[2] == NULL) {
1674151585Sdavidxu			free(its, M_SUBPROC);
1675151585Sdavidxu			p->p_itimers = NULL;
1676151576Sdavidxu		}
1677151576Sdavidxu	}
1678151576Sdavidxu}
1679