%cpu
[unix-history] / usr / src / sys / kern / kern_clock.c
index c527e36..84eef57 100644 (file)
@@ -1,7 +1,8 @@
-/*     kern_clock.c    3.10    %G%     */
+/*     %H%     3.20    kern_clock.c    */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
+#include "../h/dk.h"
 #include "../h/callo.h"
 #include "../h/seg.h"
 #include "../h/dir.h"
 #include "../h/callo.h"
 #include "../h/seg.h"
 #include "../h/dir.h"
 #include "../h/vm.h"
 #include "../h/buf.h"
 #include "../h/text.h"
 #include "../h/vm.h"
 #include "../h/buf.h"
 #include "../h/text.h"
+#include "../h/vlimit.h"
+#include "../h/mtpr.h"
+#include "../h/clock.h"
 
 #define        SCHMAG  9/10
 
 
 #define        SCHMAG  9/10
 
+/*
+ * Constant for decay filter for cpu usage.
+ */
+double ccpu = 0.93550698503161773774;          /* exp(-1/15) */
 
 /*
 
 /*
- * clock is called straight from
+ * Clock is called straight from
  * the real time clock interrupt.
  *
  * Functions:
  * the real time clock interrupt.
  *
  * Functions:
@@ -46,7 +54,7 @@ caddr_t pc;
        register struct callo *p1, *p2;
        register struct proc *pp;
        register int s;
        register struct callo *p1, *p2;
        register struct proc *pp;
        register int s;
-       int a;
+       int a, cpstate;
 
        /*
         * reprime clock
 
        /*
         * reprime clock
@@ -124,22 +132,29 @@ out:
                }
                if (s > u.u_vm.vm_maxrss)
                        u.u_vm.vm_maxrss = s;
                }
                if (s > u.u_vm.vm_maxrss)
                        u.u_vm.vm_maxrss = s;
+               if ((u.u_vm.vm_utime+u.u_vm.vm_stime+1)/HZ > u.u_limit[LIM_CPU]) {
+                       psignal(u.u_procp, SIGXCPU);
+                       if (u.u_limit[LIM_CPU] < INFINITY - 5)
+                               u.u_limit[LIM_CPU] += 5;
+               }
        }
        }
-       a = dk_busy&07;
        if (USERMODE(ps)) {
                u.u_vm.vm_utime++;
                if(u.u_procp->p_nice > NZERO)
        if (USERMODE(ps)) {
                u.u_vm.vm_utime++;
                if(u.u_procp->p_nice > NZERO)
-                       a += 8;
+                       cpstate = CP_NICE;
+               else
+                       cpstate = CP_USER;
        } else {
        } else {
-               a += 16;
+               cpstate = CP_SYS;
                if (noproc)
                if (noproc)
-                       a += 8;
+                       cpstate = CP_IDLE;
                else
                        u.u_vm.vm_stime++;
        }
                else
                        u.u_vm.vm_stime++;
        }
-       dk_time[a]++;
+       dk_time[cpstate][dk_busy&(DK_NSTATES-1)]++;
        if (!noproc) {
                pp = u.u_procp;
        if (!noproc) {
                pp = u.u_procp;
+               pp->p_cpticks++;
                if(++pp->p_cpu == 0)
                        pp->p_cpu--;
                if(pp->p_cpu % 16 == 0) {
                if(++pp->p_cpu == 0)
                        pp->p_cpu--;
                if(pp->p_cpu % 16 == 0) {
@@ -154,15 +169,25 @@ out:
                runrun++;
        }
        if (lbolt >= HZ) {
                runrun++;
        }
        if (lbolt >= HZ) {
+               extern int hangcnt;
+
                if (BASEPRI(ps))
                        return;
                lbolt -= HZ;
                ++time;
                (void) spl1();
                if (BASEPRI(ps))
                        return;
                lbolt -= HZ;
                ++time;
                (void) spl1();
+               /*
+                * machdep.c:unhang uses hangcnt to make sure uba
+                * doesn't forget to interrupt (this has been observed).
+                * This prevents an accumulation of < 5 second uba failures
+                * from summing to a uba reset.
+                */
+               if (hangcnt)
+                       hangcnt--;
                runrun++;
                wakeup((caddr_t)&lbolt);
                for(pp = &proc[0]; pp < &proc[NPROC]; pp++)
                runrun++;
                wakeup((caddr_t)&lbolt);
                for(pp = &proc[0]; pp < &proc[NPROC]; pp++)
-               if (pp->p_stat && pp->p_stat<SZOMB) {
+               if (pp->p_stat && pp->p_stat!=SZOMB) {
                        if(pp->p_time != 127)
                                pp->p_time++;
                        if(pp->p_clktim)
                        if(pp->p_time != 127)
                                pp->p_time++;
                        if(pp->p_clktim)
@@ -186,10 +211,10 @@ out:
                        if(pp->p_stat==SSLEEP||pp->p_stat==SSTOP)
                                if (pp->p_slptime != 127)
                                        pp->p_slptime++;
                        if(pp->p_stat==SSLEEP||pp->p_stat==SSTOP)
                                if (pp->p_slptime != 127)
                                        pp->p_slptime++;
-                       if(pp->p_flag&SLOAD) {
-                               ave(pp->p_aveflt, pp->p_faults, 5);
-                               pp->p_faults = 0;
-                       }
+                       if (pp->p_flag&SLOAD)
+                               pp->p_pctcpu = ccpu * pp->p_pctcpu +
+                                   (1.0 - ccpu) * (pp->p_cpticks/(float)HZ);
+                       pp->p_cpticks = 0;
                        a = (pp->p_cpu & 0377)*SCHMAG + pp->p_nice - NZERO;
                        if(a < 0)
                                a = 0;
                        a = (pp->p_cpu & 0377)*SCHMAG + pp->p_nice - NZERO;
                        if(a < 0)
                                a = 0;
@@ -225,17 +250,19 @@ out:
                 */
                if (bclnlist != NULL)
                        wakeup((caddr_t)&proc[2]);
                 */
                if (bclnlist != NULL)
                        wakeup((caddr_t)&proc[2]);
-#ifdef ERNIE
                if (USERMODE(ps)) {
                        pp = u.u_procp;
                if (USERMODE(ps)) {
                        pp = u.u_procp;
+#ifdef ERNIE
                        if (pp->p_uid)
                                if (pp->p_nice == NZERO && u.u_vm.vm_utime > 600 * HZ)
                                        pp->p_nice = NZERO+4;
                        (void) setpri(pp);
                        pp->p_pri = pp->p_usrpri;
                        if (pp->p_uid)
                                if (pp->p_nice == NZERO && u.u_vm.vm_utime > 600 * HZ)
                                        pp->p_nice = NZERO+4;
                        (void) setpri(pp);
                        pp->p_pri = pp->p_usrpri;
-               }
 #endif
 #endif
+               }
        }
        }
+       if (!BASEPRI(ps))
+               unhang();
        if (USERMODE(ps)) {
                /*
                 * We do this last since it
        if (USERMODE(ps)) {
                /*
                 * We do this last since it