/* SPYBW.C Written by SteveT Started on 20/7/92 Part of Spy to monitor CPU band width usage. */ #include #include #define DLG_WIDTH 190 #define DLG_HEIGHT 49 #define DLG_LINE 13 #define STACK_SIZE 500 GLREF_D TEXT *DatCommandPtr; GLREF_D VOID *winHandle; GLREF_D TEXT *DatProcessNamePtr; LOCAL_D UINT TaskCount; LOCAL_D INT Debug=FALSE; LOCAL_D UINT oldPri; LOCAL_D INT winId; LOCAL_D HANDLE bwPid; LOCAL_D HANDLE spyPid; LOCAL_D VOID *TimCB; LOCAL_D ULONG bwTotal; LOCAL_D UINT bwCount; LOCAL_D ULONG bwCabTotal; LOCAL_D UINT bwCabCount; LOCAL_D UINT bwCabBase; LOCAL_D ULONG bwCabDisplayTotal; LOCAL_D UINT bwCabDisplayCount; LOCAL_D UINT bwCabDisplayBase; LOCAL_D UWORD LastCount; LOCAL_D UWORD SampleCount; LOCAL_D UBYTE TaskStack[STACK_SIZE]; /***********************************************************/ /* This section of code is used by the task to measure the */ /* available band width. */ /***********************************************************/ LOCAL_C VOID MonitorLoop(VOID) { UINT i; p_unmarka(); FOREVER { for(i=0;i<500;i++); TaskCount++; } } /*********************/ /* Main body of code */ /*********************/ LOCAL_C VOID DebugInfo(VOID) { TEXT buf[80]; p_atos(&buf[0],"%u/%u",LastCount,SampleCount); wInfoMsg(&buf[0]); } GLDEF_C VOID DisableReads(UINT flag) { UINT tmp; tmp=P_SCR_DISABLE_READS; p_iow(winHandle,P_FSET,&tmp,&flag); } LOCAL_C INT CreateDialog(VOID) { W_WINDATA windata; INT w_id; windata.extent.width=DLG_WIDTH; windata.extent.height=DLG_HEIGHT; windata.extent.tl.x=(240-DLG_WIDTH)>>1; windata.extent.tl.y=(80-DLG_HEIGHT)>>1; w_id=wCreateWindow(0,W_WIN_EXTENT,&windata,1); wInitialiseWindowTree(w_id); return(w_id); } LOCAL_C VOID pTxt(UINT line,TEXT *txt,ULONG *pTotal,INT count,INT count2) { P_RECT rect; TEXT buf[20]; ULONG Percentage,lCount; rect.tl.x=4; rect.br.x=96; rect.tl.y=DLG_LINE+3+line*10; rect.br.y=rect.tl.y+8; gPrintBoxText(&rect,7,G_TEXT_ALIGN_LEFT,0,txt,p_slen(txt)); buf[0]=0; if (bwCount>0 && count!=0) { lCount=(ULONG)(count==-1?1:count); Percentage=(*pTotal)*100l; Percentage/=lCount; Percentage/=(ULONG)SampleCount; if (count!=0) { if (count2>=0) p_atos(&buf[0],"%U%% [%u-%u]",Percentage,count2,count+count2); else p_atos(&buf[0],count>0?"%U%% [%u]":"%U%%",Percentage,count); } } rect.tl.x=rect.br.x; rect.br.x=DLG_WIDTH-6; gPrintBoxText(&rect,7,G_TEXT_ALIGN_LEFT,0,&buf[0],p_slen(&buf[0])); } LOCAL_C VOID redrawWin(UINT update) { P_RECT rect; ULONG tmp; if (update) gCreateTempGC0(winId); else { wBeginRedrawWinGC0(winId); gBorder(W_BORD_CORNER_4|W_BORD_SHADOW_D|W_BORD_SHADOW_ON); rect.tl.x=4; rect.br.x=DLG_WIDTH-6; rect.tl.y=3; rect.br.y=11; gPrintBoxText(&rect,7,G_TEXT_ALIGN_CENTRE,0,"Available CPU band width",24); gDrawLine(1,DLG_LINE,DLG_WIDTH-2,DLG_LINE); } pTxt(0,"Average",&bwTotal,bwCount,-1); tmp=LastCount; pTxt(1,"Last",&tmp,-1,-1); pTxt(2,"\002B",&bwCabDisplayTotal,bwCabDisplayCount,bwCabDisplayBase); if (update) gFreeTempGC(); else wEndRedraw(); } LOCAL_C VOID GetCount(UWORD *pCount) { LONG time; WORD tstat; p_presume(bwPid); time=10l; TaskCount=0; p_ioc(TimCB,P_FREAD,&tstat,&time); p_waitstat(&tstat); *pCount=TaskCount; if (TaskCount>SampleCount) SampleCount=TaskCount; p_psuspend(bwPid); p_allowoff(); } LOCAL_C VOID InitBW(VOID) { UWORD oldSample,Count2; INT i; f_leave(bwPid=p_ptask("SYS$SPY",E_MAX_PRIORITY-1,MonitorLoop,&TaskStack[STACK_SIZE-1])); f_open(&TimCB,"TIM:",-1); spyPid=p_getpid(); oldPri=p_getpri(spyPid); p_setpri(spyPid,E_MAX_PRIORITY); if (SampleCount==0) for(i=0;i<5;i++) { /* If no matching samples in 5 then just take the best so far */ oldSample=SampleCount; GetCount(&Count2); if (Count2==oldSample || (Count2+1)==oldSample || Count2==(oldSample+1)) break; /* Two matching samples, must be good! */ } p_setpri(bwPid,E_MIN_PRIORITY); p_setpri(spyPid,E_PRIORITY_WSERV-1); } #ifdef JPIC #pragma save,ENTER_CALL #endif LOCAL_C INT xMonitorBandWidth(VOID) { WS_EV event; bwCabDisplayCount=bwCabCount=bwCount=bwCabDisplayBase=bwCabBase=LastCount=0; bwCabDisplayTotal=bwCabTotal=bwTotal=0; DisableReads(TRUE); winId=CreateDialog(); redrawWin(FALSE); wFlush(); InitBW(); wGetEvent(&event); FOREVER { p_ioyield(); if (event.type!=E_FILE_PENDING) { p_iowait(); if (event.type==WM_KEY) { if (event.p.key.keycode==27) break; if (event.p.key.keycode==(W_SPECIAL_KEY|'p')) wClientPosition(0,0); else if (event.p.key.keycode==(W_SPECIAL_KEY|'b')) { p_sound(-5,320); bwCabDisplayTotal=bwCabTotal; bwCabDisplayCount=bwCabCount; bwCabDisplayBase=bwCabBase; bwCabTotal=0; bwCabCount=0; bwCabBase=bwCount; redrawWin(TRUE); } else if (event.p.key.keycode=='d') Debug=!Debug; } else switch (event.type) { case WM_REDRAW: if (event.handle!=1) wInfoMsg("Redraw to unknown window!"); else redrawWin(FALSE); break; case WM_FOREGROUND: case WM_BACKGROUND: p_setpri(spyPid,E_PRIORITY_WSERV-1); break; } wGetEvent(&event); } else { GetCount(&LastCount); if (Debug) DebugInfo(); bwTotal+=LastCount; if (bwCount++==9999) bwCount=1; bwCabTotal+=LastCount; bwCabCount++; redrawWin(TRUE); wFlush(); } } return(0); } #ifdef JPIC #pragma restore #endif GLDEF_C VOID MonitorBandWidth(VOID) { INT err; TEXT *name; name=DatProcessNamePtr; bwPid=spyPid=0; DatProcessNamePtr=0; if (wCaptureKey(W_SPECIAL_KEY|'b',W_PSION_MODIFIER|W_CTRL_MODIFIER,W_PSION_MODIFIER|W_CTRL_MODIFIER)<0) wInfoMsg("'b' key capture failed"); wDisableLeaves(FALSE); err=p_enter1(xMonitorBandWidth); wDisableLeaves(TRUE); p_close(TimCB); wCancelCaptureKey(W_SPECIAL_KEY|'b',W_PSION_MODIFIER|W_CTRL_MODIFIER,W_PSION_MODIFIER|W_CTRL_MODIFIER); if (bwPid>0) p_pkill(bwPid,0); wCloseWindowTree(winId); DisableReads(FALSE); if (spyPid>0) p_setpri(spyPid,oldPri); if (err<0) p_notifyerr(err,"Band width monitor failed",NULL,NULL,NULL); DatProcessNamePtr=name; wDisableLeaves(FALSE); }