<> <> <> <> DIRECTORY LupineExerciser USING [ Counter, BadExercise, Delay, Exercise, ExerciseProc, Handle, PerformExercises, Start, Stamp, Stop, StartPrecisionTiming, StopPrecisionTiming, String, TestInterface ], LupineMarshalTest --USING [ALL]--, LupineMarshalTestRpcControl, PrincOps USING [wordsPerPage], Process USING [Detach], Rope USING [Fetch, Flatten, Length, Text, ROPE], UnsafeStorage USING [GetSystemUZone]; LupineMarshalTestDriver: PROGRAM IMPORTS LupineExerciser, LupineMarshalTestRpcControl, Process, Rope, UnsafeStorage SHARES Rope = BEGIN OPEN LupineExerciser, Test: LupineMarshalTest; TestInterface: LupineMarshalTestRpcControl.InterfaceRecord = LupineExerciser.TestInterface; heap: UNCOUNTED ZONE = UnsafeStorage.GetSystemUZone[]; PerformMarshalExercises: PROC = BEGIN <> <> Exercises: ARRAY [0..23) OF Exercise _ [ [routine: TimingOverhead, name: "timing overhead"], [routine: NullProcedure, name: "the null procedure"], [routine: BitsToSequence, name: "packed descriptor to packed sequence"], [routine: OneInteger, name: "1 integer procedure"], [routine: FourIntegers, name: "4 integer procedure"], [routine: TenIntegers, name: "10 integer procedure"], [routine: TenArray, name: "10 integer array procedure"], [routine: FortyArray, name: "40 integer array procedure"], [routine: HundredArray, name: "100 integer array procedure"], [routine: SignalReturn, name: "signal test (no signalling)"], [routine: SignalResume, name: "signal test (SIGNAL & RESUME)"], [routine: SignalUnwind, name: "signal test (ERROR & UNWIND)"], [routine: SimpleArithmetic, name: "perform simple VAR arithmetic"], [routine: FillArray, name: "fill a call-by-result array"], [routine: Read1PageFastFrame, name: "transfer 1 page (fast frame)"], [routine: Read1PageSlowFrame, name: "transfer 1 page (slow frame)"], [routine: Read2Pages, name: "transfer 2 pages"], [routine: Read4Pages, name: "transfer 4 pages"], [routine: Read8Pages, name: "transfer 8 pages"], [routine: CreateList, name: "create a list of integers"], [routine: StringCopy, name: "copy a string to a VAR string"], [routine: CharToVariantString, name: "variant record of string types"], [routine: StringsToAtoms, name: "descriptor of strings to list of atoms"] ]; <> TestInterface.Null[]; TestInterface.Null[]; TestInterface.Null[]; PerformExercises[ nameOfExercisedInterface: "MarshalTest", exercises: DESCRIPTOR[Exercises] ]; END; <> Periodically: PROC [test: Counter] RETURNS [--yes:-- BOOLEAN] = INLINE {RETURN[ (test MOD 31) = 0 ]}; TimingOverhead: ExerciseProc = BEGIN exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO <> exerciser.StartPrecisionTiming; NULL; exerciser.StopPrecisionTiming; ENDLOOP; ENDLOOP; exerciser.Stop; END; NullProcedure: ExerciseProc = BEGIN exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; TestInterface.Null[]; exerciser.StopPrecisionTiming; ENDLOOP; ENDLOOP; exerciser.Stop; END; OneInteger: ExerciseProc = BEGIN a: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; a _ TestInterface.One[test]; exerciser.StopPrecisionTiming; IF checkResults AND a#test THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; FourIntegers: ExerciseProc = BEGIN a,b,c,d: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; [a,b,c,d] _ TestInterface.Four[test+0,test+1,test+2,test+3]; exerciser.StopPrecisionTiming; IF checkResults AND (a#test+0 OR b#test+1 OR c#test+2 OR d#test+3) THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; TenIntegers: ExerciseProc = BEGIN a,b,c,d,e,f,g,h,i,j: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; [a,b,c,d,e,f,g,h,i,j] _ TestInterface.Ten[ test+0,test+1,test+2,test+3,test+4, test+5,test+6,test+7,test+8,test+9 ]; exerciser.StopPrecisionTiming; IF checkResults AND (a#test+0 OR b#test+1 OR c#test+2 OR d#test+3 OR e#test+4 OR f#test+5 OR g#test+6 OR h#test+7 OR i#test+8 OR j#test+9) THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; TenArray: ExerciseProc = BEGIN array10: Test.Array10; ten: Test.Array10 = ALL[10]; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; array10 _ TestInterface.TenArray[ten]; exerciser.StopPrecisionTiming; IF checkResults AND ten#array10 THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; FortyArray: ExerciseProc = BEGIN array40: Test.Array40; forty: Test.Array40 = ALL [40]; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; array40 _ TestInterface.FortyArray[forty]; exerciser.StopPrecisionTiming; IF checkResults AND forty#array40 THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; HundredArray: ExerciseProc = BEGIN array100: Test.Array100; hundred: Test.Array100 = ALL[100]; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; array100 _ TestInterface.HundredArray[hundred]; exerciser.StopPrecisionTiming; IF checkResults AND hundred#array100 THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; SignalReturn: ExerciseProc = BEGIN out: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; out _ TestInterface.SignalTest[ in: test, action: neither ! TestInterface.Signal => {BadExercise; CONTINUE} ]; exerciser.StopPrecisionTiming; IF checkResults AND out#test THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; SignalResume: ExerciseProc = BEGIN out: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; out _ TestInterface.SignalTest[ in: test, action: signal ! TestInterface.Signal => { IF checkResults AND in#test THEN BadExercise; RESUME[out: 2*in] } ]; exerciser.StopPrecisionTiming; IF checkResults AND out#2*test THEN BadExercise; ENDLOOP; ENDLOOP; exerciser.Stop; END; SignalUnwind: ExerciseProc = BEGIN out: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: Counter IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; out _ TestInterface.SignalTest[ in: test, action: error ! TestInterface.Signal => { IF checkResults AND in#test THEN BadExercise; CONTINUE } ]; exerciser.StopPrecisionTiming; <> ENDLOOP; ENDLOOP; exerciser.Stop; END; SimpleArithmetic: ExerciseProc = BEGIN sketchPad: Test.VARArithmetic; sketchPadRecord: Test.ArithmeticRecord; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO sketchPadRecord.in _ test; sketchPad _ IF Periodically[test] THEN NIL ELSE @sketchPadRecord; exerciser.Delay; exerciser.StartPrecisionTiming; TestInterface.SimpleArithmetic[pad: sketchPad]; exerciser.StopPrecisionTiming; IF checkResults AND ~Periodically[test] THEN BEGIN IF sketchPad^ # Test.ArithmeticRecord[test, test+1, test*2] THEN BadExercise; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; FillArray: ExerciseProc = BEGIN MaxVectorLength: INTEGER = 4*252; -- 252 is onePkt maximum. vector: Test.RESULTArray; vectorBody: ARRAY [0..MaxVectorLength) OF INTEGER; vectorLength: INTEGER; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO vectorLength _ test MOD (MaxVectorLength+1); vector _ IF Periodically[test] THEN NIL ELSE DESCRIPTOR[BASE[vectorBody], vectorLength]; exerciser.Delay; exerciser.StartPrecisionTiming; TestInterface.FillArray[in: test, out: vector]; exerciser.StopPrecisionTiming; IF checkResults AND ~Periodically[test] THEN BEGIN IF vectorLength # LENGTH[vector] THEN BadExercise; FOR i: INTEGER IN [0..vectorLength) DO IF vector[i] # test-i THEN BadExercise; ENDLOOP; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; Read1PageFastFrame: ExerciseProc = {ReadPages[1, exerciser, name, trials, testsPerTrial, checkResults]}; Read1PageSlowFrame: ExerciseProc = BEGIN GrabFrames: PROC [grab: INTEGER] = BEGIN grabSpace: ARRAY [0..350) OF WORD; IF grab > 0 THEN {grabSpace _ ALL[NULL]; GrabFrames[grab-1]} ELSE ReadPages[ 1, exerciser, name, trials, testsPerTrial, checkResults]; END; GrabFrames[3]; END; Read2Pages: ExerciseProc = {ReadPages[2, exerciser, name, trials, testsPerTrial, checkResults]}; Read4Pages: ExerciseProc = {ReadPages[4, exerciser, name, trials, testsPerTrial, checkResults]}; Read8Pages: ExerciseProc = {ReadPages[8, exerciser, name, trials, testsPerTrial, checkResults]}; ReadPages: --Pages plus ExerciseProc-- PROCEDURE [ pages: Counter, exerciser: Handle, name: String, trials: Counter, testsPerTrial: Counter, checkResults: BOOLEAN ] = BEGIN Buffer: TYPE = RECORD[SEQUENCE words: CARDINAL OF Test.Item]; bufferPtr: LONG POINTER TO Buffer _ heap.NEW[Buffer[pages*PrincOps.wordsPerPage]]; buffer: Test.RESULTPages = DESCRIPTOR[bufferPtr^]; BEGIN ENABLE UNWIND => heap.FREE[@bufferPtr]; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO exerciser.Delay; exerciser.StartPrecisionTiming; TestInterface.ReadPages[item: test, buffer: buffer]; exerciser.StopPrecisionTiming; IF checkResults THEN BEGIN IF bufferPtr.words # LENGTH[buffer] THEN BadExercise; FOR i: CARDINAL IN [0..LENGTH[buffer]) DO IF buffer[i] # test THEN BadExercise; ENDLOOP; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; -- ENABLE UNWIND. heap.FREE[@bufferPtr]; END; CreateList: ExerciseProc = BEGIN MaxListLength: INTEGER = 2*127; -- 127 is onePkt maximum. listLength: INTEGER; outList: Test.IntList; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO listLength _ test MOD (MaxListLength+1); exerciser.Delay; exerciser.StartPrecisionTiming; outList _ TestInterface.CreateList[in: test, length: listLength]; exerciser.StopPrecisionTiming; IF checkResults THEN BEGIN outLength: INTEGER _ 0; FOR int: Test.IntList _ outList, int.rest UNTIL int = NIL DO IF int.first # test-outLength THEN BadExercise; outLength _ outLength + 1; ENDLOOP; IF outLength # listLength THEN BadExercise; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; StringCopy: ExerciseProc = BEGIN MaxStringLength: CARDINAL = 4*Test.MaxReadonlyStringLength; <> string: LONG STRING; inString: STRING = [MaxStringLength]; outString: Rope.ROPE; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO inChar: CHARACTER = LOOPHOLE[test MOD 128]; outChar: CHARACTER = LOOPHOLE[(test+11) MOD 128]; inString.length _ test MOD (MaxStringLength+1); FOR i: CARDINAL IN [0..MaxStringLength) DO inString[i] _ inChar; ENDLOOP; string _ IF Periodically[test] THEN NIL ELSE inString; exerciser.Delay; exerciser.StartPrecisionTiming; outString _ TestInterface.StringCopy[in: string]; exerciser.StopPrecisionTiming; IF checkResults THEN BEGIN IF Periodically[test] THEN { IF outString.Length[] # 0 THEN BadExercise; } ELSE { FOR i: CARDINAL IN [0..inString.length) DO IF outString.Fetch[i] # inChar THEN BadExercise; ENDLOOP; }; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; CharToVariantString: ExerciseProc = BEGIN MaxStringLength: CARDINAL = 2*492; <<492 is the onePkt TEXT maximum; 493 was checked 19-Feb-82 10:40:08.>> string: Test.StringSelection; ropeString: Test.StringSelection[rope] = [string: rope[]]; textString: Test.StringSelection[text] = [string: text[]]; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO char: CHARACTER = LOOPHOLE[test MOD 128]; length: INTEGER = test MOD (MaxStringLength+1); type: Test.StringType = SELECT test MOD 13 FROM 0,5,8,9,11,12 => text, 1,2,4,6,7 => rope, 3,10 => nil, ENDCASE => ERROR; makeNil: BOOLEAN = Periodically[test]; exerciser.Delay; exerciser.StartPrecisionTiming; string _ TestInterface.CharToVariantString[ char: char, length: length, type: type, makeNil: makeNil ]; exerciser.StopPrecisionTiming; IF checkResults THEN BEGIN IF string.char # char OR string.length # length THEN BadExercise; IF string.type # type THEN BadExercise; WITH string: string SELECT FROM nil => NULL; rope => BEGIN IF string.seal # ropeString.seal THEN BadExercise; IF ~makeNil THEN BEGIN OPEN Rope; textRope: Text; IF Length[string.rope] # length THEN BadExercise; textRope _ Flatten[string.rope]; FOR i: INTEGER IN [0..length) DO IF textRope.text[i] # char THEN BadExercise; ENDLOOP; END ELSE IF string.rope # NIL THEN BadExercise; END; text => BEGIN IF string.seal # textString.seal THEN BadExercise; IF ~makeNil THEN BEGIN IF string.text.length # length THEN BadExercise; FOR i: INTEGER IN [0..length) DO IF string.text[i] # char THEN BadExercise; ENDLOOP; END ELSE IF string.text # NIL THEN BadExercise; END; ENDCASE => ERROR; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; BitsToSequence: ExerciseProc = BEGIN MaxVectorLength: CARDINAL = 3*850; BitVector: TYPE = PACKED ARRAY [0..MaxVectorLength) OF Test.Bits; bitVectorPtr: LONG POINTER TO BitVector _ heap.NEW[BitVector]; Pattern: PROC [i: INTEGER] RETURNS [Test.Bits] = INLINE {RETURN[ i MOD (LAST[Test.Bits]+1) ]}; BEGIN ENABLE UNWIND => heap.FREE[@bitVectorPtr]; exerciser.Start[name]; THROUGH [0..trials) DO exerciser.Stamp; FOR test: INTEGER IN [0..testsPerTrial) DO length: INTEGER = test MOD (MaxVectorLength+1); bitsIn: Test.BitDescriptor = DESCRIPTOR[bitVectorPtr, length]; bitsOut: REF READONLY Test.BitSequence; FOR i: INTEGER DECREASING IN (length..0] DO bitsIn[i] _ Pattern[i]; ENDLOOP; exerciser.Delay; exerciser.StartPrecisionTiming; bitsOut _ TestInterface.BitsToSequence[in: bitsIn]; exerciser.StopPrecisionTiming; IF checkResults THEN BEGIN IF bitsOut.length-1 # length THEN BadExercise; FOR i: INTEGER IN [0..length) DO IF i < LENGTH[bitsOut.fixed] AND bitsOut.fixed[i+1] # bitsIn[i] THEN BadExercise; IF bitsOut.dynamic[i+1] # bitsIn[i] THEN BadExercise; ENDLOOP; END; ENDLOOP; ENDLOOP; exerciser.Stop; END; -- ENABLE UNWIND. heap.FREE[@bitVectorPtr]; END; StringsToAtoms: ExerciseProc = {}; <> Process.Detach[ FORK PerformMarshalExercises[] ]; END. -- LupineMarshalTestDriver.