merge in vnode changes
[unix-history] / usr / src / sys / kern / kern_clock.c
index 875b45a..3fda9e4 100644 (file)
@@ -1,30 +1,37 @@
-/*     kern_clock.c    4.54    83/05/27        */
-
-#include "../machine/reg.h"
-#include "../machine/psl.h"
-
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dk.h"
-#include "../h/callout.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/kernel.h"
-#include "../h/proc.h"
-#include "../h/vm.h"
-#include "../h/text.h"
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)kern_clock.c        7.4 (Berkeley) %G%
+ */
 
 
-#ifdef vax
-#include "../vax/mtpr.h"
+#include "param.h"
+#include "systm.h"
+#include "dkstat.h"
+#include "callout.h"
+#include "dir.h"
+#include "user.h"
+#include "kernel.h"
+#include "proc.h"
+#include "vm.h"
+#include "text.h"
+
+#include "machine/reg.h"
+#include "machine/psl.h"
+
+#if defined(vax) || defined(tahoe)
+#include "machine/mtpr.h"
+#include "machine/clock.h"
 #endif
 
 #ifdef GPROF
 #endif
 
 #ifdef GPROF
-#include "../h/gprof.h"
+#include "gprof.h"
 #endif
 
 #endif
 
-#ifdef KGCLOCK
-extern int phz;
-#endif
+#define ADJTIME                /* For now... */
+#define        ADJ_TICK 1000
+int    adjtimedelta;
 
 /*
  * Clock handling routines.
 
 /*
  * Clock handling routines.
@@ -47,6 +54,19 @@ extern int phz;
  *     allocate more timeout table slots when table overflows.
  */
 
  *     allocate more timeout table slots when table overflows.
  */
 
+/*
+ * Bump a timeval by a small number of usec's.
+ */
+#define BUMPTIME(t, usec) { \
+       register struct timeval *tp = (t); \
+ \
+       tp->tv_usec += (usec); \
+       if (tp->tv_usec >= 1000000) { \
+               tp->tv_usec -= 1000000; \
+               tp->tv_sec++; \
+       } \
+}
+
 /*
  * The hz hardware interval timer.
  * We update the events relating to real time.
 /*
  * The hz hardware interval timer.
  * We update the events relating to real time.
@@ -54,23 +74,13 @@ extern int phz;
  * we run through the statistics gathering routine as well.
  */
 /*ARGSUSED*/
  * we run through the statistics gathering routine as well.
  */
 /*ARGSUSED*/
