LupineMarshalTestDriver.mesa.
Copyright © 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
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
PerformMarshalExercises must be forked so that all of the local constants
remain valid in the process required by LupineExerciser.PerformExercises.
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"]
];
Cause remote binding now, so the transient won't affect timings.
TestInterface.Null[]; TestInterface.Null[]; TestInterface.Null[];
PerformExercises[
nameOfExercisedInterface: "MarshalTest",
exercises: DESCRIPTOR[Exercises] ];
END;
For periodically causing glitches (eg, NIL) that Lupine claims to handle.
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.Delay;
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;
Checking is never valid after an ERROR since out is undefined.
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;
MaxStringLength+1 (twoPkt threshold) tested 19-Feb-82 11:06:28.
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 = {};
Module initialization.
Process.Detach[ FORK PerformMarshalExercises[] ];
END. -- LupineMarshalTestDriver.