home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 9
/
FreshFishVol9-CD2.bin
/
bbs
/
util
/
cpuload-1.0ß.lha
/
CPULoad
/
CPULoad.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-30
|
7KB
|
349 lines
/*
CPULoad
(C) Thomas Radtke 1994
main: Process, Initialisierungen und buisy loop
druck: Task, Graphische Ausgabe
IdleIrq: IRQ server, Auswertung des buisy loop
Um double-Rechnungen zu vermeiden werden ULONG's in beide Richtungen
geshiftet. Bei hohen Rechenleistungen kann dies ggf. zu Überläufen
führen. Abhilfe bringt eine Verringerung des 'aktuell'-Wertes
('aktuell>>n') um ein geeignetes n.
Das Abbruchsignal ist CTRL-D. Niemals CTRL-C verwenden, wenn der
Compiler dieses Signal als generellen Abbruch benutzt.
Basiert auf Idle LED von Lindsay Meek.
read the README !
*/
char *dummy="$VER: CPULoad 1.0ß";
#include <intuition/intuitionbase.h>
#include <exec/nodes.h>
#include <exec/tasks.h>
#include <exec/interrupts.h>
#include <hardware/intbits.h>
#include <libraries/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
/* Stacksize für den Grafik-Task (1000 < STACK_SIZE < 10000) */
#define STACK_SIZE 10000L
/* Task name und Pointer für Task Struktur */
struct Task *task = NULL;
char *taskname = "CPULoad";
struct timerequest *tr;
struct MsgPort *tport;
struct Message *msg;
struct Window *CustWindow;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
#define rp CustWindow->RPort
struct NewWindow BlankWindow=
{
175,24,130,50,1,0,
CLOSEWINDOW | NEWSIZE | RAWKEY,
WINDOWSIZING | ACTIVATE | GIMMEZEROZERO | SMART_REFRESH | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
0,0,
"CPULoad",
0,0,70,20,0,0,
PUBLICSCREEN
};
unsigned int maximum,aktuell;
/* globale Kopie des Main-Prozesses für druck() (wegen der Signale) */
struct Task *met2;
/* System structure name */
#define UTILITY_NAME "IdleCPU"
/* various counters used to detect the idle state in the vblank */
static ULONG idle_vbi_cnt_limit[3];
/* allocate the timer */
struct timerequest *create_timer(ULONG unit)
{
LONG error;
struct MsgPort *timerport;
struct timerequest *timermsg;
if ((timerport=(struct MsgPort *)CreatePort(0,0))==NULL) exit(1);
if ((timermsg=(struct timerequest *)CreateExtIO(timerport,sizeof(struct timerequest)))==NULL) exit(1);
if ((error=OpenDevice(TIMERNAME,unit,(struct IORequest *)timermsg,0))!=0) exit(1);
return(timermsg);
}
/* Läuft im VBL-Interrupt */
int IdleCPU()
{
idle_vbi_cnt_limit[0]=1;
aktuell=idle_vbi_cnt_limit[1];
idle_vbi_cnt_limit[1]=0;
return 0;
}
/* Läuft als Task */
druck()
{
struct IntuiMessage *message; /* Windowclose */
struct IntuiMessage *GetMsg();
struct timeval updateval; /* 1/10 Sekunde */
char name[256]; /* PubScreen */
int n;
unsigned int sum; /* Summand der freien Zyklen */
unsigned int height,width,right,bottom;
unsigned int int_pix_per_load; /* Skalierung */
int whitepen,blackpen;
struct Screen *PubScreen;
short pen,minpen,maxpen;
unsigned short RGB;
int class;
/* init timer */
tr=create_timer(UNIT_MICROHZ);
updateval.tv_secs=0;
updateval.tv_micro=100000; /* 1/10 secs */
IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0);
GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0);
GetDefaultPubScreen(name);
PubScreen=(struct Screen *)LockPubScreen(name);
UnlockPubScreen(0L,PubScreen);
BlankWindow.MaxHeight=PubScreen->Height;
BlankWindow.MaxWidth=PubScreen->Width;
CustWindow=(struct Window *)OpenWindow(&BlankWindow);
/* Farbgebung aus der ColorMap bestimmen (SunClock-Methode) */
whitepen = 1;
blackpen = 0;
maxpen=0x000;
minpen=0xfff;
for (n=0; n<1<<PubScreen->BitMap.Depth; n++)
{
RGB = GetRGB4(PubScreen->ViewPort.ColorMap,n);
pen = (RGB & 0x00f) + ((RGB & 0x0f0) >> 4) + ((RGB & 0xf00) >> 8);
if (pen < minpen)
{
minpen = pen;
blackpen = n;
}
if (pen > maxpen)
{
maxpen = pen;
whitepen = n;
}
}
height=CustWindow->GZZHeight;
width=CustWindow->GZZWidth;
right=width-1;
bottom=height-1;
/* Ja, ja, mach mich Weiß ! */
SetAPen(rp,whitepen);
RectFill(rp,0,0,right,bottom);
/* FOREVER */
while (1)
{
sum=0; /* Zyklenzähler */
for (n=0; n<10; n++)
{
/* Akkumuliere CPU-Auslastung */
sum+=aktuell;
/* wait for 1/10 secs to give others a chance */
/* Delay() funktioniert nicht, weil dos nicht erwünscht in task */
tr->tr_node.io_Command=TR_ADDREQUEST;
tr->tr_time=updateval;
DoIO((struct IORequest *)tr);
}
sum/=10; /* Average */
/* Verschiebe Bild nach links */
height=CustWindow->GZZHeight;
width=CustWindow->GZZWidth;
right=width-1;
bottom=height-1;
int_pix_per_load=(height<<16)/maximum;
ScrollRaster(rp,1,0,0,0,width,height);
/* Jede Sekunde Ausdruck */
SetAPen(rp,blackpen);
Move(rp,right,bottom);
Draw(rp,right,(sum*int_pix_per_load)>>16);
if (rp->cp_y)
{
SetAPen(rp,whitepen);
Draw(rp,right,0);
}
/*
Dies ist der gefährliche Teil des Universums. Falls das nicht auf allen
Maschinen läuft, zum testen rausschmeissen
*/
message=GetMsg(CustWindow->UserPort);
if ((class=message->Class)==CLOSEWINDOW)
{
ReplyMsg(message); /* !!! */
Signal(met2,SIGBREAKF_CTRL_D); /* Kill all tasks */
}
else if (class==NEWSIZE)
{
ReplyMsg(message);
SetAPen(rp,whitepen);
RectFill(rp,0,0,right,bottom);
}
else if (class==RAWKEY)
{
if (message->Code==89) WindowToFront(CustWindow);
ReplyMsg(message);
}
}
}
/* Run this as a process. It aborts when it detects a CTRL_D signal */
main()
{
extern struct Task *FindTask(char *);
struct Task *met;
struct Interrupt mei;
WORD oldpri;
char *oldname;
int i;
/* switch off CTRL_C handling */
signal(SIGINT,SIG_IGN);
met=FindTask(UTILITY_NAME); /* Gibts mich schon ? */
if (met!=NULL) /* Jawoll. */
{
/* Send CTRL_D signal to task */
Signal(met,SIGBREAKF_CTRL_D); /* dann Adieu ! */
exit(1); /* +-:-) */
}
/* setup für IRQ */
mei.is_Node.ln_Type = NT_INTERRUPT;
mei.is_Node.ln_Pri = -127;
mei.is_Node.ln_Name = UTILITY_NAME;
mei.is_Data = (APTR)0; /* idle_vbi_cnt_limit; */
mei.is_Code = IdleCPU;
AddIntServer(INTB_VERTB, &mei); /* Install IRQ server */
met=FindTask(NULL); /* Finde mich selber */
oldpri=met->tc_Node.ln_Pri; /* Save old priority */
oldname=met->tc_Node.ln_Name; /* Save old name */
/* Redirect task name, damit niemand durch rename die gute Absicht vereitelt */
met->tc_Node.ln_Name=UTILITY_NAME;
met->tc_Node.ln_Pri=40; /* Raise priority for calibration */
met2=met; /* Pointer für druck() */
/* reset counters */
idle_vbi_cnt_limit[0]=0;
idle_vbi_cnt_limit[1]=0;
idle_vbi_cnt_limit[2]=0;
/* wait for next vbi, nicht ganz astrein */
Forbid();
while(idle_vbi_cnt_limit[0]==0) ;
/* count # of increments in one frame (for calibration) */
idle_vbi_cnt_limit[2]=0;
idle_vbi_cnt_limit[0]=0;
while (idle_vbi_cnt_limit[0]==0) idle_vbi_cnt_limit[2]++;
Permit();
/* druck() braucht maximum */
maximum=idle_vbi_cnt_limit[2];
/* printf("%d\n",maximum); */
/* und endlich...trara ! */
task=CreateTask(taskname,30,druck,STACK_SIZE);
met->tc_Node.ln_Pri=-127;
/* Busy loop for eating up idle cpu cycles */
while((met->tc_SigRecvd & SIGBREAKF_CTRL_D)==0) /* Abort on CTRL_D */
{
idle_vbi_cnt_limit[1]++; /* Increment idle counter */
}
/* und Tschüs */
RemIntServer(INTB_VERTB,&mei); /* Remove IRQ server */
met->tc_Node.ln_Pri=oldpri; /* Change priority back */
met->tc_Node.ln_Name=oldname; /* Change name back */
Forbid();
DeleteTask(task);
Permit();
CloseWindow(CustWindow);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
exit(1);
}