-#ifdef vax
 hardclock(pc, ps)
        caddr_t pc;
        int ps;
 {
 hardclock(pc, ps)
        caddr_t pc;
        int ps;
 {
-#endif
-#ifdef sun
-hardclock(regs)
-       struct regs regs;
-{
-#define        ps      regs.r_sr
-#define        pc      (caddr_t)regs.r_pc
-#endif
        register struct callout *p1;
        register struct proc *p;
        register struct callout *p1;
        register struct proc *p;
-       register int s, cpstate;
-       int needsoft = 0;
+       register int s;
 
        /*
         * Update real-time timeout queue.
 
        /*
         * Update real-time timeout queue.
@@ -86,7 +96,6 @@ hardclock(regs)
        while (p1) {
                if (--p1->c_time > 0)
                        break;
        while (p1) {
                if (--p1->c_time > 0)
                        break;
-               needsoft = 1;
                if (p1->c_time == 0)
                        break;
                p1 = p1->c_next;
                if (p1->c_time == 0)
                        break;
                p1 = p1->c_next;
@@ -99,43 +108,21 @@ hardclock(regs)
         * one tick.
         */
        if (USERMODE(ps)) {
         * one tick.
         */
        if (USERMODE(ps)) {
-#ifdef sun
-               u.u_ar0 = &regs.r_r0;   /* aston needs ar0 */
-#endif
-               if (u.u_prof.pr_scale)
-                       needsoft = 1;
                /*
                 * CPU was in user state.  Increment
                 * user time counter, and process process-virtual time
                 * interval timer. 
                 */
                /*
                 * CPU was in user state.  Increment
                 * user time counter, and process process-virtual time
                 * interval timer. 
                 */
-               bumptime(&u.u_ru.ru_utime, tick);
+               BUMPTIME(&u.u_ru.ru_utime, tick);
                if (timerisset(&u.u_timer[ITIMER_VIRTUAL].it_value) &&
                    itimerdecr(&u.u_timer[ITIMER_VIRTUAL], tick) == 0)
                        psignal(u.u_procp, SIGVTALRM);
                if (timerisset(&u.u_timer[ITIMER_VIRTUAL].it_value) &&
                    itimerdecr(&u.u_timer[ITIMER_VIRTUAL], tick) == 0)
                        psignal(u.u_procp, SIGVTALRM);
-               if (u.u_procp->p_nice > NZERO)
-                       cpstate = CP_NICE;
-               else
-                       cpstate = CP_USER;
        } else {
                /*
        } else {
                /*
-                * CPU was in system state.  If profiling kernel
-                * increment a counter.  If no process is running
-                * then this is a system tick if we were running
-                * at a non-zero IPL (in a driver).  If a process is running,
-                * then we charge it with system time even if we were
-                * at a non-zero IPL, since the system often runs
-                * this way during processing of system calls.
-                * This is approximate, but the lack of true interval
-                * timers makes doing anything else difficult.
+                * CPU was in system state.
                 */
                 */
-               cpstate = CP_SYS;
-               if (noproc) {
-                       if (BASEPRI(ps))
-                               cpstate = CP_IDLE;
-               } else {
-                       bumptime(&u.u_ru.ru_stime, tick);
-               }
+               if (!noproc)
+                       BUMPTIME(&u.u_ru.ru_stime, tick);
        }
 
        /*
        }
 
        /*
@@ -146,7 +133,7 @@ hardclock(regs)
         * This assumes that the current process has been running
         * the entire last tick.
         */
         * This assumes that the current process has been running
         * the entire last tick.
         */
-       if (noproc == 0 && cpstate != CP_IDLE) {
+       if (noproc == 0) {
                if ((u.u_ru.ru_utime.tv_sec+u.u_ru.ru_stime.tv_sec+1) >
                    u.u_rlimit[RLIMIT_CPU].rlim_cur) {
                        psignal(u.u_procp, SIGXCPU);
                if ((u.u_ru.ru_utime.tv_sec+u.u_ru.ru_stime.tv_sec+1) >
                    u.u_rlimit[RLIMIT_CPU].rlim_cur) {
                        psignal(u.u_procp, SIGXCPU);
@@ -158,7 +145,10 @@ hardclock(regs)
                    itimerdecr(&u.u_timer[ITIMER_PROF], tick) == 0)
                        psignal(u.u_procp, SIGPROF);
                s = u.u_procp->p_rssize;
                    itimerdecr(&u.u_timer[ITIMER_PROF], tick) == 0)
                        psignal(u.u_procp, SIGPROF);
                s = u.u_procp->p_rssize;
-               u.u_ru.ru_idrss += s; u.u_ru.ru_isrss += 0;     /* XXX */
+               u.u_ru.ru_idrss += s;
+#ifdef notdef
+               u.u_ru.ru_isrss += 0;           /* XXX (haven't got this) */
+#endif
                if (u.u_procp->p_textp) {
                        register int xrss = u.u_procp->p_textp->x_rssize;
 
                if (u.u_procp->p_textp) {
                        register int xrss = u.u_procp->p_textp->x_rssize;
 
@@ -195,20 +185,12 @@ hardclock(regs)
                }
        }
 
                }
        }
 
-       /*
-        * If this is the only timer then we have to use it to
-        * gather statistics.
-        */
-#ifndef KGCLOCK
-       gatherstats(pc, ps);
-#else
        /*
         * If the alternate clock has not made itself known then
         * we must gather the statistics.
         */
        if (phz == 0)
                gatherstats(pc, ps);
        /*
         * If the alternate clock has not made itself known then
         * we must gather the statistics.
         */
        if (phz == 0)
                gatherstats(pc, ps);
-#endif
 
        /*
         * Increment the time-of-day, and schedule
 
        /*
         * Increment the time-of-day, and schedule
@@ -216,15 +198,38 @@ hardclock(regs)
         * so we don't keep the relatively high clock interrupt
         * priority any longer than necessary.
         */
         * so we don't keep the relatively high clock interrupt
         * priority any longer than necessary.
         */
-       bumptime(&time, tick);
-       if (needsoft)
-               setsoftclock();
-}
-#ifdef sun
-#undef pc
-#undef ps
+#ifdef ADJTIME
+       if (adjtimedelta == 0)
+               bumptime(&time, tick);
+       else {
+               if (adjtimedelta < 0) {
+                       bumptime(&time, tick-ADJ_TICK);
+                       adjtimedelta++;
+               } else {
+                       bumptime(&time, tick+ADJ_TICK);
+                       adjtimedelta--;
+               }
+       }
+#else
+       if (timedelta == 0)
+               BUMPTIME(&time, tick)
+       else {
+               register delta;
+
+               if (timedelta < 0) {
+                       delta = tick - tickdelta;
+                       timedelta += tickdelta;
+               } else {
+                       delta = tick + tickdelta;
+                       timedelta -= tickdelta;
+               }
+               BUMPTIME(&time, delta);
+       }
 #endif
 #endif
+       setsoftclock();
+}
 
 
+int    dk_ndrive = DK_NDRIVE;
 /*
  * Gather statistics on resource utilization.
  *
 /*
  * Gather statistics on resource utilization.
  *
@@ -238,7 +243,7 @@ gatherstats(pc, ps)
        caddr_t pc;
        int ps;
 {
        caddr_t pc;
        int ps;
 {
-       int cpstate, s;
+       register int cpstate, s;
 
        /*
         * Determine what state the cpu is in.
 
        /*
         * Determine what state the cpu is in.
@@ -254,7 +259,14 @@ gatherstats(pc, ps)
        } else {
                /*
                 * CPU was in system state.  If profiling kernel
        } else {
                /*
                 * CPU was in system state.  If profiling kernel
-                * increment a counter.
+                * increment a counter.  If no process is running
+                * then this is a system tick if we were running
+                * at a non-zero IPL (in a driver).  If a process is running,
+                * then we charge it with system time even if we were
+                * at a non-zero IPL, since the system often runs
+                * this way during processing of system calls.
+                * This is approximate, but the lack of true interval
+                * timers makes doing anything else difficult.
                 */
                cpstate = CP_SYS;
                if (noproc && BASEPRI(ps))
                 */
                cpstate = CP_SYS;
                if (noproc && BASEPRI(ps))
@@ -281,18 +293,10 @@ gatherstats(pc, ps)
  * Run periodic events from timeout queue.
  */
 /*ARGSUSED*/
  * Run periodic events from timeout queue.
  */
 /*ARGSUSED*/
-#ifdef vax
 softclock(pc, ps)
        caddr_t pc;
        int ps;
 {
 softclock(pc, ps)
        caddr_t pc;
        int ps;
 {
-#endif
-#ifdef sun
-softclock()
-{
-#define        pc      (caddr_t)u.u_ar0[PC]
-#define        ps      u.u_ar0[PS]
-#endif
 
        for (;;) {
                register struct callout *p1;
 
        for (;;) {
                register struct callout *p1;
@@ -300,7 +304,7 @@ softclock()
                register int (*func)();
                register int a, s;
 
                register int (*func)();
                register int a, s;
 
-               s = spl7();
+               s = splhigh();
                if ((p1 = calltodo.c_next) == 0 || p1->c_time > 0) {
                        splx(s);
                        break;
                if ((p1 = calltodo.c_next) == 0 || p1->c_time > 0) {
                        splx(s);
                        break;
@@ -313,26 +317,27 @@ softclock()
                (*func)(arg, a);
        }
        /*
                (*func)(arg, a);
        }
        /*
-        * If trapped user-mode, give it a profiling tick.
+        * If trapped user-mode and profiling, give it
+        * a profiling tick.
         */
         */
-       if (USERMODE(ps) && u.u_prof.pr_scale) {
-               u.u_procp->p_flag |= SOWEUPC;
-               aston();
-       }
-}
-
-/*
- * Bump a timeval by a small number of usec's.
- */
-bumptime(tp, usec)
-       register struct timeval *tp;
-       int usec;
-{
+       if (USERMODE(ps)) {
+               register struct proc *p = u.u_procp;
 
 
-       tp->tv_usec += usec;
-       if (tp->tv_usec >= 1000000) {
-               tp->tv_usec -= 1000000;
-               tp->tv_sec++;
+               if (u.u_prof.pr_scale) {
+                       p->p_flag |= SOWEUPC;
+                       aston();
+               }
+               /*
+                * Check to see if process has accumulated
+                * more than 10 minutes of user time.  If so
+                * reduce priority to give others a chance.
+                */
+               if (p->p_uid && p->p_nice == NZERO &&
+                   u.u_ru.ru_utime.tv_sec > 10 * 60) {
+                       p->p_nice = NZERO+4;
+                       (void) setpri(p);
+                       p->p_pri = p->p_usrpri;
+               }
        }
 }
 
        }
 }
 
@@ -345,9 +350,9 @@ timeout(fun, arg, t)
        register int t;
 {
        register struct callout *p1, *p2, *pnew;
        register int t;
 {
        register struct callout *p1, *p2, *pnew;
-       register int s = spl7();
+       register int s = splhigh();
 
 
-       if (t == 0)
+       if (t <= 0)
                t = 1;
        pnew = callfree;
        if (pnew == NULL)
                t = 1;
        pnew = callfree;
        if (pnew == NULL)
@@ -377,7 +382,7 @@ untimeout(fun, arg)
        register struct callout *p1, *p2;
        register int s;
 
        register struct callout *p1, *p2;
        register int s;
 
-       s = spl7();
+       s = splhigh();
        for (p1 = &calltodo; (p2 = p1->c_next) != 0; p1 = p2) {
                if (p2->c_func == fun && p2->c_arg == arg) {
                        if (p2->c_next && p2->c_time > 0)
        for (p1 = &calltodo; (p2 = p1->c_next) != 0; p1 = p2) {
                if (p2->c_func == fun && p2->c_arg == arg) {
                        if (p2->c_next && p2->c_time > 0)
@@ -401,7 +406,7 @@ hzto(tv)
 {
        register long ticks;
        register long sec;
 {
        register long ticks;
        register long sec;
-       int s = spl7();
+       int s = splhigh();
 
        /*
         * If number of milliseconds will fit in 32 bit arithmetic,
 
        /*
         * If number of milliseconds will fit in 32 bit arithmetic,
@@ -439,10 +444,3 @@ profil()
        upp->pr_off = uap->pcoffset;
        upp->pr_scale = uap->pcscale;
 }
        upp->pr_off = uap->pcoffset;
        upp->pr_scale = uap->pcscale;
 }
-
-opause()
-{
-
-       for (;;)
-               sleep((caddr_t)&u, PSLEP);
-}