-- Copyright (C) 1984 by Xerox Corporation. All rights reserved. -- Calibrate.mesa, HGM, 11-Jan-84 17:15:43 DIRECTORY Ascii USING [CR], Inline USING [LowHalf], Process USING [GetPriority, MsecToTicks, Pause, Priority, SetPriority, Yield], ProcessorFace USING [SetMP], Put USING [Text], String USING [AppendChar, AppendLongDecimal, AppendLongNumber, AppendString], System USING [ GetClockPulses, Microseconds, MicrosecondsToPulses, Pulses, PulsesToMicroseconds]; Calibrate: MONITOR IMPORTS Inline, Process, ProcessorFace, Put, String, System = BEGIN TestPulseConversion: PROCEDURE = BEGIN temp: STRING = [200]; convert: ARRAY [0..12) OF LONG CARDINAL = [ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 200000000, 500000000, 1000000000]; String.AppendString[temp, "Conversion Info, LAST[LONG CARDINAL] => "L]; AppendLongCardinal[temp, LAST[LONG CARDINAL]]; String.AppendChar[temp, Ascii.CR]; String.AppendString[temp, " Pulses => Microseconds => Pulses => Microseconds"L]; String.AppendChar[temp, Ascii.CR]; Put.Text[NIL, temp]; FOR i: CARDINAL IN [0..12) DO pulses: System.Pulses; microseconds: System.Microseconds; temp: STRING = [200]; pulses ← [convert[i]]; AppendLongCardinal[temp, pulses]; String.AppendString[temp, " => "L]; microseconds ← System.PulsesToMicroseconds[pulses]; AppendLongCardinal[temp, microseconds]; String.AppendString[temp, " => "L]; pulses ← System.MicrosecondsToPulses[microseconds]; AppendLongCardinal[temp, pulses]; String.AppendString[temp, " => "L]; microseconds ← System.PulsesToMicroseconds[pulses]; AppendLongCardinal[temp, microseconds]; String.AppendChar[temp, Ascii.CR]; Put.Text[NIL, temp]; Process.Pause[Process.MsecToTicks[2000]]; ENDLOOP; END; LookForGaps: PROCEDURE = BEGIN priorityPrev: Process.Priority ← Process.GetPriority[]; first, last: System.Pulses; max: System.Microseconds ← 0; FOR i: CARDINAL IN [0..5) DO Process.SetPriority[LAST[Process.Priority]]; FOR j: CARDINAL IN [0..1000) DO first ← System.GetClockPulses[]; Process.Yield[]; last ← System.GetClockPulses[]; pulses ← last-first; microseconds ← System.PulsesToMicroseconds[[last-first]]; max ← MAX[max, microseconds]; IF microseconds > 350 THEN EXIT; ENDLOOP; Process.SetPriority[priorityPrev]; ProcessorFace.SetMP[Inline.LowHalf[max]]; IF microseconds > 350 THEN BEGIN temp: STRING = [200]; String.AppendString[temp, "Long gap: Yield took "L]; String.AppendLongDecimal[temp, microseconds]; String.AppendString[temp, " microseconds."L]; String.AppendChar[temp, Ascii.CR]; Put.Text[NIL, temp]; END; Process.Yield[]; ENDLOOP; BEGIN temp: STRING = [200]; String.AppendString[temp, "The longest Yield took "L]; String.AppendLongDecimal[temp, max]; String.AppendString[temp, " microseconds."L]; String.AppendChar[temp, Ascii.CR]; Put.Text[NIL, temp]; END; END; CalibrateCPU: PROCEDURE = BEGIN cyclesToTest: ARRAY [0..25) OF CARDINAL = [ 100, 100, 100, 100, 100, 100, 100, 100, 100, 500, 1000, 2000, 5000, 10000, 10000, 10000, 10000, 10000, 20000, 50000, 50000, 50000, 50000, 50000, 50000]; temp: STRING = [500]; String.AppendString[temp, "Assuming a DLion gets 13100 cycles/sec."L]; String.AppendChar[temp, Ascii.CR]; String.AppendString[temp, " Cycles Pulses Microsec Cycles/Sec %"L]; String.AppendChar[temp, Ascii.CR]; Put.Text[NIL, temp]; FOR i: CARDINAL IN [0..25) DO temp: STRING = [200]; cycles: CARDINAL = cyclesToTest[i]; CollectNumbers[cycles]; AppendLongCardinal[temp, cycles]; AppendLongCardinal[temp, pulses]; AppendLongCardinal[temp, microseconds]; AppendLongCardinal[temp, cyclesPerSecond]; AppendPercent[temp, cyclesPerSecond, 13100]; String.AppendChar[temp, Ascii.CR]; Put.Text[NIL, temp]; Process.Pause[Process.MsecToTicks[5000]]; ENDLOOP; END; cycles, pulses, microseconds, cyclesPerSecond: LONG CARDINAL ← 0; pointer: LONG POINTER TO LONG CARDINAL = @cycles; Decr: PROCEDURE [x: CARDINAL] RETURNS [CARDINAL] = BEGIN RETURN[x+2]; END; CollectNumbers: PROCEDURE [cyclesToSample: CARDINAL] = BEGIN string: STRING = "123"L; priorityPrev: Process.Priority ← Process.GetPriority[]; first, last: System.Pulses; nanoSecPerCycle: LONG CARDINAL; -- Beware, things might hang (SV lockup) if our code (GF, EV) get swapped out. Process.SetPriority[LAST[Process.Priority]]; first ← System.GetClockPulses[]; THROUGH [0..cyclesToSample) DO x: CARDINAL ← 0; char: CHARACTER ← string[1]; FOR i: CARDINAL IN [20..25) DO x ← x + 1; ENDLOOP; x ← Decr[x]; pointer↑ ← pointer↑ + 1; ENDLOOP; -- This appears to go slow if an extra timeout scan happens, packet arrives or ... last ← System.GetClockPulses[]; Process.SetPriority[priorityPrev]; pulses ← last-first; microseconds ← System.PulsesToMicroseconds[[last-first]]; SELECT microseconds FROM > 100000 => nanoSecPerCycle ← System.PulsesToMicroseconds[[LONG[100]*pulses]]/(cyclesToSample/10); ENDCASE => nanoSecPerCycle ← System.PulsesToMicroseconds[[LONG[1000]*pulses]]/cyclesToSample; cyclesPerSecond ← (1000000000)/nanoSecPerCycle; END; AppendLongCardinal: PROCEDURE [s: LONG STRING, n: LONG CARDINAL] = BEGIN temp: STRING = [20]; String.AppendLongNumber[temp, n, 10]; FOR i: CARDINAL IN [temp.length..12) DO String.AppendChar[s, ' ]; ENDLOOP; String.AppendString[s, temp]; END; AppendPercent: PROCEDURE [s: LONG STRING, n, m: LONG CARDINAL] = BEGIN temp: STRING = [20]; String.AppendLongNumber[temp, (1000*n)/m, 10]; FOR i: CARDINAL IN [temp.length..5) DO String.AppendChar[s, ' ]; ENDLOOP; FOR i: CARDINAL IN [0..temp.length) DO IF i = (temp.length -1) THEN String.AppendChar[s, '.]; String.AppendChar[s, temp[i]]; ENDLOOP; ProcessorFace.SetMP[0]; Process.Pause[Process.MsecToTicks[100]]; ProcessorFace.SetMP[Inline.LowHalf[(1000*n)/m]]; END; CalibrateCPU[]; LookForGaps[]; TestPulseConversion[]; END.