process: Add loadav calculator.
authorAlan Cox <alan@etchedpixels.co.uk>
Tue, 25 Nov 2014 11:00:42 +0000 (11:00 +0000)
committerAlan Cox <alan@etchedpixels.co.uk>
Tue, 25 Nov 2014 11:00:42 +0000 (11:00 +0000)
Needs to be exposed nicely to userspace yet.

Also remove a dead FIXME in the process code

Kernel/include/kdata.h
Kernel/kdata.c
Kernel/process.c

index 7524c08..e12fe7c 100644 (file)
@@ -60,6 +60,15 @@ typedef struct devsw {
 
 extern struct devsw dev_tab[];
 
+// Load management
+struct runload {
+       /* exponent is 8.8 fixed point */
+       uint8_t exponent;
+       uint16_t average;
+};
+
+extern struct runload loadavg[];
+
 // the system call dispatch table
 #define UZI_SYSCALL_COUNT 61
 typedef int16_t (*syscall_t)(void);
index 98494fe..39d92da 100644 (file)
@@ -18,6 +18,12 @@ clock_t ticks;                       // system tick counter
 
 int16_t acct_fh = -1;          /* Accounting file handle */
 
+struct runload loadavg[3] = {
+       { 235, 0 },     /* 12 sets of 5 seconds per minute */
+       { 251, 0 },     /* 60 sets of 5 seconds per 5 minutes */
+       { 254, 0 }      /* 180 sets of 5 seconds per 15 minutes */
+};
+
 /* We keep the boot up strings in the buffer pool then toss them! 8) */
 
 struct blkbuf bufpool[NBUFS] = {
index 6d59901..647a28b 100644 (file)
@@ -1,6 +1,6 @@
 #undef DEBUG                   /* turn this on to enable syscall tracing */
 #undef DEBUGHARDER             /* report calls to wakeup() that lead nowhere */
-#undef DEBUGREALLYHARD         /* turn on getproc dumping */
+#undef DEBUGREALLYHARD         /* turn on getproc dumping */
 
 #include <kernel.h>
 #include <timer.h>
@@ -278,6 +278,34 @@ ptptr ptab_alloc(void)
        return newp;
 }
 
+/* Follow Unix tradition with load reporting (or more accurately it
+   is pre-Unix from Tenex) */
+
+void load_average(void)
+{
+       struct runload *r;
+       static uint8_t utick;
+       uint8_t i;
+       uint8_t nr;
+
+       utick++;
+       if (utick < 50)
+               return;
+
+       utick = 0;
+
+       /* Every 5 seconds */
+       i = 0;
+       r = &loadavg[0];
+       nr = nready;
+
+       while (i++ < 3) {
+               r->average = ((((r->average - (nr << 8)) * r->exponent) +
+                               ((unsigned long)nr) << 16)) >> 8;
+               r++;
+       }
+}
+
 /* This is the clock interrupt routine.   Its job is to increment the clock
  * counters, increment the tick count of the running process, and either
  * switch it out if it has been in long enough and is in user space or mark
@@ -290,11 +318,12 @@ ptptr ptab_alloc(void)
 void timer_interrupt(void)
 {
        /* Increment processes and global tick counters */
-       if (udata.u_ptab->p_status == P_RUNNING)
+       if (udata.u_ptab->p_status == P_RUNNING) {
                if (udata.u_insys)
                        udata.u_stime++;
                else
                        udata.u_utime++;
+       }
        ticks++;
 
        /* Do once-per-decisecond things */
@@ -432,8 +461,6 @@ void chksigs(void)
                        kprintf("about to process signal %d\n", j);
 #endif
                        udata.u_cursig = j;
-                       /* FIXME: multiple signal processing here and in
-                          lowlevel-$cpu.s */
                        break;
                }
        }