<> <> DIRECTORY BasicTime USING [GetClockPulses, Pulses, PulsesToMicroseconds], Commander USING [CommandProc, Handle, Register], IO, Process USING[ Pause, SecondsToTicks ], VMInternal; ASmallTestProgram: CEDAR PROGRAM IMPORTS BasicTime, Commander, IO, Process, VMInternal SHARES VMInternal = BEGIN OPEN VMInternal; PrintVMStats: Commander.CommandProc = { size: INT = lastRealPage; DO pinned: INT _ 0; free: INT _ 0; readonly: INT _ 0; readonlyrefd: INT _ 0; rwdirty: INT _ 0; rwdirtyrefd: INT _ 0; rwclean: INT _ 0; rwcleanrefd: INT _ 0; unmapped: INT _ 0; page: INT _ RealPageNumber.FIRST; totalpages: INT _ 0 ; startPulse: BasicTime.Pulses = BasicTime.GetClockPulses[]; endPulse: BasicTime.Pulses; microsecs: LONG CARDINAL ; TRUSTED { WHILE page <= size DO totalpages _ totalpages.SUCC; WITH rmMap[page] SELECT FROM rmE: reclaimable RMMapEntry => { vP: PageNumber = rmE.virtual; vmEntry: VMMapEntry = GetVMMap[vP]; WITH vmE: vmEntry SELECT InOut[vmEntry] FROM in => { refed: BOOL = vmE.state.flags.referenced; dirty: BOOL = vmE.state.flags.dirty OR rmE.needsBackingStoreWrite; IF vmE.state.flags.readonly THEN { IF refed THEN readonlyrefd _ readonlyrefd.SUCC ELSE readonly _ readonly.SUCC; } ELSE { IF dirty THEN { IF refed THEN rwdirtyrefd _ rwdirtyrefd.SUCC ELSE rwdirty _ rwdirty.SUCC; } ELSE { IF refed THEN rwcleanrefd _ rwcleanrefd.SUCC ELSE rwclean _ rwclean.SUCC; }; }; }; out => { unmapped _ unmapped.SUCC; -- probably being swapped in }; ENDCASE; }; rmE: free RMMapEntry => { free _ free.SUCC ; }; rmE: pinned RMMapEntry => { pinned _ pinned.SUCC; }; ENDCASE; page _ page.SUCC; ENDLOOP; }; endPulse _ BasicTime.GetClockPulses[]; microsecs _ BasicTime.PulsesToMicroseconds[endPulse-startPulse]; IO.PutF[cmd.out, "\n VM Stats microsecs %g free: %g pinned: %g unmapped: %g\n", IO.card[microsecs], IO.int[free], IO.int[pinned], IO.int[unmapped]]; IO.PutF[cmd.out, " readonly: %g readonlyrefd: %g rwdirty: %g rwdirtyrefd: %g\n", IO.int[readonly], IO.int[readonlyrefd], IO.int[rwdirty], IO.int[rwdirtyrefd]]; IO.PutF[cmd.out, " rwclean: %g rwcleanrefd: %g total pages: %g\n", IO.int[rwclean], IO.int[rwcleanrefd], IO.int[totalpages]]; Process.Pause[Process.SecondsToTicks[5]]; ENDLOOP; }; Commander.Register[key: "PrintVMStats", proc: PrintVMStats, doc: "Print pinned, and non-pinned readonly, r/w dirty and r/w clean pages in memory"]; END.