# 2.11BSD#431 - /usr/src/sys/sys/kern_time.c

##### Functions

    adjtime           X
    getitimer         X
    gettimeofday      X
    itimerdecr        X
    itimerfix         X
    setitimer         X
    setthetime        X
    settimeofday      X
    timevaladd        X
    timevalfix        X
    timevalsub        X

##### Macros

    timevalfix        X

##### struct's

    a                 X

       1: /*
       2:  * Copyright (c) 1986 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  *
       6:  *	@(#)kern_time.c	1.5 (2.11BSD) 2000/4/9
       7:  */
       8:
       9: #include "param.h"
      10: #include "user.h"
      11: #include "proc.h"
      12: #include "kernel.h"
      13: #include "systm.h"
      14:
      15: /*
      16:  * Time of day and interval timer support.
      17:  *
      18:  * These routines provide the kernel entry points to get and set
      19:  * the time-of-day.
      20:  */
      21:
      22: gettimeofday()
      23: {
      24:     register struct a {
      25:         struct  timeval *tp;
      26:         struct  timezone *tzp;
      27:     } *uap = (struct a *)u.u_ap;
      28:     struct timeval atv;
      29:     int s;
      30:     register u_int  ms;
      31:
      32:     if (uap->tp) {
      33:         /*
      34: 		 * We don't resolve the milliseconds on every clock tick; it's
      35: 		 * easier to do it here.  Long casts are out of paranoia.
      36: 		 */
      37:         s = splhigh(); atv = time; ms = lbolt; splx(s);
      38:         atv.tv_usec = (long)ms * mshz;
      39:         u.u_error = copyout((caddr_t)&atv, (caddr_t)(uap->tp),
      40:             sizeof(atv));
      41:         if (u.u_error)
      42:             return;
      43:     }
      44:     if (uap->tzp)
      45:         u.u_error = copyout((caddr_t)&tz, (caddr_t)uap->tzp,
      46:             sizeof (tz));
      47: }
      48:
      49: settimeofday()
      50: {
      51:     register struct a {
      52:         struct  timeval *tv;
      53:         struct  timezone *tzp;
      54:     } *uap = (struct a *)u.u_ap;
      55:     struct timeval atv;
      56:     struct timezone atz;
      57:
      58:     if (uap->tv) {
      59:         u.u_error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
      60:             sizeof (struct timeval));
      61:         if (u.u_error)
      62:             return;
      63:         setthetime(&atv);
      64:         if  (u.u_error)
      65:             return;
      66:     }
      67:     if (uap->tzp && suser()) {
      68:         u.u_error = copyin((caddr_t)uap->tzp, (caddr_t)&atz,
      69:             sizeof (atz));
      70:         if (u.u_error == 0)
      71:             tz = atz;
      72:     }
      73: }
      74:
      75: setthetime(tv)
      76:     register struct timeval *tv;
      77:     {
      78:     int s;
      79:
      80:     if  (!suser())
      81:         return;
      82: #ifdef  NOTNOW
      83: /*
      84:  * If the system is secure, we do not allow the time to be set to an
      85:  * earlier value.  The time may be slowed (using adjtime) but not set back.
      86:  *
      87:  * NOTE:  Can not do this until ntpd is updated to deal with the coarse (50, 60
      88:  *	  hz) clocks.  Ntpd wants to adjust time system clock a few microseconds
      89:  *	  at a time (which gets rounded to 0 in adjtime below). If that fails
      90:  *	  ntpd uses settimeofday to step the time backwards which obviously
      91:  *	  will fail if the next 'if' is enabled - all that does is fill up the
      92:  *	  logfiles with "can't set time" messages and the time keeps drifting.
      93: */
      94:     if  (securelevel > 0 && timercmp(tv, &time, <))
      95:         {
      96:         u.u_error = EPERM;  /* XXX */
      97:         return;
      98:         }
      99: #endif
     100: /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
     101:     boottime.tv_sec += tv->tv_sec - time.tv_sec;
     102:     s = splhigh();
     103:     time = *tv; lbolt = time.tv_usec / mshz;
     104:     splx(s);
     105: #ifdef  notyet
     106:     /*
     107: 	 * if you have a time of day board, use it here
     108: 	 */
     109:     resettodr();
     110: #endif
     111:     }
     112:
     113: adjtime()
     114: {
     115:     register struct a {
     116:         struct timeval *delta;
     117:         struct timeval *olddelta;
     118:     } *uap = (struct a *)u.u_ap;
     119:     struct timeval atv;
     120:     register int s;
     121:     long adjust;
     122:
     123:     if (!suser())
     124:         return;
     125:     u.u_error = copyin((caddr_t)uap->delta, (caddr_t)&atv,
     126:         sizeof (struct timeval));
     127:     if (u.u_error)
     128:         return;
     129:     adjust = (atv.tv_sec * hz) + (atv.tv_usec / mshz);
     130:     /* if unstoreable values, just set the clock */
     131:     if (adjust > 0x7fff || adjust < 0x8000) {
     132:         s = splclock();
     133:         time.tv_sec += atv.tv_sec;
     134:         lbolt += atv.tv_usec / mshz;
     135:         while (lbolt >= hz) {
     136:             lbolt -= hz;
     137:             ++time.tv_sec;
     138:         }
     139:         splx(s);
     140:         if (!uap->olddelta)
     141:             return;
     142:         atv.tv_sec = atv.tv_usec = 0;
     143:     } else {
     144:         if (!uap->olddelta) {
     145:             adjdelta = adjust;
     146:             return;
     147:         }
     148:         atv.tv_sec = adjdelta / hz;
     149:         atv.tv_usec = (adjdelta % hz) * mshz;
     150:         adjdelta = adjust;
     151:     }
     152:     (void) copyout((caddr_t)&atv, (caddr_t)uap->olddelta,
     153:         sizeof (struct timeval));
     154: }
     155:
     156: getitimer()
     157: {
     158:     register struct a {
     159:         u_int   which;
     160:         struct  itimerval *itv;
     161:     } *uap = (struct a *)u.u_ap;
     162:     struct itimerval aitv;
     163:     register int s;
     164:
     165:     if (uap->which > ITIMER_PROF) {
     166:         u.u_error = EINVAL;
     167:         return;
     168:     }
     169:     aitv.it_interval.tv_usec = 0;
     170:     aitv.it_value.tv_usec = 0;
     171:     s = splclock();
     172:     if (uap->which == ITIMER_REAL) {
     173:         register struct proc *p = u.u_procp;
     174:
     175:         aitv.it_interval.tv_sec = p->p_realtimer.it_interval;
     176:         aitv.it_value.tv_sec = p->p_realtimer.it_value;
     177:     }
     178:     else {
     179:         register struct k_itimerval *t = &u.u_timer[uap->which - 1];
     180:
     181:         aitv.it_interval.tv_sec = t->it_interval / hz;
     182:         aitv.it_value.tv_sec = t->it_value / hz;
     183:     }
     184:     splx(s);
     185:     u.u_error = copyout((caddr_t)&aitv, (caddr_t)uap->itv,
     186:         sizeof (struct itimerval));
     187: }
     188:
     189: setitimer()
     190: {
     191:     register struct a {
     192:         u_int   which;
     193:         struct  itimerval *itv, *oitv;
     194:     } *uap = (struct a *)u.u_ap;
     195:     struct itimerval aitv;
     196:     register struct itimerval *aitvp;
     197:     int s;
     198:
     199:     if (uap->which > ITIMER_PROF) {
     200:         u.u_error = EINVAL;
     201:         return;
     202:     }
     203:     aitvp = uap->itv;
     204:     if (uap->oitv) {
     205:         uap->itv = uap->oitv;
     206:         getitimer();
     207:     }
     208:     if (aitvp == 0)
     209:         return;
     210:     u.u_error = copyin((caddr_t)aitvp, (caddr_t)&aitv,
     211:         sizeof (struct itimerval));
     212:     if (u.u_error)
     213:         return;
     214:     s = splclock();
     215:     if (uap->which == ITIMER_REAL) {
     216:         register struct proc *p = u.u_procp;
     217:
     218:         p->p_realtimer.it_value = aitv.it_value.tv_sec;
     219:         if (aitv.it_value.tv_usec)
     220:             ++p->p_realtimer.it_value;
     221:         p->p_realtimer.it_interval = aitv.it_interval.tv_sec;
     222:         if (aitv.it_interval.tv_usec)
     223:             ++p->p_realtimer.it_interval;
     224:     }
     225:     else {
     226:         register struct k_itimerval *t = &u.u_timer[uap->which - 1];
     227:
     228:         t->it_value = aitv.it_value.tv_sec * hz;
     229:         if (aitv.it_value.tv_usec)
     230:             t->it_value += hz;
     231:         t->it_interval = aitv.it_interval.tv_sec * hz;
     232:         if (aitv.it_interval.tv_usec)
     233:             t->it_interval += hz;
     234:     }
     235:     splx(s);
     236: }
     237:
     238: /*
     239:  * Check that a proposed value to load into the .it_value or
     240:  * .it_interval part of an interval timer is acceptable, and
     241:  * fix it to have at least minimal value (i.e. if it is less
     242:  * than the resolution of the clock, round it up.)
     243:  */
     244: itimerfix(tv)
     245:     struct timeval *tv;
     246: {
     247:
     248:     if (tv->tv_sec < 0 || tv->tv_sec > 100000000L ||
     249:         tv->tv_usec < 0 || tv->tv_usec >= 1000000L)
     250:         return (EINVAL);
     251:     if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < (1000/hz))
     252:         tv->tv_usec = 1000/hz;
     253:     return (0);
     254: }
     255:
     256: #ifdef NOT_CURRENTLY_IN_USE
     257: /*
     258:  * Decrement an interval timer by a specified number
     259:  * of microseconds, which must be less than a second,
     260:  * i.e. < 1000000.  If the timer expires, then reload
     261:  * it.  In this case, carry over (usec - old value) to
     262:  * reducint the value reloaded into the timer so that
     263:  * the timer does not drift.  This routine assumes
     264:  * that it is called in a context where the timers
     265:  * on which it is operating cannot change in value.
     266:  */
     267: itimerdecr(itp, usec)
     268:     register struct itimerval *itp;
     269:     int usec;
     270: {
     271:
     272:     if (itp->it_value.tv_usec < usec) {
     273:         if (itp->it_value.tv_sec == 0) {
     274:             /* expired, and already in next interval */
     275:             usec -= itp->it_value.tv_usec;
     276:             goto expire;
     277:         }
     278:         itp->it_value.tv_usec += 1000000L;
     279:         itp->it_value.tv_sec--;
     280:     }
     281:     itp->it_value.tv_usec -= usec;
     282:     usec = 0;
     283:     if (timerisset(&itp->it_value))
     284:         return (1);
     285:     /* expired, exactly at end of interval */
     286: expire:
     287:     if (timerisset(&itp->it_interval)) {
     288:         itp->it_value = itp->it_interval;
     289:         itp->it_value.tv_usec -= usec;
     290:         if (itp->it_value.tv_usec < 0) {
     291:             itp->it_value.tv_usec += 1000000L;
     292:             itp->it_value.tv_sec--;
     293:         }
     294:     } else
     295:         itp->it_value.tv_usec = 0;      /* sec is already 0 */
     296:     return (0);
     297: }
     298: #endif /* NOT_CURRENTLY_IN_USE */
     299:
     300: #define timevalfix  tvfix
     301:
     302: /*
     303:  * Add and subtract routines for timevals.
     304:  * N.B.: subtract routine doesn't deal with
     305:  * results which are before the beginning,
     306:  * it just gets very confused in this case.
     307:  * Caveat emptor.
     308:  */
     309: timevaladd(t1, t2)
     310:     struct timeval *t1, *t2;
     311: {
     312:
     313:     t1->tv_sec += t2->tv_sec;
     314:     t1->tv_usec += t2->tv_usec;
     315:     timevalfix(t1);
     316: }
     317:
     318: #ifdef NOT_CURRENTLY_IN_USE
     319: timevalsub(t1, t2)
     320:     struct timeval *t1, *t2;
     321: {
     322:
     323:     t1->tv_sec -= t2->tv_sec;
     324:     t1->tv_usec -= t2->tv_usec;
     325:     timevalfix(t1);
     326: }
     327: #endif
     328:
     329: timevalfix(t1)
     330:     struct timeval *t1;
     331: {
     332:
     333:     if (t1->tv_usec < 0) {
     334:         t1->tv_sec--;
     335:         t1->tv_usec += 1000000L;
     336:     }
     337:     if (t1->tv_usec >= 1000000L) {
     338:         t1->tv_sec++;
     339:         t1->tv_usec -= 1000000L;
     340:     }
     341: }

#### Defined functions

adjtime defined in line 113; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 39, 250

getitimer defined in line 156; used 3 times

- in line 206
- in /usr/src/sys/sys/init_sysent.c line 38, 196

gettimeofday defined in line 22; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 37, 226

itimerdecr defined in line 267; never used
itimerfix defined in line 244; used 1 times

- in /usr/src/sys/sys/sys_generic.c line 378

setitimer defined in line 189; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 38, 193

setthetime defined in line 75; used 1 times

- in line 63

settimeofday defined in line 49; used 2 times

- in /usr/src/sys/sys/init_sysent.c line 37, 232

timevaladd defined in line 309; used 1 times

- in /usr/src/sys/sys/sys_generic.c line 385

timevalfix defined in line 329; never used
timevalsub defined in line 319; never used

#### Defined struct's

a defined in line 191; used 10 times

- in line 27(2), 54(2), 118(2), 161(2), 194(2)

#### Defined macros

timevalfix defined in line 300; used 2 times

- in line 315, 325

Last modified: 2000-04-12 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1116 |