From: Alan Cox Date: Tue, 25 Nov 2014 11:00:42 +0000 (+0000) Subject: process: Add loadav calculator. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=4cc69c5c002acbc972e6b766cb5060791ab545db;p=FUZIX.git process: Add loadav calculator. Needs to be exposed nicely to userspace yet. Also remove a dead FIXME in the process code --- diff --git a/Kernel/include/kdata.h b/Kernel/include/kdata.h index 7524c085..e12fe7c0 100644 --- a/Kernel/include/kdata.h +++ b/Kernel/include/kdata.h @@ -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); diff --git a/Kernel/kdata.c b/Kernel/kdata.c index 98494fef..39d92dac 100644 --- a/Kernel/kdata.c +++ b/Kernel/kdata.c @@ -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] = { diff --git a/Kernel/process.c b/Kernel/process.c index 6d599019..647a28b4 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -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 #include @@ -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; } }