[comp.sys.amiga] Amiga load average program

wjr@unicus.UUCP (William J. Rucklidge) (02/19/87)

This is a little program which I usually have running in my title bar.
It displays the number of tasks in the Amiga's run queue, averaged over
the last minute, 5 minutes and 15 minutes. This lets you see just how much
(or how little) of the time there is something using the Amiga's processor,
and how many tasks are queued to use it.

It's fairly small... it does use printf() but only for error messages in the
case of absolute disaster, so if you want you can remove all the calls to
printf() in here.

It works with Manx 16 bit, and should work with anything (unless your
compiler doesn't understand void *, in which case the declarations
of OpenLibrary() etc should be changed.)

William Rucklidge		Unicus Software Inc, Toronto, Ont.
UUCP: {the known world}!seismo!mnetor!unicus!wjr	wjr@unicus.UUCP
BITNET: WJR AT UTORONTO		CSNET: wjr@toronto
This message brought to you with the aid of the Poslfit Committee.
CUT HERE----------------------------------------------------------------
/*
 *	lav.c - Amiga load average
 *
 *	Written by:
 *	William J. Rucklidge
 *	wjr@unicus.UUCP		(soon to be wjr@unicus.com)
 *
 *	You may take this program and skywrite it and sell tickets for all
 *	I care. (i.e this program is placed in the public domain).
 *	However, if you have any improvements, suggestions or comments, mail
 *	a note to me.
 */

#include	<intuition/intuition.h>
#include	<exec/exec.h>
#include	<exec/execbase.h>

#define	TIME15	900	/* Number of samples in 15 minutes */
#define	TIME5	300	/* Number of samples in 5 minutes */
#define	TIME1	60	/* Number of samples in 1 minute */
#define	TPS	50	/* Ticks per sample, for Delay() */
#define	CLOSEWIDTH	30	/* Width of the close gadget in pixels */

struct NewWindow windef = {
	289, 0, 300, 10,
	-1, -1,
	CLOSEWINDOW,
	WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
	NULL, NULL,
	(UBYTE *) "Load",
	NULL, NULL, 0, 0, 0, 0,
	WBENCHSCREEN
};

struct IntuiText wintext = {
	0, 1, JAM2,
	0, 0,
	NULL, NULL, NULL
	};

extern void *OpenLibrary(), *OpenWindow(), *FindTask();

struct IntuitionBase *IntuitionBase;

void
convertTime(sum, count, position)
long sum;
int count;
register char *position;
{
    register long temp;

    temp = (sum * 100L + 50L) / count;
    *(position + 4) = '0' + (int)(temp % 10);
    temp /= 10;
    *(position + 3) = '0' + (int)(temp % 10);
    temp /= 10;
    *(position + 1) = '0' + (int)(temp % 10);
    temp /= 10;
    if (temp != 0) {
	*position = '0' + (int)(temp % 10);
	}
    else {
	*position = ' ';
	}
    }

#define	FORMAT	"Load: ##.## ##.## ##.##"

main()
{
    register int length;	/* Length of the current run queue */
    register struct Node *mynode; /* Node to walk through the queue */
    register int i;	/* General counter */
    int last[TIME15];	/* Length of the run queue in the last TIME seconds */
    long sum15 = 0;	/* Sum of the last 15 minutes */
    long sum5 = 0;	/* Sum of the last 5 minutes */
    long sum1 = 0;	/* Sum of the last minute */
    int pos = 0;	/* Current position in last for new value */
    int pos15 = 0;	/* Current position in last for sum15 */
    int pos5 = TIME15-TIME5;	/* Current position in last for sum5 */
    int pos1 = TIME15-TIME1;	/* Current position in last for sum1 */
    char uptimestr[26];
    struct ExecBase *ExecBase;
    struct Window *win;

    SetTaskPri(FindTask(0L), 5L);

    (void) strcpy(uptimestr, FORMAT);

    if (!(ExecBase = (struct ExecBase *)OpenLibrary("exec.library", 0L))) {
	printf("Couldn't open exec... the sky is falling!\n");
	exit(999);
	}

    if (!(IntuitionBase =
	    (struct IntuitionBase *)OpenLibrary("intuition.library", 0L))) {
	printf("Couldn't open intuition - must be dumb\n");
	CloseLibrary(ExecBase);
	exit(998);
	}

    if (!(win = OpenWindow(&windef))) {
	printf("Couldn't open window\n");
	CloseLibrary(IntuitionBase);
	CloseLibrary(ExecBase);
	exit(997);
	}

    wintext.IText = (UBYTE *)uptimestr;

    for (i = 0; i < TIME15 ; i++) {
	last[i] = 0;
	}

    for (;;) {
	Delay((long)TPS);
	if (GetMsg(win -> UserPort)) {
	    break;
	    }

	length = 0;
	Disable();
	for (mynode = (ExecBase -> TaskReady).lh_Head;
		mynode = mynode -> ln_Succ; ) {
	    length++;
	    }
	Enable();

	sum15 += (length - last[pos15]);
	sum5 += (length - last[pos5]);
	sum1 += (length - last[pos1]);
	last[pos] = length;
	if (++pos15 == TIME15) {
	    pos15 = 0;
	    }
	if (++pos5 == TIME15) {
	    pos5 = 0;
	    }
	if (++pos1 == TIME15) {
	    pos1 = 0;
	    }
	if (++pos == TIME15) {
	    pos = 0;
	    }

	convertTime(sum1, TIME1, uptimestr + 6);
	convertTime(sum5, TIME5, uptimestr + 12);
	convertTime(sum15, TIME15, uptimestr + 18);
	PrintIText(win -> RPort, &wintext, (long)CLOSEWIDTH, 1L);
	}

    CloseWindow(win);
    CloseLibrary(IntuitionBase);
    CloseLibrary(ExecBase);
    }