<> <> <> <<>> DIRECTORY AllocatorOps, Basics, Commander, CommandTool, Convert, CountedVM USING [Handle, Free, SimpleAllocate], IO, Rope, SampleMapOps, SlowSampleMapOps, Process, PrincOps, Random, SafeStorage USING [ReclaimCollectibleObjects]; TestBB: CEDAR PROGRAM IMPORTS SampleMapOps, SlowSampleMapOps, AllocatorOps, Basics, Commander, CommandTool, Convert, CountedVM, IO, Process, Random, SafeStorage ~ BEGIN OPEN SampleMapOps; AnotEqSA: SIGNAL[which: ATOM] = CODE; BnotEqSB: SIGNAL[which: ATOM] = CODE; DoubleCopyFailed: SIGNAL[first, num: LONG CARDINAL] = CODE; LastOp: TYPE = {none, putSample, move, transfer, fill, tile, rotate}; lastOp: LastOp; simplePattern: BOOL _ FALSE; CountVec: TYPE = ARRAY LastOp OF INT; doOpCountVec: CountVec; wordsPerPage: NAT = PrincOps.wordsPerPage; LongTest: PROC [cmd: Commander.Handle _ NIL, n: INT _ 100, m: INT _ 100, seed: INT _ 31415, maxSize: NAT _ 2048] RETURNS[CountVec] ~ { BEGIN ENABLE ABORTED => GOTO exit; random: Random.RandomStream _ Random.Create[seed: seed]; SkewedRand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ { RETURN [random.ChooseInt[0, max]*random.ChooseInt[0, max]/max+1] }; doOpCountVec _ [0, 0, 0, 0, 0, 0, 0]; FOR i: INT IN [0..n) DO bitsPerSample: CARDINAL _ random.ChooseInt[1, 16]; aSize: CVEC ~ [SkewedRand[maxSize], SkewedRand[maxSize]]; bSize: CVEC ~ [SkewedRand[(maxSize+1)/2], SkewedRand[(maxSize+2)/3]]; a: SampleMap; b: SampleMap; <> <> IF cmd # NIL THEN cmd.out.PutChar[IF i MOD 10 = 0 THEN '! ELSE '~]; a _ SlowSampleMapOps.Create[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample]; b _ SlowSampleMapOps.Create[sSize: bSize.s, fSize: bSize.f, bitsPerSample: bitsPerSample]; <> <> RunTest[a, b, seed, m]; a _ b _ NIL; <> <> SafeStorage.ReclaimCollectibleObjects[suspendMe: FALSE]; ENDLOOP; EXITS exit => NULL; END; RETURN[doOpCountVec]; }; RunTest: PROC [a, b: SampleMap, seed: INT _ 314159, n: INT _ 1000] ~ { <<>> <> random: Random.RandomStream _ Random.Create[seed: seed]; sa, sb: SampleMap; <> <> <> <<[first, num] _ TestEquality[t1, st1, nWords];>> <> AddressInit[a, 1, Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo]; AddressInit[b, -1, Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo]; sa _ SlowSampleMapOps.Copy[[a]]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$first]; sb _ SlowSampleMapOps.Copy[[b]]; IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$first]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterSb]; FOR i: INT IN [0..n) DO rand: CARDINAL _ random.ChooseInt[0, CARDINAL.LAST]; function: Function; op: LastOp; IF simplePattern THEN { ax: WORD; AddressInit[a, 1, ax _ Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo]; AddressInit[sa, 1, ax]; AddressInit[b, -1, ax _ Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo]; AddressInit[sb, -1, ax]; }; [function, op] _ DoOp[a, b, sa, sb, rand]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterDoOp]; IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$afterDoOp]; {t: SampleMap _ a; a _ b; b _ t}; {t: SampleMap _ sa; sa _ sb; sb _ t}; Process.CheckForAbort[]; ENDLOOP; FreeCountedVM[a, b, sa, sb]; a _ b _ sa _ sb _ NIL; }; SkewTest: PROC [cmd: Commander.Handle _ NIL, n: INT _ 100, m: INT _ 100, seed: INT _ 31415, maxSize: NAT _ 2048] RETURNS[CountVec] ~ { BEGIN ENABLE ABORTED => GOTO exit; random: Random.RandomStream _ Random.Create[seed: seed]; SkewedRand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ { RETURN [random.ChooseInt[0, max]*random.ChooseInt[0, max]/max+1] }; doOpCountVec _ [0, 0, 0, 0, 0, 0, 0]; FOR i: INT IN [0..n) DO bitsPerSample: CARDINAL _ random.ChooseInt[1, 16]; aSize: CVEC ~ [SkewedRand[maxSize], SkewedRand[maxSize]]; bSize: CVEC ~ [SkewedRand[(maxSize+1)/2], SkewedRand[(maxSize+2)/3]]; a: SampleMap; b: SampleMap; IF cmd # NIL THEN cmd.out.PutChar[IF i MOD 10 = 0 THEN '! ELSE '~]; <<-- FunnyCreate makes odd sized SampleMaps>> a _ FunnyCreate[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample]; b _ FunnyCreate[sSize: bSize.s, fSize: bSize.f, bitsPerSample: bitsPerSample]; RunSkewTest[a, b, seed, m]; a _ b _ NIL; SafeStorage.ReclaimCollectibleObjects[suspendMe: FALSE]; ENDLOOP; EXITS exit => NULL; END; RETURN[doOpCountVec]; }; RunSkewTest: PROC [a, b: SampleMap, seed: INT _ 314159, n: INT _ 1000] ~ { random: Random.RandomStream _ Random.Create[seed: seed]; sa, sb: SampleMap; AddressInit[a, 1, Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo]; AddressInit[b, -1, Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo]; sa _ SlowSampleMapOps.Copy[[a]]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$first]; sb _ SlowSampleMapOps.Copy[[b]]; IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$first]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterSb]; FOR i: INT IN [0..n) DO rand: CARDINAL _ random.ChooseInt[0, CARDINAL.LAST]; function: Function; op: LastOp; IF simplePattern THEN { ax: WORD; AddressInit[a, 1, ax _ Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo]; AddressInit[sa, 1, ax]; AddressInit[b, -1, ax _ Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo]; AddressInit[sb, -1, ax]; }; [function, op] _ DoSkewOp[a, b, sa, sb, rand]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterDoOp]; IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$afterDoOp]; {t: SampleMap _ a; a _ b; b _ t}; {t: SampleMap _ sa; sa _ sb; sb _ t}; Process.CheckForAbort[]; ENDLOOP; FreeCountedVM[a, b, sa, sb]; a _ b _ sa _ sb _ NIL; }; DoFillTest: PROC[cmd: Commander.Handle _ NIL, n: INT _ 100, seed: INT _ 31415, maxSize: NAT _ 2048] RETURNS[count: INT] ~ { BEGIN ENABLE ABORTED => GOTO exit; random: Random.RandomStream _ Random.Create[seed: seed]; SkewedRand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ { RETURN [random.ChooseInt[0, max]*random.ChooseInt[0, max]/max+1] }; count _ 0; FOR i: INT IN [0..n) DO bitsPerSample: CARDINAL _ random.ChooseInt[1, 4]; aSize: CVEC ~ [SkewedRand[maxSize], SkewedRand[maxSize]]; bSize: CVEC ~ [SkewedRand[(maxSize+1)/2], SkewedRand[(maxSize+2)/3]]; a, sa, b, sb: SampleMap; IF cmd # NIL THEN cmd.out.PutChar[IF i MOD 10 = 0 THEN '! ELSE '~]; a _ SlowSampleMapOps.Create[sSize: aSize.s, fSize: aSize.f, bitsPerSample: bitsPerSample]; b _ SlowSampleMapOps.Create[sSize: bSize.s, fSize: bSize.f, bitsPerSample: bitsPerSample]; AddressInit[a, 1, Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo]; AddressInit[b, -1, Basics.DoubleShiftRight[LOOPHOLE[b.base.word], 8].lo]; sa _ SlowSampleMapOps.Copy[[a]]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$first]; sb _ SlowSampleMapOps.Copy[[b]]; IF NOT Equal[[sb],[b]] THEN SIGNAL BnotEqSB[$first]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterSb]; AlwaysDoFill[a, b, sa, sb, seed]; IF NOT Equal[[sa],[a]] THEN SIGNAL AnotEqSA[$afterDoFill]; a _ b _ NIL; count _ count + 1; ENDLOOP; EXITS exit => NULL; END; }; DoOp: PROC [a, b, sa, sb: SampleMap, seed: CARDINAL] RETURNS[function: Function, lop: LastOp] ~ { Rand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ { seed _ seed * 3141 + 3; RETURN [Basics.HighHalf[Basics.LongMult[max+1, seed]]]; }; RandV: PROC [max: CVEC] RETURNS [CVEC] ~ {RETURN [[Rand[max.s], Rand[max.f]]]}; aMin: CVEC ~ [Rand[a.sSize], Rand[a.fSize]]; aSize: CVEC ~ [Rand[a.sSize-aMin.s], Rand[a.fSize-aMin.f]]; ad: CVEC ~ [Rand[a.sSize-aSize.s], Rand[a.fSize-aSize.f]]; bMin: CVEC ~ [Rand[b.sSize-1], Rand[b.fSize-1]]; bSize: CVEC ~ [Rand[b.sSize-bMin.s-1]+1, Rand[b.fSize-bMin.f-1]+1]; value: CARDINAL _ Rand[Basics.BITSHIFT[1, a.bitsPerSample]-1]; op: NAT = Rand[5]; function _ [VAL[Rand[3]], VAL[Rand[1]]]; SELECT op FROM 0 => IF a.sSize > 0 AND a.fSize > 0 THEN { randVec: CVEC = RandV[[a.sSize-1, a.fSize-1]]; PutSample[sampleMap: a, index: randVec, value: value, function: function]; SlowSampleMapOps.PutSample[sampleMap: sa, index: randVec, value: value, function: function, goodDest: a]; lastOp _ putSample; } ELSE lastOp _ none; 1 => { Move[sampleMap: a, destStart: aMin, sourceStart: ad, size: aSize, function: function]; SlowSampleMapOps.Move[sampleMap: sa, destStart: aMin, sourceStart: ad, size: aSize, function: function, goodDest: a]; lastOp _ move; }; 2 => { Transfer[dest: a, destStart: aMin, source: [b, bMin, bSize], function: function]; SlowSampleMapOps.Transfer[dest: sa, destStart: aMin, source: [sb, bMin, bSize], function: function, goodDest: a]; lastOp _ transfer; }; 3 => { IF value = 0 THEN value _ 123456B; -- don't want 0 gray fill Fill[dest: [a, aMin, aSize], value: value, function: function]; SlowSampleMapOps.Fill[dest: [sa, aMin, aSize], value: value, function: function, goodDest: [a, aMin, aSize] ]; lastOp _ fill; }; 4 => { s0: INTEGER _ INTEGER[Rand[100]]-50; f0: INTEGER _ INTEGER[Rand[100]]-50; phase: NAT _ Rand[bSize.f]*Rand[1]; tile: SampleMap ~ FromSubMap[[b, bMin, bSize]]; slowTile: SampleMap ~ FromSubMap[[sb, bMin, bSize]]; IF tile.sSize > 0 AND tile.fSize > 0 THEN { lastOp _ tile; TileBox[dest: a, start: aMin, size: aSize, source: tile, s0: s0, f0: f0, phase: phase, function: function]; SlowSampleMapOps.TileBox[dest: sa, start: aMin, size: aSize, source: slowTile, s0: s0, f0: f0, phase: phase, function: function, goodDest: a]; } ELSE lastOp _ none; }; 5 => { Rot[FromSubMap[[a, aMin, aSize]], FromSubMap[[b, bMin, bSize]], FromSubMap[[sa, aMin, aSize]], FromSubMap[[b, bMin, bSize]] ]; lastOp _ rotate; }; ENDCASE => ERROR; doOpCountVec[lastOp] _ doOpCountVec[lastOp] + 1; RETURN[function, lastOp]; }; FreeCountedVM: PROC[a, b, c, d: SampleMap] = TRUSTED { WITH a.ref SELECT FROM x: CountedVM.Handle => CountedVM.Free[x]; ENDCASE => NULL; WITH b.ref SELECT FROM x: CountedVM.Handle => CountedVM.Free[x]; ENDCASE => NULL; WITH c.ref SELECT FROM x: CountedVM.Handle => CountedVM.Free[x]; ENDCASE => NULL; WITH d.ref SELECT FROM x: CountedVM.Handle => CountedVM.Free[x]; ENDCASE => NULL; a.ref _ b.ref _ c.ref _ d.ref _ NIL; }; FunnyCreate: PROC [sSize: CARDINAL, fSize: CARDINAL, bitsPerSample: [0..Basics.bitsPerWord]] RETURNS [SampleMap] ~ { bitsPerLine: NAT ~ Basics.LongMult[fSize, bitsPerSample]; nWords: LONG CARDINAL ~ (Basics.LongMult[sSize, bitsPerLine]+15)/16; vm: CountedVM.Handle ~ CountedVM.SimpleAllocate[words: nWords]; TRUSTED {RETURN [UnsafeCreate[ sSize: sSize, fSize: fSize, bitsPerSample: bitsPerSample, bitsPerLine: bitsPerLine, base: [word: vm.pointer, bit: 0], nWords: vm.words, ref: vm ]]}; }; Rot: PROC [a, b, sa, sb: SampleMap] ~ { rowSize: NAT ~ MIN[a.sSize, b.fSize]; buf: Buffer ~ ObtainBuffer[rowSize]; IF rowSize > 0 THEN FOR i: NAT IN [0..MIN[a.fSize, b.sSize]) DO Get[buffer: buf, sampleMap: b, s: i]; Flip[buf]; Put[buffer: buf, sampleMap: a, s: 0, f: i, ds: 1, df: 0]; Get[buffer: buf, sampleMap: sb, s: i]; Flip[buf]; SlowSampleMapOps.Put[buffer: buf, sampleMap: sa, s: 0, f: i, ds: 1, df: 0, goodDest: a]; ENDLOOP; ReleaseBuffer[buf]; }; SkewRotate: PROC [a, b, sa, sb: SampleMap] ~ { rowSize: NAT ~ MIN[a.sSize, b.fSize]; buf: Buffer ~ ObtainBuffer[rowSize]; IF rowSize > 0 THEN FOR i: NAT IN [0..MIN[a.fSize, b.sSize]) DO Get[buffer: buf, sampleMap: b, s: i]; Flip[buf]; Put[buffer: buf, sampleMap: a, s: 0, f: i, ds: 1, df: 0]; Get[buffer: buf, sampleMap: sb, s: i]; Flip[buf]; SlowSampleMapOps.Put[buffer: buf, sampleMap: sa, s: 0, f: i, ds: 1, df: 0, goodDest: NIL]; ENDLOOP; ReleaseBuffer[buf]; }; AlwaysDoFill: PROC [a, b, sa, sb: SampleMap, seed: CARDINAL] ~ { Rand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ { seed _ seed * 3141 + 3; RETURN [Basics.HighHalf[Basics.LongMult[max+1, seed]]]; }; RandV: PROC [max: CVEC] RETURNS [CVEC] ~ {RETURN [[Rand[max.s], Rand[max.f]]]}; aMin: CVEC ~ [Rand[a.sSize], Rand[a.fSize]]; aSize: CVEC ~ [Rand[a.sSize-aMin.s], Rand[a.fSize-aMin.f]]; ad: CVEC ~ [Rand[a.sSize-aSize.s], Rand[a.fSize-aSize.f]]; bMin: CVEC ~ [Rand[b.sSize-1], Rand[b.fSize-1]]; bSize: CVEC ~ [Rand[b.sSize-bMin.s-1]+1, Rand[b.fSize-bMin.f-1]+1]; value: CARDINAL _ Rand[Basics.BITSHIFT[1, a.bitsPerSample]-1]; function: Function _ [null, complement]; IF value = 0 THEN value _ 123456B; -- don't want 0 gray fill Fill[dest: [a, aMin, aSize], value: value, function: function]; SlowSampleMapOps.Fill[dest: [sa, aMin, aSize], value: value, function: function, goodDest: [a, aMin, aSize] ]; }; DoSkewOp: PROC [a, b, sa, sb: SampleMap, seed: CARDINAL] RETURNS[function: Function, lop: LastOp] ~ { Rand: PROC [max: CARDINAL] RETURNS [CARDINAL] ~ { seed _ seed * 3141 + 3; RETURN [Basics.HighHalf[Basics.LongMult[max+1, seed]]]; }; RandV: PROC [max: CVEC] RETURNS [CVEC] ~ {RETURN [[Rand[max.s], Rand[max.f]]]}; aMin: CVEC ~ [Rand[a.sSize], Rand[a.fSize]]; aSize: CVEC ~ [Rand[a.sSize-aMin.s], Rand[a.fSize-aMin.f]]; ad: CVEC ~ [Rand[a.sSize-aSize.s], Rand[a.fSize-aSize.f]]; bMin: CVEC ~ [Rand[b.sSize-1], Rand[b.fSize-1]]; bSize: CVEC ~ [Rand[b.sSize-bMin.s-1]+1, Rand[b.fSize-bMin.f-1]+1]; value: CARDINAL _ Rand[Basics.BITSHIFT[1, a.bitsPerSample]-1]; op: NAT = Rand[5]; function _ [VAL[Rand[3]], VAL[Rand[1]]]; SELECT op FROM 0 => IF a.sSize > 0 AND a.fSize > 0 THEN { randVec: CVEC = RandV[[a.sSize-1, a.fSize-1]]; PutSample[sampleMap: a, index: randVec, value: value, function: function]; SlowSampleMapOps.PutSample[sampleMap: sa, index: randVec, value: value, function: function, goodDest: NIL]; lastOp _ putSample; } ELSE lastOp _ none; 1 => { Move[sampleMap: a, destStart: aMin, sourceStart: ad, size: aSize, function: function]; SlowSampleMapOps.Move[sampleMap: sa, destStart: aMin, sourceStart: ad, size: aSize, function: function, goodDest: NIL]; lastOp _ move; }; 2 => { Transfer[dest: a, destStart: aMin, source: [b, bMin, bSize], function: function]; SlowSampleMapOps.Transfer[dest: sa, destStart: aMin, source: [sb, bMin, bSize], function: function, goodDest: NIL]; lastOp _ transfer; }; 3 => { IF value = 0 THEN value _ 123456B; -- don't want 0 gray fill Fill[dest: [a, aMin, aSize], value: value, function: function]; SlowSampleMapOps.Fill[dest: [sa, aMin, aSize], value: value, function: function, goodDest: [NIL, [0, 0], [0, 0] ] ]; lastOp _ fill; }; 4 => { s0: INTEGER _ INTEGER[Rand[100]]-50; f0: INTEGER _ INTEGER[Rand[100]]-50; phase: NAT _ Rand[bSize.f]*Rand[1]; tile: SampleMap ~ FromSubMap[[b, bMin, bSize]]; slowTile: SampleMap ~ FromSubMap[[sb, bMin, bSize]]; IF tile.sSize > 0 AND tile.fSize > 0 THEN { lastOp _ tile; TileBox[dest: a, start: aMin, size: aSize, source: tile, s0: s0, f0: f0, phase: phase, function: function]; SlowSampleMapOps.TileBox[dest: sa, start: aMin, size: aSize, source: slowTile, s0: s0, f0: f0, phase: phase, function: function, goodDest: NIL]; } ELSE lastOp _ none; }; 5 => { SkewRotate[FromSubMap[[a, aMin, aSize]], FromSubMap[[b, bMin, bSize]], FromSubMap[[sa, aMin, aSize]], FromSubMap[[b, bMin, bSize]] ]; lastOp _ rotate; }; ENDCASE => ERROR; doOpCountVec[lastOp] _ doOpCountVec[lastOp] + 1; RETURN[function, lastOp]; }; AddressInit: PROC[a: SampleMap, inc: INTEGER, value: WORD] = TRUSTED { sBase: LONG POINTER TO WORD _ LOOPHOLE[a.base.word]; wordsRemaining, nWords: LONG CARDINAL; WITH a.ref SELECT FROM x: CountedVM.Handle => nWords _ x.words; ENDCASE => nWords _ SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample]; IF nWords < 256 THEN { FOR j: LONG CARDINAL IN [0..nWords) DO sBase^ _ value; sBase _ sBase + 1; value _ value + inc; ENDLOOP; RETURN }; FOR i: LONG CARDINAL _ 0, i+wordsPerPage UNTIL i >= nWords - 1 DO this: WORD _ value; IF nWords >= 511 THEN IF AllocatorOps.quantumMap[LOOPHOLE[value]] THEN ERROR; IF wordsRemaining < wordsPerPage THEN { FOR j: LONG CARDINAL IN [0..wordsRemaining) DO sBase^ _ this; sBase _ sBase + 1; this _ this + inc; ENDLOOP } ELSE { FOR j: INTEGER IN [0..wordsPerPage) DO sBase^ _ this; sBase _ sBase + 1; this _ this + inc; ENDLOOP; }; value _ value + 1; wordsRemaining _ wordsRemaining - wordsPerPage; ENDLOOP; }; MakeAddressPattern: PROC[a, sa: SampleMap, inc: INTEGER] = TRUSTED { sBase: LONG POINTER TO WORD _ LOOPHOLE[a.base.word]; tBase: LONG POINTER TO WORD _ LOOPHOLE[sa.base.word]; value: WORD _ Basics.DoubleShiftRight[LOOPHOLE[a.base.word], 8].lo; nWords: LONG CARDINAL = SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample]; wordsRemaining: LONG CARDINAL _ nWords; IF nWords < 256 THEN { FOR j: LONG CARDINAL IN [0..nWords) DO sBase^ _ tBase^ _ value; sBase _ sBase + 1; tBase _ tBase + 1; value _ value + inc; ENDLOOP; RETURN }; FOR i: LONG CARDINAL _ 0, i+wordsPerPage UNTIL i >= nWords - 1 DO this: WORD _ value; IF nWords >= 511 THEN IF AllocatorOps.quantumMap[LOOPHOLE[value]] THEN ERROR; IF wordsRemaining < wordsPerPage THEN { FOR j: LONG CARDINAL IN [0..wordsRemaining) DO sBase^ _ tBase^ _ this; sBase _ sBase + 1; tBase _ tBase + 1; this _ this + inc; ENDLOOP } ELSE { FOR j: INTEGER IN [0..wordsPerPage) DO sBase^ _ tBase^ _ this; sBase _ sBase + 1; tBase _ tBase + 1; this _ this + inc; ENDLOOP; }; wordsRemaining _ wordsRemaining - wordsPerPage; value _ value + 1; ENDLOOP; }; MakeSimpleUpPattern: PROC[a, sa: SampleMap] = TRUSTED { sBase: LONG POINTER TO WORD _ LOOPHOLE[a.base.word]; tBase: LONG POINTER TO WORD _ LOOPHOLE[sa.base.word]; nWords: LONG CARDINAL = SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample]; FOR i: LONG CARDINAL IN [0.. nWords) DO sBase^ _ tBase^ _ LOOPHOLE[i, Basics.LongNumber].lo; sBase _ sBase + 1; tBase _ tBase + 1; ENDLOOP; }; MakeSimpleDownPattern: PROC[a, sa: SampleMap] = TRUSTED { sBase: LONG POINTER TO WORD _ LOOPHOLE[a.base.word]; tBase: LONG POINTER TO WORD _ LOOPHOLE[sa.base.word]; nWords: LONG CARDINAL = SampleMapOps.ComputeWords[sSize: a.sSize, fSize: a.fSize, bitsPerSample: a.bitsPerSample]; val: WORD _ 177777B; FOR i: LONG CARDINAL IN [0.. nWords) DO sBase^ _ tBase^ _ val; sBase _ sBase + 1; tBase _ tBase + 1; val _ val - 1; ENDLOOP; }; MakePattern: PROC[s, t: SampleMap, nWords: LONG CARDINAL, value: WORD] = TRUSTED { sBase: LONG POINTER TO WORD _ LOOPHOLE[s.base.word]; tBase: LONG POINTER TO WORD _ LOOPHOLE[t.base.word]; alt: WORD _ IF value = 0 THEN 0 ELSE Basics.BITNOT[value]; alt2: WORD _ IF value = 0 THEN 0 ELSE Basics.BITSHIFT[value, -3]; temp: WORD _ alt2; FOR i: LONG CARDINAL IN [0..nWords/2) DO sBase^ _ value; tBase^ _ value; sBase _ sBase + 1; tBase _ tBase + 1; sBase^ _ alt; tBase^ _ alt; sBase _ sBase + 1; tBase _ tBase + 1; temp _ value; value _ alt; alt _ alt2; alt2 _ temp; ENDLOOP; }; ReallyCopy: PROC[from, to: SampleMap, nWords: INT] = TRUSTED { fromBase: LONG POINTER TO WORD _ LOOPHOLE[from.base.word]; toBase: LONG POINTER TO WORD _ LOOPHOLE[to.base.word]; FOR i: INT IN [0..nWords) DO toBase^ _ fromBase^; toBase _ toBase + 1; fromBase _ fromBase + 1; ENDLOOP; }; TestEquality: PROC[a, sa: SampleMap, nWords: LONG CARDINAL] RETURNS[firstBad, num: LONG CARDINAL] = TRUSTED { aBase: LONG POINTER TO WORD _ LOOPHOLE[a.base.word]; saBase: LONG POINTER TO WORD _ LOOPHOLE[sa.base.word]; firstBad _ num _ 0; FOR i: LONG CARDINAL IN [0..nWords) DO IF aBase^ # saBase^ THEN IF (num _ num + 1) = 1 THEN firstBad _ i; aBase _ aBase + 1; saBase _ saBase + 1; ENDLOOP; }; Srt: Commander.CommandProc = { cv: CountVec; m, n: INT _ 0; [] _ CommandTool.Parse[cmd]; m _ IntFromCmd[cmd]; IF m = -1 THEN RETURN; n _ IntFromCmd[cmd]; IF n = -1 THEN RETURN; cv _ LongTest[cmd, m, n]; cmd.out.PutF["\nnone: %g, putSample: %g, move: %g, transfer: %g, ", IO.int[cv[none]], IO.int[cv[putSample]], IO.int[cv[move]], IO.int[cv[transfer]] ]; cmd.out.PutF["fill: %g, tile: %g, rotate: %g\n", IO.int[cv[fill]], IO.int[cv[tile]], IO.int[cv[rotate]] ]; }; Skew: Commander.CommandProc = { cv: CountVec; m, n: INT _ 0; [] _ CommandTool.Parse[cmd]; m _ IntFromCmd[cmd]; IF m = -1 THEN RETURN; n _ IntFromCmd[cmd]; IF n = -1 THEN RETURN; cv _ SkewTest[cmd, m, n]; cmd.out.PutF["\nnone: %g, putSample: %g, move: %g, transfer: %g, ", IO.int[cv[none]], IO.int[cv[putSample]], IO.int[cv[move]], IO.int[cv[transfer]] ]; cmd.out.PutF["fill: %g, tile: %g, rotate: %g\n", IO.int[cv[fill]], IO.int[cv[tile]], IO.int[cv[rotate]] ]; }; FillTest: Commander.CommandProc = { n, done: INT _ 0; [] _ CommandTool.Parse[cmd]; n _ IntFromCmd[cmd]; IF n = -1 THEN RETURN; done _ DoFillTest[cmd, n]; cmd.out.PutF["\n %g fill tests done\n", IO.int[done] ]; }; IntFromCmd: PROC[cmd: Commander.Handle] RETURNS[n: INT] = { arg: Rope.ROPE = CommandTool.NextArgument[cmd]; n _ -1; n _ Convert.IntFromRope[arg ! Convert.Error => CONTINUE ]; IF n = -1 THEN cmd.out.PutF["\nCouldn't parse \"%g\" as a number - quitting\n", IO.rope[arg] ] }; Commander.Register["srt", Srt, "Run tests of BitBltOpsImpl"]; Commander.Register["skew", Skew, "Run skew tests of BitBltOpsImpl"]; Commander.Register["fill", FillTest, "Run fill tests of BitBltOpsImpl"]; END.