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; 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. ΤLupineMarshalTestDriver.mesa. Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by BZM on 12-May-82 19:58:06. Last edited by Bob Hagmann on February 8, 1985 5:14:28 pm PST PerformMarshalExercises must be forked so that all of the local constants remain valid in the process required by LupineExerciser.PerformExercises. Cause remote binding now, so the transient won't affect timings. For periodically causing glitches (eg, NIL) that Lupine claims to handle. exerciser.Delay; Checking is never valid after an ERROR since out is undefined. MaxStringLength+1 (twoPkt threshold) tested 19-Feb-82 11:06:28. 492 is the onePkt TEXT maximum; 493 was checked 19-Feb-82 10:40:08. Module initialization. Κα˜head™Icodešœ Οmœ1™<—J™)J™=J˜J˜šΟk ˜ šœžœ˜J˜J˜1J˜JšœC˜C—JšœΟcœ˜"Jšœ˜Jšœ žœ˜Jšœžœ ˜Jšœžœ&˜0Jšœžœ˜%J˜J˜—šœž˜ JšžœK˜RJšžœ˜ Jšœžœžœ*˜6J˜J˜Jšœ[˜[Jšœž œžœ"˜6J˜šΟnœžœ˜Jšž˜JšœI™IJšœI™Išœ žœ žœ ˜(J˜3J˜5J˜HJ˜3J˜5J˜5J˜8J˜:J˜=J˜=J˜?J˜>J˜CJ˜:J˜DJ˜DJ˜0J˜0J˜0J˜9J˜=J˜G˜IJ˜——Jšœ@™@JšœC˜C˜J˜(Jšœ ž œ˜#—Jšžœ˜J˜J˜—JšœI™IJ˜š   œžœžœŸœžœ˜?Jšžœžœžœ ˜%J˜J˜J˜——˜˜Jšž˜J˜šžœ ž˜J˜šžœžœž˜*Jšœ™J˜Jšžœ˜J˜Jšžœ˜—Jšžœ˜—J˜Jšžœ˜J˜—˜Jšž˜J˜šžœ ž˜J˜šžœžœž˜*J˜J˜Jšœ˜J˜Jšžœ˜—Jšžœ˜—J˜Jšžœ˜J˜—˜Jšž˜Jšœžœ˜ J˜šžœ ž˜J˜šžœžœž˜*J˜J˜Jšœ˜J˜Jšžœžœžœ ˜,Jšžœ˜—Jšžœ˜—J˜Jšžœ˜J˜—˜Jšž˜Jšœ žœ˜J˜šžœ ž˜J˜šžœžœž˜*J˜J˜Jšœ<˜™>Jšžœ˜—Jšžœ˜—J˜Jšžœ˜J˜J˜—˜ Jšžœ˜J˜J˜'J˜J˜šžœ ž˜J˜šžœžœžœž˜*J˜Jš œ žœžœžœžœ˜AJ˜J˜Jšœ/˜/J˜šžœžœžœž˜2šžœ9˜;Jšžœ ˜—Jšžœ˜—Jšžœ˜—Jšžœ˜—J˜Jšžœ˜J˜J˜—˜Jšž˜Jšœžœ Ÿ˜š œžœžœžœ˜0Jšžœžœžœžœ˜-J˜—Jšžœžœžœ žœ˜0J˜šžœ ž˜J˜šžœžœžœž˜*Jšœžœžœ˜/Jšœž œ˜>Jšœ žœžœ˜'š žœžœž œžœ ž˜+Jšœžœ˜!—J˜J˜Jšœ3˜3J˜šžœžœž˜Jšžœžœ ˜.šžœžœžœ ž˜ šžœžœž˜ Jšœžœ ˜0—Jšžœ"žœ ˜5Jšžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ˜—J˜JšžœŸ˜Jšœžœ˜Jšžœ˜J˜—J˜"J˜J˜—J˜Jšœ™˜Jšœžœ˜1J˜J˜—JšžœŸ˜!J˜J˜—…—8 MU