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);
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] = {
#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>
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
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 */
kprintf("about to process signal %d\n", j);
#endif
udata.u_cursig = j;
- /* FIXME: multiple signal processing here and in
- lowlevel-$cpu.s */
break;
}
}