; +---------------------------------------------------------------------------+ ; | | ; | UTIL$ROOT:[PERFMON]CPUIDLE.MAR Calculate CPU Idle Time | ; | Scott Bailey, Xerox Corp. RE/GSD/WCO Created November 14, 1988 | ; | | ; | Modification History | ; | V1.0-002 11/14/88 RSB Original version | ; | | ; +---------------------------------------------------------------------------+ ; ; This procedure returns the number of 10-ms ticks of idle time accumulated by ; the active CPUs found on the system. It also returns the number of CPUs ; found, so the caller can determine how useful the returned idle time is. The ; basic algorithm is stolen from the routine GET_SPC in module SYSGETSPI in ; facility MONITOR from the VMS V5.0 fiche. ; .TITLE CPUIDLE - Calculate CPU Idle Time .IDENT 'V1.0-002' .LIBRARY 'SYS$LIBRARY:LIB' .LINK 'SYS$SYSTEM:SYS.STB' /SELECTIVE_SEARCH ; $CPUDEF $SSDEF ; ; status.wl.v = CPUIDLE(idle.wl.r,cpus.wl.r) ; ; IDLE (longword output parameter, passed by reference) contains the total ; aggregate idle time measured on the system, in 10-ms ticks. ; CPUS (longword output parameter, passed by reference) contains the number ; of active CPUs whose idle times were analyzed. ; STATUS (longword function value) contains the return status from this call. ; It will be SS$_BADPARAM if the argument count was incorrect, otherwise it ; will be SS$_NORMAL. Flakey arguments may cause access violations. ; IDLE = 4 ; Argument list offset definitions CPUS = 8 ; ; This procedure has been tested only on uniprocessor systems. The effects of ; starting and stopping cpus on a multiprocessor system are unknown but probably ; result in idle times which are not monotonically increasing with time; e.g. ; if a cpu is stopped, its idle time is probably removed from the total, which ; causes the returned value to decrease. ; .PSECT $CODE PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT,NOVEC .ENTRY CPUIDLE,^M CMPL #2,(AP) ; Did user supply 2 arguments? BEQL 10$ ; Yes, continue MOVL #SS$_BADPARAM,R0 ; Set error status RET ; and get out 10$: ; Initialize counters CLRL R0 ; Idle tick counter CLRL R4 ; Active CPU counter MOVL G^SMP$GL_ACTIVE_CPUS,R1 ; Get bitmask of active CPUs 20$: ; Start of scan loop FFS #0,#32,R1,R2 ; R2 will have next CPU index BEQL 30$ ; Quit if no more active CPUs MOVL G^SMP$GL_CPU_DATA[R2],R3 ; R3 points to CPU's counters ADDL2 CPU$L_NULLCPU(R3),R0 ; Add in idle time INCL R4 ; Count this CPU BBSC R2,R1,20$ ; Mark CPU 'counted' & loop 30$: ; Pass back information MOVL R0,@IDLE(AP) ; Store total idle time MOVL R4,@CPUS(AP) ; Store active CPU count MOVL #SS$_NORMAL,R0 ; We finished okay RET .END