xref: /csrg-svn/sys/kern/kern_time.c (revision 8114)
1*8114Sroot /*	kern_time.c	5.5	82/09/08	*/
27424Sroot 
37424Sroot #include "../h/param.h"
48034Sroot #include "../h/dir.h"		/* XXX */
57424Sroot #include "../h/user.h"
68034Sroot #include "../h/kernel.h"
77424Sroot #include "../h/reg.h"
87424Sroot #include "../h/inode.h"
97424Sroot #include "../h/proc.h"
107424Sroot 
118103Sroot /*
128103Sroot  * Time of day and interval timer support.
138103Sroot  */
148103Sroot 
158034Sroot gettimeofday()
167424Sroot {
178034Sroot 	register struct a {
188034Sroot 		struct	timeval *tp;
198034Sroot 		struct	timezone *tzp;
208034Sroot 	} *uap = (struct a *)u.u_ap;
218034Sroot 	struct timeval atv;
228103Sroot 	int s;
237500Sroot 
248103Sroot 	s = spl7(); atv = time; splx(s);
258034Sroot 	if (copyout((caddr_t)&atv, (caddr_t)uap->tp, sizeof (atv))) {
268034Sroot 		u.u_error = EFAULT;
278034Sroot 		return;
288034Sroot 	}
298034Sroot 	if (uap->tzp == 0)
308034Sroot 		return;
318103Sroot 	/* SHOULD HAVE PER-PROCESS TIMEZONE */
328034Sroot 	if (copyout((caddr_t)&tz, uap->tzp, sizeof (tz))) {
338034Sroot 		u.u_error = EFAULT;
348034Sroot 		return;
358034Sroot 	}
367500Sroot }
377500Sroot 
388034Sroot settimeofday()
397500Sroot {
408034Sroot 	register struct a {
418103Sroot 		struct	timeval *tv;
428103Sroot 		struct	timezone *tzp;
438034Sroot 	} *uap = (struct a *)u.u_ap;
448034Sroot 	struct timeval atv;
458034Sroot 	struct timezone atz;
467500Sroot 
478034Sroot 	if (copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (struct timeval))) {
488034Sroot 		u.u_error = EFAULT;
498034Sroot 		return;
508034Sroot 	}
518103Sroot 	setthetime(&atv);
528103Sroot 	if (uap->tzp && suser()) {
538034Sroot 		if (copyin((caddr_t)uap->tzp, (caddr_t)&atz, sizeof (atz))) {
548034Sroot 			u.u_error = EFAULT;
558034Sroot 			return;
568034Sroot 		}
578034Sroot 	}
587500Sroot }
597500Sroot 
608103Sroot setthetime(tv)
618103Sroot 	struct timeval *tv;
628103Sroot {
638103Sroot 	register int delta;
648103Sroot 	int s;
658103Sroot 
668103Sroot 	if (!suser())
678103Sroot 		return;
688103Sroot 	boottime.tv_sec += tv->tv_sec - time.tv_sec;
698103Sroot 	s = spl7(); time = *tv; splx(s);
708103Sroot 	clockset();
718103Sroot }
728103Sroot 
738034Sroot timevaladd(t1, t2)
748034Sroot 	struct timeval *t1, *t2;
757500Sroot {
767500Sroot 
778034Sroot 	t1->tv_sec += t2->tv_sec;
788103Sroot 	t1->tv_usec += t2->tv_usec;
798034Sroot 	timevalfix(t1);
807500Sroot }
817500Sroot 
828034Sroot timevalsub(t1, t2)
838034Sroot 	struct timeval *t1, *t2;
847500Sroot {
857500Sroot 
868034Sroot 	t1->tv_sec -= t2->tv_sec;
878103Sroot 	t1->tv_usec -= t2->tv_usec;
888034Sroot 	timevalfix(t1);
897424Sroot }
907424Sroot 
918034Sroot timevalfix(t1)
928034Sroot 	struct timeval *t1;
937424Sroot {
948034Sroot 
958034Sroot 	if (t1->tv_usec < 0) {
968034Sroot 		t1->tv_sec--;
978034Sroot 		t1->tv_usec += 1000000;
988034Sroot 	}
998034Sroot 	if (t1->tv_usec >= 1000000) {
1008034Sroot 		t1->tv_sec++;
1018034Sroot 		t1->tv_usec -= 1000000;
1028034Sroot 	}
1038034Sroot }
1048034Sroot 
1058034Sroot getitimer()
1068034Sroot {
1077424Sroot 	register struct a {
1088034Sroot 		u_int	which;
1098034Sroot 		struct	itimerval *itv;
1108034Sroot 	} *uap = (struct a *)u.u_ap;
111*8114Sroot 	struct itimerval aitv;
1128034Sroot 	int s;
1137424Sroot 
1148034Sroot 	if (uap->which > 2) {
1158034Sroot 		u.u_error = EINVAL;
1168034Sroot 		return;
1177424Sroot 	}
1188034Sroot 	s = spl7();
119*8114Sroot 	if (uap->which == ITIMER_REAL) {
120*8114Sroot 		aitv = u.u_procp->p_realtimer;
121*8114Sroot 		if (timerisset(&aitv.it_value))
122*8114Sroot 			if (timercmp(&aitv.it_value, &time, <))
123*8114Sroot 				timerclear(&aitv.it_value);
124*8114Sroot 			else
125*8114Sroot 				timevalsub(&aitv.it_value, &time);
126*8114Sroot 	} else
127*8114Sroot 		aitv = u.u_timer[uap->which];
128*8114Sroot 	splx(s);
129*8114Sroot 	if (copyout((caddr_t)&aitv, uap->itv, sizeof (struct itimerval)))
1307424Sroot 		u.u_error = EFAULT;
1318034Sroot 	splx(s);
1327424Sroot }
1337424Sroot 
1348034Sroot setitimer()
1357424Sroot {
1367424Sroot 	register struct a {
1378034Sroot 		u_int	which;
1388103Sroot 		struct	itimerval *itv, *oitv;
1398034Sroot 	} *uap = (struct a *)u.u_ap;
1408034Sroot 	struct itimerval aitv;
1418034Sroot 	int s;
142*8114Sroot 	register struct proc *p = u.u_procp;
1437424Sroot 
1448034Sroot 	if (uap->which > 2) {
1458034Sroot 		u.u_error = EINVAL;
1468103Sroot 		return;
1477424Sroot 	}
1488034Sroot 	if (copyin((caddr_t)uap->itv, (caddr_t)&aitv,
1498034Sroot 	    sizeof (struct itimerval))) {
1508034Sroot 		u.u_error = EFAULT;
1518103Sroot 		return;
1528034Sroot 	}
1538103Sroot 	if (uap->oitv) {
1548103Sroot 		uap->itv = uap->oitv;
1558103Sroot 		getitimer();
1568103Sroot 	}
1578103Sroot 	if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) {
1588103Sroot 		u.u_error = EINVAL;
1598103Sroot 		return;
1608103Sroot 	}
1618103Sroot 	s = spl7();
162*8114Sroot 	if (uap->which == ITIMER_REAL) {
163*8114Sroot 		untimeout(unrto, p);
164*8114Sroot 		if (timerisset(&aitv.it_value)) {
165*8114Sroot 			timevaladd(&aitv.it_value, &time);
166*8114Sroot 			timeout(unrto, p, hzto(&aitv.it_value));
167*8114Sroot 		}
168*8114Sroot 		p->p_realtimer = aitv;
169*8114Sroot 	} else
1708103Sroot 		u.u_timer[uap->which] = aitv;
1718034Sroot 	splx(s);
1727424Sroot }
1737424Sroot 
174*8114Sroot unrto(p)
175*8114Sroot 	register struct proc *p;
176*8114Sroot {
177*8114Sroot 	int s;
178*8114Sroot 
179*8114Sroot 	psignal(p, SIGALRM);
180*8114Sroot 	if (!timerisset(&p->p_realtimer.it_interval)) {
181*8114Sroot 		timerclear(&p->p_realtimer.it_value);
182*8114Sroot 		return;
183*8114Sroot 	}
184*8114Sroot 	for (;;) {
185*8114Sroot 		s = spl7();
186*8114Sroot 		timevaladd(&p->p_realtimer.it_value,
187*8114Sroot 		    &p->p_realtimer.it_interval);
188*8114Sroot 		if (timercmp(&p->p_realtimer.it_value, &time, >)) {
189*8114Sroot 			timeout(unrto, p, hzto(&p->p_realtimer.it_value));
190*8114Sroot 			splx(s);
191*8114Sroot 			return;
192*8114Sroot 		}
193*8114Sroot 		splx(s);
194*8114Sroot 	}
195*8114Sroot }
196*8114Sroot 
1978103Sroot itimerfix(tv)
1988103Sroot 	struct timeval *tv;
1997424Sroot {
2008034Sroot 
201*8114Sroot 	if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
202*8114Sroot 	    tv->tv_usec < 0 || tv->tv_usec >= 1000000)
2038103Sroot 		return (EINVAL);
2048103Sroot 	if (tv->tv_sec == 0 && tv->tv_usec < tick)
2058103Sroot 		tv->tv_usec = tick;
2068103Sroot 	return (0);
2078034Sroot }
2088034Sroot 
2098034Sroot itimerdecr(itp, usec)
2108034Sroot 	register struct itimerval *itp;
2118034Sroot 	int usec;
2128034Sroot {
2138034Sroot 
2148103Sroot 	if (itp->it_value.tv_usec < usec) {
2158103Sroot 		if (itp->it_value.tv_sec == 0) {
2168103Sroot 			usec -= itp->it_value.tv_usec;
2178034Sroot 			goto expire;
2188103Sroot 		}
2198103Sroot 		itp->it_value.tv_usec += 1000000;
2208103Sroot 		itp->it_value.tv_sec--;
2218034Sroot 	}
2228103Sroot 	itp->it_value.tv_usec -= usec;
2238103Sroot 	usec = 0;
2248103Sroot 	if (timerisset(&itp->it_value))
2258034Sroot 		return (1);
2268034Sroot expire:
2278103Sroot 	if (timerisset(&itp->it_interval)) {
2288103Sroot 		itp->it_value = itp->it_interval;
2298103Sroot 		itp->it_value.tv_usec -= usec;
2308103Sroot 		if (itp->it_value.tv_usec < 0) {
2318103Sroot 			itp->it_value.tv_usec += 1000000;
2328103Sroot 			itp->it_value.tv_sec--;
2338103Sroot 		}
2348103Sroot 	} else
2358103Sroot 		itp->it_value.tv_usec = 0;
2368034Sroot 	return (0);
2378034Sroot }
2388034Sroot 
2398034Sroot #ifndef NOCOMPAT
2408034Sroot otime()
2418034Sroot {
2428034Sroot 
2438034Sroot 	u.u_r.r_time = time.tv_sec;
2448034Sroot }
2458034Sroot 
2468103Sroot ostime()
2478103Sroot {
2488103Sroot 	register struct a {
2498103Sroot 		int	time;
2508103Sroot 	} *uap = (struct a *)u.u_ap;
2518103Sroot 	struct timeval tv;
2528103Sroot 
2538103Sroot 	tv.tv_sec = uap->time;
2548103Sroot 	tv.tv_usec = 0;
2558103Sroot 	setthetime(&tv);
2568103Sroot }
2578103Sroot 
2588034Sroot #include "../h/timeb.h"
2598034Sroot 
2608034Sroot oftime()
2618034Sroot {
2627424Sroot 	register struct a {
2638034Sroot 		struct	timeb	*tp;
2647424Sroot 	} *uap;
2658034Sroot 	struct timeb t;
2667424Sroot 
2677424Sroot 	uap = (struct a *)u.u_ap;
2688034Sroot 	(void) spl7();
2698034Sroot 	t.time = time.tv_sec;
2708034Sroot 	t.millitm = time.tv_usec / 1000;
2718034Sroot 	(void) spl0();
2728034Sroot 	t.timezone = tz.tz_minuteswest;
2738034Sroot 	t.dstflag = tz.tz_dsttime;
2748034Sroot 	if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t)) < 0)
2757424Sroot 		u.u_error = EFAULT;
2767424Sroot }
2778103Sroot #endif
278