home *** CD-ROM | disk | FTP | other *** search
- /*
- 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);
- }
-