DIRECTORY AlpineFS, BasicTime USING [GetClockPulses, GMT, Now, Period, Pulses, PulsesToMicroseconds], Commander USING [CommandProc, Handle, Register], FileStream USING [ErrorFromStream, FinalizationProc, GetFinalizationProc, GetStreamClassData, OpenFileFromStream, SetFinalizationProc, SetStreamClassData, SaveStreamError], FileStreamTestInterface USING [ OneTest ], FileStats USING [Data, GetData], FS, IO, Basics USING [LongNumber, LowByte, UnsafeBlock], Process USING [Pause], Random USING [Create, NextInt, ChooseInt, RandomStream], Real USING [PairToReal, SqRt], Rope USING [Cat, Find, ROPE], UserCredentials USING [Get], VM; FileStreamTestImpl: PROGRAM IMPORTS AlpineFS, BasicTime, Commander, FileStats, FileStream, FileStreamTestInterface, FS, IO, I: Basics, Process, RAN: Random, Real, Rope, UserCredentials, VM EXPORTS FileStreamTestInterface = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; dpy: PUBLIC STREAM ; fileSystem: {local, alpine} _ local; fileNamePrefix: ROPE _ NIL; FilePos: INT ; CatchCount: INT ; -- for ChaseBuffers StopChase: BOOL _ FALSE ; randomDataBlockSize: CARDINAL = 1000; maxFileBytes: LONG CARDINAL _ VM.BytesForPages[140] + 1; randomSeed: CARDINAL _ 12314B; chaseCount: INT = 800000 ; backupChaseCount: INT = 30000 ; debugTrace: BOOL _ FALSE; GoSlow: BOOL _ FALSE; Alarm: SIGNAL = CODE; TickStop: SIGNAL = CODE; WordCount: PROC [fileName: ROPE, vmPagesPerBuffer: INT [1 .. 128], nBuffers: INT [1 .. 4]] = { totalWordCount: INT _ 0; totalLineCount: INT _ 0; headerWritten: BOOL _ FALSE; verbose: BOOL _ TRUE; Start: BasicTime.GMT _ BasicTime.Now[]; Finish: BasicTime.GMT ; in: IO.STREAM _ StreamOpen[fileName: fileName, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] ! FS.Error => GOTO openFailed ]; charCount, wordCount, newLineCount: INT; dpy.PutF["\n\n\nStart of Word Count Test: vmPages: %g, nBuffers: %g\n\n\n", IO.int[vmPagesPerBuffer], IO.int[nBuffers]]; [charCount, wordCount, newLineCount] _ CountFile[in]; totalWordCount _ totalWordCount + wordCount; totalLineCount _ totalLineCount + newLineCount; in.Close[]; in _ NIL ; IF verbose AND ~headerWritten THEN { headerWritten _ TRUE; dpy.PutF["Lines\tWords\t\tFile\n"]; }; dpy.PutF["%6d\t%6d\t\t%g\n\n\n", IO.int[newLineCount], IO.int[wordCount], IO.rope[fileName]]; Finish _ BasicTime.Now[]; dpy.PutF["\n\n Seconds: %g\n", IO.int[BasicTime.Period[Start, Finish]]]; EXITS openFailed => dpy.PutF["Could not open \"%g\"\n\n\n", IO.rope[fileName]]; }; CountFile: PROC[ file: IO.STREAM ] RETURNS [ charCount: INT _ 0, wordCount: INT _ 0, newLineCount: INT _ 0 ] = { State: TYPE = { inWord, inJunk, oneNull }; state: State _ inJunk; DO c: CHAR _ IO.GetChar[file ! IO.EndOfStream => GOTO eof]; SELECT c FROM IN ['0..'9], IN ['A..'Z], IN ['a..'z] => IF state ~= inWord THEN { state _ inWord; wordCount _ wordCount + 1; }; = 0C => IF state = oneNull THEN EXIT ELSE state _ oneNull; ENDCASE => { state _ inJunk; IF c = '\n THEN newLineCount _ newLineCount + 1; }; charCount _ charCount + 1; REPEAT eof => NULL; ENDLOOP; }; TypeAFile: PROC[fileName: ROPE] = { readStream: IO.STREAM _ StreamOpen[fileName: fileName]; DO c: CHAR _ IO.GetChar[readStream ! IO.EndOfStream => GOTO eof]; dpy.PutF["%g",IO.char[c]]; REPEAT eof => NULL; ENDLOOP; }; ChaseBuffers: PROC[fileName: ROPE, vmPagesPerBuffer: INT [1 .. 128], nBuffers: INT [1 .. 4], readPause: INT _ 2, writePause: INT _ 1]= { randomStream: RAN.RandomStream; Start: BasicTime.GMT _ BasicTime.Now[]; Finish: BasicTime.GMT ; biggie: CARDINAL ; writeStream: IO.STREAM _ StreamOpen[fileName: fileName, accessOptions: $create, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] ]; process: PROCESS ; FilePos _ 0 ; CatchCount _ 0 ; dpy.PutF["\n\n\n\nStart of Chase Buffers test: vmPages: %g, nBuffers: %g\n", IO.int[vmPagesPerBuffer], IO.int[nBuffers]]; dpy.PutF[" readPause: %g, writePause: %g\n\n\n", IO.int[readPause], IO.int[writePause]]; process _ FORK readprocess[writeStream,readPause]; randomStream _ RAN.Create[seed: randomSeed]; UNTIL FilePos >= chaseCount DO fill: INT ; fill _ randomStream.ChooseInt[min: 1, max: 311]; biggie _ FilePos MOD 127 ; FOR i:INT IN [1..fill] DO char: CHAR ; TRUSTED {char _ LOOPHOLE[I.LowByte[biggie]] ;}; IF StopChase THEN Alarm[]; writeStream.PutChar[ char ]; FilePos _ FilePos + 1; IF (biggie _ biggie + 1 ) >= 127 THEN biggie _ 0 ; ENDLOOP; IF FilePos >= chaseCount THEN { IF StopChase THEN Alarm[]; }; IF fill < 13 AND writePause > 0 THEN Process.Pause[writePause]; ENDLOOP; IF NOT writeStream.EndOf THEN Alarm[]; writeStream.Flush[]; writeStream.Close[]; writeStream _ NIL ; dpy.PutF["\nAbout to JOIN\n"]; TRUSTED {JOIN process ;}; Finish _ BasicTime.Now[]; dpy.PutF["\n\n Seconds: %g\n", IO.int[BasicTime.Period[Start, Finish]]]; dpy.PutF["\nRead Process caught writer %g times\nEnd of Chase Buffers test\n", IO.int[CatchCount]]; }; readprocess: PROC [ writestream: IO.STREAM , readPause: INT] = { myPos: INT _ 0 ; dupMyPos: INT _ 0 ; dupFilePos: INT ; biggie: CARDINAL _ 0 ; readStream: IO.STREAM _ FS.StreamFromOpenStream[writestream]; readStream.SetIndex[0]; IF readStream.CharsAvail <= 0 THEN {StopChase _ TRUE; Alarm[]}; WHILE myPos < chaseCount DO dupFilePos _ FilePos ; IF myPos = FilePos THEN { CatchCount _ CatchCount + 1 ; IF readPause > 0 THEN Process.Pause[readPause]; } ELSE { readChar, char: CHAR ; TRUSTED {char _ LOOPHOLE[I.LowByte[biggie]] ;}; IF readStream.EndOf THEN Alarm[]; readChar _ readStream.GetChar[! IO.EndOfStream => {StopChase _ TRUE; Alarm[]} ]; myPos _ myPos + 1 ; dupMyPos _ dupMyPos + 1 ; IF myPos # dupMyPos THEN {StopChase _ TRUE; Alarm[]} ; IF readChar # char THEN Alarm[] ; IF (biggie _ biggie + 1 ) >= 127 THEN biggie _ 0 ; }; ENDLOOP; myPos _ chaseCount-1 ; biggie _ myPos MOD 127 ; WHILE myPos > (chaseCount-backupChaseCount) DO char: CHAR ; TRUSTED {char _ LOOPHOLE[I.LowByte[biggie]] ;}; readStream.Backup[char: char]; myPos _ myPos - 1 ; IF (biggie = 0 ) THEN biggie _ 126 ELSE biggie _ biggie - 1 ; IF readStream.EndOf THEN Alarm[]; ENDLOOP; readStream.Reset[]; IF NOT readStream.EndOf THEN Alarm[]; readStream.Close[]; readStream_ NIL ; }; DropSomeStreams: PROC[fileName1: ROPE, fileName2: ROPE] = { writeStream1, readStream1, writeStream2: IO.STREAM ; dpy.PutF["\n\nStart of DropSomeStreams test:"]; writeStream1 _ StreamOpen[fileName: fileName1, accessOptions: $create]; readStream1 _ FS.StreamFromOpenStream[writeStream1]; writeStream2 _ StreamOpen[fileName: fileName2, accessOptions: $create]; writeStream1 _ NIL ; readStream1 _ NIL ; writeStream2 _ NIL ; dpy.PutF["\n\nEnd of DropSomeStreams test:"]; }; extendCount: INT _ 0 ; didExtend: BOOL _ FALSE ; extendSize: ARRAY [1 .. 6] OF INT _ [ 5120+512, 10240, 10240+512, 20480, 20480, 1048576+512] ; myExtend: INT _ 0 ; extend: SAFE PROC [ count: FS.ByteCount] RETURNS [FS.ByteCount] = TRUSTED { IF extendCount < 6 THEN extendCount _ extendCount + 1 ; didExtend _ TRUE ; myExtend _ extendSize[extendCount]; RETURN[extendSize[extendCount]] }; ExtendFileTest: PROC[fileName: ROPE, vmPagesPerBuffer: INT [1 .. 128] _ 4 , nBuffers: INT [1 .. 4] _ 2 , vmPagesPerWrite: INT [1 .. 128] _ 4 ] = { bytesLeft: INT _ 1048576 ; bytesPerFilePage: INT = FS.BytesForPages[1]; unsafeDataBlock: I.UnsafeBlock ; UnsafeBlockInterval: VM.Interval; writeStream: IO.STREAM ; writeFile: FS.OpenFile ; Start: BasicTime.GMT ; Finish: BasicTime.GMT ; startReadFileData, startWriteFileData, finishReadFileData, finishWriteFileData: FileStats.Data ; dpy.PutF["\n\nStart of extend file test:"]; dpy.PutF["\n vmPages: %g, nBuffers: %g, pagesPerWrite %g\n", IO.int[vmPagesPerBuffer], IO.int[nBuffers], IO.int[vmPagesPerWrite] ]; UnsafeBlockInterval _ VM.Allocate[count: vmPagesPerWrite]; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; unsafeDataBlock.count _ vmPagesPerWrite*bytesPerFilePage; startReadFileData _ FileStats.GetData[read]; startWriteFileData _ FileStats.GetData[write]; Start _ BasicTime.Now[]; writeStream _ StreamOpen[fileName: fileName, accessOptions: $create, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] , createByteCount: 5120, extendFileProc: extend ]; writeFile _ FS.OpenFileFromStream[writeStream]; WHILE bytesLeft > 0 DO writeStream.UnsafePutBlock[unsafeDataBlock]; IF didExtend THEN { pageAllocation: VM.PageNumber; byteLength: FS.ByteCount ; didExtend _ FALSE ; [pages: pageAllocation, bytes: byteLength] _ writeFile.GetInfo[]; dpy.PutF["\n Extend to : %g pageAllocation %g, byteLength %g", IO.int[myExtend], IO.int[pageAllocation], IO.int[byteLength] ]; }; bytesLeft _ bytesLeft - unsafeDataBlock.count ; ENDLOOP; writeStream.Close[]; writeStream _ NIL ; Finish _ BasicTime.Now[]; finishReadFileData _ FileStats.GetData[read]; finishWriteFileData _ FileStats.GetData[write]; TRUSTED{VM.Free[UnsafeBlockInterval]}; dpy.PutF["\n\n Seconds: %g File reads %g pages %g, Writes %g pages %g\n", IO.int[BasicTime.Period[Start, Finish]], IO.int[finishReadFileData.calls-startReadFileData.calls], IO.int[finishReadFileData.pages-startReadFileData.pages], IO.int[finishWriteFileData.calls-startWriteFileData.calls], IO.int[finishWriteFileData.pages-startWriteFileData.pages] ]; dpy.PutF[" reads/sec %g, writes/sec %g\n", IO.int[ (finishReadFileData.calls-startReadFileData.calls)/BasicTime.Period[Start, Finish]], IO.int[ (finishWriteFileData.calls-startWriteFileData.calls)/BasicTime.Period[Start, Finish]] ]; dpy.PutF["\nEnd of extend file test\n"]; }; WriteAMegabyte: PROC[fileName: ROPE, vmPagesPerBuffer: INT [1 .. 128], nBuffers: INT [1 .. 4], vmPagesPerWrite: INT [1 .. 128]] = { extend: SAFE PROC [ count: FS.ByteCount] RETURNS [FS.ByteCount] = TRUSTED { RETURN[count + 20480] }; Start: BasicTime.GMT ; Finish: BasicTime.GMT ; startPulse: BasicTime.Pulses ; endPulse: BasicTime.Pulses ; requestNo: INT ; microsecondsPerRequest: ARRAY [1..100] OF INT ; startReadFileData, startWriteFileData, finishReadFileData, finishWriteFileData: FileStats.Data ; bytesLeft: INT _ 1048576 ; bytesPerFilePage: INT = FS.BytesForPages[1]; unsafeDataBlock: I.UnsafeBlock ; UnsafeBlockInterval: VM.Interval; writeStream: IO.STREAM ; dpy.PutF["\n\nStart of write megabyte test:"]; dpy.PutF["\n vmPages: %g, nBuffers: %g, pagesPerWrite %g\n", IO.int[vmPagesPerBuffer], IO.int[nBuffers], IO.int[vmPagesPerWrite] ]; UnsafeBlockInterval _ VM.Allocate[count: vmPagesPerWrite]; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; unsafeDataBlock.count _ vmPagesPerWrite*bytesPerFilePage; startReadFileData _ FileStats.GetData[read]; startWriteFileData _ FileStats.GetData[write]; Start _ BasicTime.Now[]; writeStream _ StreamOpen[fileName: fileName, accessOptions: $create, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] , createByteCount: 1048576 ]; requestNo _ 1 ; startPulse _ BasicTime.GetClockPulses[] ; WHILE bytesLeft > 0 DO writeStream.UnsafePutBlock[unsafeDataBlock]; endPulse _ BasicTime.GetClockPulses[] ; IF requestNo <= 100 THEN { microsecondsPerRequest[requestNo] _ BasicTime.PulsesToMicroseconds[endPulse - startPulse] ; startPulse _ endPulse ; requestNo _ requestNo + 1 ; }; bytesLeft _ bytesLeft - unsafeDataBlock.count ; ENDLOOP; writeStream.Close[]; writeStream _ NIL ; Finish _ BasicTime.Now[]; finishReadFileData _ FileStats.GetData[read]; finishWriteFileData _ FileStats.GetData[write]; TRUSTED{VM.Free[UnsafeBlockInterval]}; dpy.PutF["\n\n Seconds: %g File reads %g pages %g, Writes %g pages %g\n", IO.int[BasicTime.Period[Start, Finish]], IO.int[finishReadFileData.calls-startReadFileData.calls], IO.int[finishReadFileData.pages-startReadFileData.pages], IO.int[finishWriteFileData.calls-startWriteFileData.calls], IO.int[finishWriteFileData.pages-startWriteFileData.pages] ]; dpy.PutF[" reads/sec %g, writes/sec %g\n", IO.int[ (finishReadFileData.calls-startReadFileData.calls)/BasicTime.Period[Start, Finish]], IO.int[ (finishWriteFileData.calls-startWriteFileData.calls)/BasicTime.Period[Start, Finish]] ]; FOR requestNo IN [1..100] DO IF requestNo MOD 10 = 1 THEN dpy.PutF["%g-%g: ",IO.int[requestNo], IO.int[requestNo+9]]; dpy.PutF["%g ",IO.int[microsecondsPerRequest[requestNo]]]; IF requestNo MOD 10 = 0 THEN dpy.PutF["\n"]; ENDLOOP; dpy.PutF["\nEnd of WriteAMegabyte\n"]; }; ReadAMegabyte: PROC[fileName: ROPE, pause: INT, vmPagesPerBuffer: INT [1 .. 128], nBuffers: INT [1 .. 4], vmPagesPerRead: INT [1 .. 128]] = { randomStream: RAN.RandomStream; Start: BasicTime.GMT ; Finish: BasicTime.GMT ; startReadFileData, startWriteFileData, finishReadFileData, finishWriteFileData: FileStats.Data ; bytesLeft: INT _ 1048576 ; readCount: INT ; realOne: REAL _ Real.PairToReal[1,0]; microsecondsPerRequest: ARRAY [1..100] OF INT ; requestNo: INT ; startPulse: BasicTime.Pulses ; endPulse: BasicTime.Pulses ; bytesPerFilePage: INT = FS.BytesForPages[1]; unsafeDataBlock: I.UnsafeBlock ; UnsafeBlockInterval: VM.Interval; readStream: IO.STREAM ; randomStream _ RAN.Create[seed: randomSeed]; dpy.PutF["\n\nStart of read megabyte test:"]; dpy.PutF["\n pause %g, vmPages: %g, nBuffers: %g, pagesPerRead %g\n", IO.int[pause], IO.int[vmPagesPerBuffer], IO.int[nBuffers], IO.int[vmPagesPerRead] ]; UnsafeBlockInterval _ VM.Allocate[count: vmPagesPerRead]; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; unsafeDataBlock.count _ vmPagesPerRead*bytesPerFilePage; startReadFileData _ FileStats.GetData[read]; startWriteFileData _ FileStats.GetData[write]; Start _ BasicTime.Now[]; readStream _ StreamOpen[fileName: fileName, accessOptions: $read, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] ]; readCount _ unsafeDataBlock.count ; requestNo _ 1 ; startPulse _ BasicTime.GetClockPulses[] ; WHILE bytesLeft > 0 DO IF pause >= 0 THEN readCount _ readStream.UnsafeGetBlock[unsafeDataBlock]; endPulse _ BasicTime.GetClockPulses[] ; IF requestNo <= 100 THEN { microsecondsPerRequest[requestNo] _ BasicTime.PulsesToMicroseconds[endPulse - startPulse] ; startPulse _ endPulse ; requestNo _ requestNo + 1 ; }; IF readCount # unsafeDataBlock.count AND unsafeDataBlock.count <= bytesLeft THEN Alarm[]; bytesLeft _ bytesLeft - unsafeDataBlock.count ; IF pause # 0 THEN { zc, nzc: INT _ 0 ; FOR I: INT IN [0..readCount) DO IF unsafeDataBlock.base[I] = 0 THEN zc _ zc +1 ELSE nzc _ nzc + 1; IF randomStream.NextInt[] = zc THEN zc _ zc + 1 ; IF zc = 0 THEN zc _ 1 ; IF zc # 0 THEN nzc _ nzc / zc ; IF (I MOD 64) = 0 THEN realOne _ Real.SqRt[realOne]; ENDLOOP; } ELSE IF pause < 0 THEN Process.Pause[-pause]; ENDLOOP; readStream.Close[]; readStream _ NIL ; Finish _ BasicTime.Now[]; finishReadFileData _ FileStats.GetData[read]; finishWriteFileData _ FileStats.GetData[write]; TRUSTED{VM.Free[UnsafeBlockInterval]}; dpy.PutF["\n\n Seconds: %g File reads %g pages %g, Writes %g pages %g\n", IO.int[BasicTime.Period[Start, Finish]], IO.int[finishReadFileData.calls-startReadFileData.calls], IO.int[finishReadFileData.pages-startReadFileData.pages], IO.int[finishWriteFileData.calls-startWriteFileData.calls], IO.int[finishWriteFileData.pages-startWriteFileData.pages] ]; dpy.PutF[" reads/sec %g, writes/sec %g\n", IO.int[ (finishReadFileData.calls-startReadFileData.calls)/BasicTime.Period[Start, Finish]], IO.int[ (finishWriteFileData.calls-startWriteFileData.calls)/BasicTime.Period[Start, Finish]] ]; dpy.PutF["Times to do request\n"]; FOR requestNo IN [1..100] DO IF requestNo MOD 10 = 1 THEN dpy.PutF["%g-%g: ",IO.int[requestNo], IO.int[requestNo+9]]; dpy.PutF["%g ",IO.int[microsecondsPerRequest[requestNo]]]; IF requestNo MOD 10 = 0 THEN dpy.PutF["\n"]; ENDLOOP; dpy.PutF["\nEnd of ReadAMegabyte\n"]; }; WriteAMegabyteWithPattern: PROC[fileName: ROPE, vmPagesPerBuffer: INT [1 .. 128], nBuffers: INT [1 .. 4], vmPagesPerWrite: INT [1 .. 1024]] = { extend: SAFE PROC [ count: FS.ByteCount] RETURNS [FS.ByteCount] = TRUSTED { RETURN[count + 20480] }; Start: BasicTime.GMT ; Finish: BasicTime.GMT ; startReadFileData, startWriteFileData, finishReadFileData, finishWriteFileData: FileStats.Data ; bytesLeft: INT _ 1048576 ; bytesPerFilePage: INT = FS.BytesForPages[1]; unsafeDataBlock: I.UnsafeBlock ; UnsafeBlockInterval: VM.Interval; writeStream: IO.STREAM ; dpy.PutF["\n\nStart of write megabyte with pattern test:"]; dpy.PutF["\n vmPages: %g, nBuffers: %g, pagesPerWrite %g\n", IO.int[vmPagesPerBuffer], IO.int[nBuffers], IO.int[vmPagesPerWrite] ]; UnsafeBlockInterval _ VM.Allocate[count: vmPagesPerWrite]; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; unsafeDataBlock.count _ vmPagesPerWrite*bytesPerFilePage; startReadFileData _ FileStats.GetData[read]; startWriteFileData _ FileStats.GetData[write]; Start _ BasicTime.Now[]; writeStream _ StreamOpen[fileName: fileName, accessOptions: $create, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] , createByteCount: 1048576 ]; WHILE bytesLeft > 0 DO byteNo: INT _ 1048576 - bytesLeft ; biggie: CARDINAL _ byteNo MOD 127 ; charNo: INT ; charNo _ 0 ; FOR requestNo: INT IN [0..unsafeDataBlock.count) DO char: CHAR ; TRUSTED {char _ LOOPHOLE[I.LowByte[biggie]] ;}; IF charNo >= 1024 THEN { charNo _ charNo - 1024; unsafeDataBlock.base _ unsafeDataBlock.base + 512 ; }; unsafeDataBlock.base[charNo] _ LOOPHOLE[char] ; byteNo _ byteNo + 1 ; IF (biggie _ biggie + 1 ) >= 127 THEN biggie _ 0 ; charNo _ charNo + 1 ; ENDLOOP; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; writeStream.UnsafePutBlock[unsafeDataBlock]; bytesLeft _ bytesLeft - unsafeDataBlock.count ; ENDLOOP; writeStream.Close[]; writeStream _ NIL ; Finish _ BasicTime.Now[]; finishReadFileData _ FileStats.GetData[read]; finishWriteFileData _ FileStats.GetData[write]; TRUSTED{VM.Free[UnsafeBlockInterval]}; dpy.PutF["\n\n Seconds: %g File reads %g pages %g, Writes %g pages %g\n", IO.int[BasicTime.Period[Start, Finish]], IO.int[finishReadFileData.calls-startReadFileData.calls], IO.int[finishReadFileData.pages-startReadFileData.pages], IO.int[finishWriteFileData.calls-startWriteFileData.calls], IO.int[finishWriteFileData.pages-startWriteFileData.pages] ]; dpy.PutF[" reads/sec %g, writes/sec %g\n", IO.int[ (finishReadFileData.calls-startReadFileData.calls)/BasicTime.Period[Start, Finish]], IO.int[ (finishWriteFileData.calls-startWriteFileData.calls)/BasicTime.Period[Start, Finish]] ]; dpy.PutF["\nEnd of WriteAMegabyteWithPattern\n"]; }; ReadAMegabyteWithPattern: PROC[fileName: ROPE, pause: INT, vmPagesPerBuffer: INT [1 .. 128], nBuffers: INT [1 .. 4], vmPagesPerRead: INT [1 .. 1024]] = { Start: BasicTime.GMT ; Finish: BasicTime.GMT ; startReadFileData, startWriteFileData, finishReadFileData, finishWriteFileData: FileStats.Data ; bytesLeft: INT _ 1048576 ; byteNo: INT _ 0 ; readCount: INT ; errorCount: INT _ 0 ; requestNo: INT ; biggie: CARDINAL ; bytesPerFilePage: INT = FS.BytesForPages[1]; unsafeDataBlock: I.UnsafeBlock ; UnsafeBlockInterval: VM.Interval; readStream: IO.STREAM ; dpy.PutF["\n\nStart of read megabyte with pattern test:"]; dpy.PutF["\n pause %g, vmPages: %g, nBuffers: %g, pagesPerRead %g\n", IO.int[pause], IO.int[vmPagesPerBuffer], IO.int[nBuffers], IO.int[vmPagesPerRead] ]; UnsafeBlockInterval _ VM.Allocate[count: vmPagesPerRead]; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; unsafeDataBlock.count _ vmPagesPerRead*bytesPerFilePage; startReadFileData _ FileStats.GetData[read]; startWriteFileData _ FileStats.GetData[write]; Start _ BasicTime.Now[]; readStream _ StreamOpen[fileName: fileName, accessOptions: $read, streamBufferParms: [vmPagesPerBuffer: vmPagesPerBuffer, nBuffers: nBuffers ] ]; readCount _ unsafeDataBlock.count ; requestNo _ 1 ; WHILE bytesLeft > 0 DO charNo: INT ; IF pause >= 0 THEN readCount _ readStream.UnsafeGetBlock[unsafeDataBlock]; IF readCount # unsafeDataBlock.count AND unsafeDataBlock.count <= bytesLeft THEN Alarm[]; biggie _ byteNo MOD 127 ; charNo _ 0 ; FOR requestNo: INT IN [0..readCount) DO char: CHAR ; TRUSTED {char _ LOOPHOLE[I.LowByte[biggie]] ;}; IF charNo >= 1024 THEN { charNo _ charNo - 1024; unsafeDataBlock.base _ unsafeDataBlock.base + 512 ; }; IF unsafeDataBlock.base[charNo] # LOOPHOLE[char] THEN { dpy.PutF["\n >>>> byte %g, was : %g, should be: %g", IO.int[byteNo], IO.char[LOOPHOLE[unsafeDataBlock.base[charNo]]], IO.char[char]]; errorCount _ errorCount + 1 ; IF errorCount > 20 THEN bytesLeft _ 0 ; }; byteNo _ byteNo + 1 ; IF (biggie _ biggie + 1 ) >= 127 THEN biggie _ 0 ; charNo _ charNo + 1 ; ENDLOOP; unsafeDataBlock.base _ VM.AddressForPageNumber[UnsafeBlockInterval.page]; bytesLeft _ bytesLeft - unsafeDataBlock.count ; ENDLOOP; readStream.Close[]; readStream _ NIL ; Finish _ BasicTime.Now[]; finishReadFileData _ FileStats.GetData[read]; finishWriteFileData _ FileStats.GetData[write]; TRUSTED{VM.Free[UnsafeBlockInterval]}; dpy.PutF["\n\n Seconds: %g File reads %g pages %g, Writes %g pages %g\n", IO.int[BasicTime.Period[Start, Finish]], IO.int[finishReadFileData.calls-startReadFileData.calls], IO.int[finishReadFileData.pages-startReadFileData.pages], IO.int[finishWriteFileData.calls-startWriteFileData.calls], IO.int[finishWriteFileData.pages-startWriteFileData.pages] ]; dpy.PutF[" reads/sec %g, writes/sec %g\n", IO.int[ (finishReadFileData.calls-startReadFileData.calls)/BasicTime.Period[Start, Finish]], IO.int[ (finishWriteFileData.calls-startWriteFileData.calls)/BasicTime.Period[Start, Finish]] ]; dpy.PutF["Times to do request\n"]; dpy.PutF["\nEnd of ReadAMegabyteWithPattern\n"]; }; nullFinalizationProc: FileStream.FinalizationProc = TRUSTED { dpy.PutF["\nnullFinalizationProc got called:"]; }; ErrorTests: PROC[fileName: ROPE] = { writeStream: IO.STREAM ; hitEOF: BOOL ; dpy.PutF["\n\nStart of error tests:"]; writeStream _ StreamOpen[fileName: fileName, accessOptions: $create, streamBufferParms: [vmPagesPerBuffer: 4, nBuffers: 2 ] , createByteCount: 40000 ]; FOR I:INT IN [0 .. 55) DO writeStream.PutChar[0C]; ENDLOOP; hitEOF _ FALSE ; [] _ writeStream.GetChar[! IO.EndOfStream => {hitEOF _ TRUE ; CONTINUE;}]; IF NOT hitEOF THEN { dpy.PutF["\n OOPS: should have hit eof\n"];}; IF FileStream.ErrorFromStream[ writeStream ] # [ok, NIL, NIL] THEN { dpy.PutF["\n OOPS: should have NIL error at first\n"];}; FileStream.SaveStreamError[self: writeStream, error: [bug, NIL, "Some rope"]]; IF FileStream.ErrorFromStream[ writeStream ] = [ok, NIL, NIL] THEN { dpy.PutF["\n OOPS: should have NON-NIL error later\n"];}; IF fileSystem=local THEN BEGIN IF FileStream.GetStreamClassData[ writeStream ] # NIL THEN { dpy.PutF["\n OOPS: should have NIL class data at first\n"];}; FileStream.SetStreamClassData[self: writeStream, data: writeStream]; IF FileStream.GetStreamClassData[ writeStream ] = NIL THEN { dpy.PutF["\n OOPS: should have NON-NIL error later\n"];}; FileStream.SetStreamClassData[self: writeStream, data: NIL]; IF FileStream.GetFinalizationProc[ writeStream ] # NIL THEN { dpy.PutF["\n OOPS: should have NIL FinalizationProc at first\n"];}; FileStream.SetFinalizationProc[self: writeStream, proc: nullFinalizationProc]; IF FileStream.GetFinalizationProc[ writeStream ] = NIL THEN { dpy.PutF["\n OOPS: should have NON-NIL FinalizationProc later\n"];}; END; [] _ FileStream.OpenFileFromStream[ writeStream ]; writeStream.Close[]; dpy.PutF["\nEnd of error tests:"]; }; StreamOpen: PUBLIC SAFE PROC [fileName: ROPE, accessOptions: FS.AccessOptions _ $read, createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ FS.defaultStreamBufferParms, extendFileProc: FS.ExtendFileProc _ NIL] RETURNS [STREAM] = CHECKED BEGIN RETURN [SELECT fileSystem FROM local => FS.StreamOpen[fileName: fileName, accessOptions: accessOptions, createByteCount: createByteCount, streamBufferParms: streamBufferParms, extendFileProc: extendFileProc], alpine => AlpineFS.StreamOpen[name: Rope.Cat[fileNamePrefix, fileName], accessOptions: accessOptions, createByteCount: createByteCount, streamBufferParms: streamBufferParms, extendFileProc: extendFileProc], ENDCASE => ERROR] END; RunReadForever: PROC = { WriteAMegabyteWithPattern["AMegabyte.file", 8, 2, 8]; DO ReadAMegabyteWithPattern["AMegabyte.file", 0, 4, 2, 4]; ENDLOOP; }; RunTests: PROC = { ErrorTests["FileStreamTest.file"]; WriteAMegabyte["AMegabyte.file", 32, 2, 4]; ReadAMegabyte["AMegabyte.file", 0, 1, 1, 1]; ReadAMegabyte["AMegabyte.file", 0, 1, 2, 1]; ReadAMegabyte["AMegabyte.file", 0, 1, 3, 1]; ReadAMegabyte["AMegabyte.file", 0, 1, 4, 1]; ReadAMegabyte["AMegabyte.file", 1, 1, 1, 1]; ReadAMegabyte["AMegabyte.file", -1, 1, 1, 1]; ReadAMegabyte["AMegabyte.file", 1, 1, 2, 1]; -- ReadAMegabyte["AMegabyte.file", 1, 2, 1, 2]; -- ReadAMegabyte["AMegabyte.file", 1, 2, 2, 2]; -- ReadAMegabyte["AMegabyte.file", 1, 4, 1, 4]; -- ReadAMegabyte["AMegabyte.file", 1, 4, 2, 4]; -- ReadAMegabyte["AMegabyte.file", 1, 8, 1, 8]; -- ReadAMegabyte["AMegabyte.file", 1, 8, 2, 8]; -- ReadAMegabyte["AMegabyte.file", 1, 16, 2, 16]; DropSomeStreams["DropStream1.file", "DropStream2.file"] ; ExtendFileTest[fileName: "extendA.file"]; WriteAMegabyte["AMegabyte.file", 1, 1, 1]; WriteAMegabyte["AMegabyte.file", 1, 2, 1]; WriteAMegabyte["AMegabyte.file", 1, 3, 1]; WriteAMegabyte["AMegabyte.file", 1, 4, 1]; WriteAMegabyte["AMegabyte.file", 1, 3, 32]; WriteAMegabyte["AMegabyte.file", 2, 2, 2]; WriteAMegabyte["AMegabyte.file", 4, 2, 1]; WriteAMegabyte["AMegabyte.file", 4, 2, 4]; WriteAMegabyte["AMegabyte.file", 8, 4, 2]; WriteAMegabyte["AMegabyte.file", 16, 1, 1]; WriteAMegabyte["AMegabyte.file", 16, 2, 1]; WriteAMegabyte["AMegabyte.file", 16, 2, 16]; WriteAMegabyte["AMegabyte.file", 16, 2, 32]; WriteAMegabyte["AMegabyte.file", 32, 2, 4]; ReadAMegabyte["AMegabyte.file", 0, 32, 2, 4]; WriteAMegabyteWithPattern["AMegabyte.file", 8, 2, 8]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; WriteAMegabyteWithPattern["AMegabyte.file", 16, 2, 16]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; WriteAMegabyteWithPattern["AMegabyte.file", 5, 2, 16]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; WriteAMegabyteWithPattern["AMegabyte.file", 16, 2, 7]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 32]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 64]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 128]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 256]; WriteAMegabyteWithPattern["AMegabyte.file", 16, 2, 32]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; WriteAMegabyteWithPattern["AMegabyte.file", 16, 2, 64]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; WriteAMegabyteWithPattern["AMegabyte.file", 16, 2, 128]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; WriteAMegabyteWithPattern["AMegabyte.file", 16, 2, 256]; ReadAMegabyteWithPattern["AMegabyte.file", 0, 16, 2, 16]; TypeAFile["FileStreamTest.tioga"]; ChaseBuffers["ChaseBuffers.TestFile", 1, 1]; ChaseBuffers["ChaseBuffers.TestFile", 16, 2]; WordCount["ChaseBuffers.TestFile",16,2]; WordCount["ChaseBuffers.TestFile",1,2]; WordCount["ChaseBuffers.TestFile",1,1]; WordCount["ChaseBuffers.TestFile",11,2]; FileStreamTestInterface.OneTest["FileStreamTest.file"]; WordCount["FileStreamImpl.mesa",16,2]; ChaseBuffers["ChaseBuffers.TestFile", 4, 2, 5, 0]; ChaseBuffers["ChaseBuffers.TestFile", 4, 2, 1, 9]; ChaseBuffers["ChaseBuffers.TestFile", 1, 3]; WordCount["ChaseBuffers.TestFile",8,3]; ChaseBuffers["ChaseBuffers.TestFile", 7, 4]; dpy.PutF["\nEnd of all the Tests!!\n\n\n"]; }; FileStreamTestCmd: Commander.CommandProc = TRUSTED BEGIN initOnly: BOOLEAN _ cmd.commandLine.Find[s2: "Init", case: FALSE]>=0; readForever: BOOLEAN _ cmd.commandLine.Find[s2: "ReadForever", case: FALSE]>=0; fileSystem _ IF cmd.commandLine.Find[s2: "Alpine", case: FALSE]>=0 THEN alpine ELSE local; fileNamePrefix _ SELECT fileSystem FROM local => NIL, alpine => IO.PutFR["[Luther.alpine]<%g>", [rope[UserCredentials.Get[].name]]], ENDCASE => ERROR; dpy _ cmd.out; IF ~initOnly THEN { IF readForever THEN RunReadForever[] ELSE RunTests[]; }; END; Commander.Register[key: "FileStreamTest", proc: FileStreamTestCmd, doc: "FileStreamTest [Init] [Alpine] [ReadForever]\n Init - just init the package, don't run the test\n Alpine - use Alpine rather than local file system\n ReadForever - write a file on the local disk and read it forever"]; END. 4File: FileStreamTestImpl.mesa Last edited by MBrown on July 11, 1983 11:05 pm Last Edited by: Hagmann, December 6, 1983 3:48 pm Last Edited by: Taft, December 1, 1983 4:51 pm Bob Hagmann May 16, 1985 3:35:41 pm PDT Word Count Test - execise preread Expects a file name as the argument, and counts the number of words in the indicated file. Counts the number of words in the indicated stream. Chase Buffers - test parallel buffering logic Creates a reader process to chase a writer process through 1,000,000 bytes of output. Process.Pause[pause] the tests Κη– "cedar" style˜Jšœ™Jšœ/™/Jšœ1™1šœ.™.Icode™'—˜šΟk ˜ J˜ Jšœ œœ-˜QJšœ œ!˜0šœ œ:˜JJ˜J˜Jšœœœ ˜?šœ˜J˜šœœ˜J˜Jšœœ˜/J˜šœ˜Jšœœ˜Jšœ œœ˜/Jšœœ ˜!Jšœ œœ ˜PJ˜J˜Jšœœœ ˜6Jšœœ ˜!Jšœœ ˜2J˜——Jšœ˜—J˜Jšœœ˜šœ'˜.Jšœœ˜ Jšœ œœ˜/J˜J˜Jšœœœ˜=Jšœœ ˜!Jšœ˜—J˜Jšœœœ ˜%J˜Jšœ œ˜J˜J˜—JšŸœœ œ œ˜;˜Jšœ)œœ˜4J˜J˜/JšœG˜GJ˜4JšœG˜GJšœœ˜Jšœœ˜Jšœœ˜J˜-J˜J˜—Jšœ œ˜Jšœ œœ˜šœ œ œœ˜#J˜:—Jšœ œ˜J˜š œœœ œ œœœ˜KJšœœ ˜7Jšœ œ˜J˜#Jšœ˜J˜J˜—šŸœœ œ˜$Jšœœœ˜Cšœœ˜)Jšœ œ ˜Jšœœœ˜,Jšœœ˜ Jšœœ ˜!Jšœ œœ˜Jšœ œ ˜Jšœœ˜Jšœœ˜J˜`J˜+˜IJšœœœ˜F—Jšœœ#˜;Jšœœ0˜IJ˜9J˜,J˜.J˜šœD˜DJ˜NJ˜J˜—Jšœ œ!˜/šœ˜J˜,šœ œ˜Jšœœ ˜Jšœ œ ˜Jšœ œ˜J˜A˜?Jšœœœ˜B—J˜—J˜/Jšœ˜—J˜Jšœœ˜J˜J˜-J˜/Jšœœ˜&˜LJšœ&˜(Jšœ8˜:Jšœ7˜9Jšœ9˜;Jšœ8˜:J˜—˜+JšœZ˜\Jšœ^˜`J˜—J˜(J˜J˜J˜J˜——šŸœœ œ˜$šœœœœ˜^š œœœ œ œœœ˜KJšœ˜J˜—Jšœœ˜Jšœœ˜J˜J˜Jšœ œ˜Jšœœ œœ˜/J˜`Jšœ œ ˜Jšœœœ˜,Jšœœ˜ Jšœœ ˜!Jšœ œœ˜J˜.˜IJšœœœ˜F—Jšœœ#˜;Jšœœ0˜IJ˜9J˜,J˜.J˜šœD˜DJ˜NJ˜—J˜J˜)šœ˜J˜,J˜'šœœ˜˜#J˜7—J˜J˜J˜—J˜/Jšœ˜—J˜Jšœœ˜J˜J˜-J˜/Jšœœ˜&˜LJšœ&˜(Jšœ8˜:Jšœ7˜9Jšœ9˜;Jšœ8˜:J˜—˜+JšœZ˜\Jšœ^˜`—šœ œ œ˜šœ œœœ˜BJšœ˜—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˜-˜KJšœ œœœ˜T—Jšœœ"˜:Jšœœ0˜IJ˜8J˜,J˜.J˜šœA˜AJ˜P—J˜#J˜J˜)šœ˜Jšœ œ8˜JJ˜'šœœ˜˜#J˜7—J˜J˜J˜—šœ#œ#˜KJšœ ˜ —J˜/šœ œ˜Jšœ œ˜š œœœœ˜Jšœœœ œ˜BJšœœ˜1Jšœœ ˜Jšœœ˜Jšœœœ œ˜4Jšœ˜—Jšœ™J˜Jšœœ œ˜-—Jšœ˜—J˜Jšœ œ˜J˜J˜-J˜/Jšœœ˜&˜LJšœ&˜(Jšœ8˜:Jšœ7˜9Jšœ9˜;Jšœ8˜:J˜—˜+JšœZ˜\Jšœ^˜`—J˜"šœ œ œ˜šœ œœœ˜BJšœ˜—Jšœœ)˜;Jšœ œœ˜,Jšœ˜—J˜%J˜J˜J˜J˜J˜——šŸœœ œ˜/šœœœœ˜_š œœœ œ œœœ˜KJšœ˜J˜—Jšœœ˜Jšœœ˜J˜`Jšœ œ ˜Jšœœœ˜,Jšœœ˜ Jšœœ ˜!Jšœ œœ˜J˜;˜IJšœœœ˜F—Jšœœ#˜;Jšœœ0˜IJ˜9J˜,J˜.J˜šœD˜DJ˜NJ˜—šœ˜Jšœœ˜#Jšœœ œ˜#Jšœœ˜ Jšœ ˜ šœ œœ˜3Jšœœ˜ Jšœ œœ˜/šœœ˜Jšœ˜Jšœ3˜3J˜—Jšœœ˜/J˜Jšœœ ˜2Jšœ˜Jšœ˜—Jšœœ0˜IJ˜,J˜/Jšœ˜—J˜Jšœœ˜J˜J˜-J˜/Jšœœ˜&˜LJšœ&˜(Jšœ8˜:Jšœ7˜9Jšœ9˜;Jšœ8˜:J˜—˜+JšœZ˜\Jšœ^˜`J˜—J˜1J˜J˜J˜——šŸœœ œ œ˜:Jšœœœœ˜^˜Jšœœ˜Jšœœ˜J˜`Jšœ œ ˜Jšœœ˜Jšœ œ˜Jšœ œ˜Jšœ œ˜Jšœœ˜Jšœœœ˜,Jšœœ˜ Jšœœ ˜!Jšœ œœ˜J˜:˜KJšœ œœœ˜T—Jšœœ"˜:Jšœœ0˜IJ˜8J˜,J˜.J˜šœA˜AJ˜P—J˜#J˜šœ˜Jšœœ˜ Jšœ œ8˜Jšœ#œ#˜KJšœ ˜ —Jšœœ˜Jšœ ˜ šœ œœ˜'Jšœœ˜ Jšœ œœ˜/šœœ˜Jšœ˜Jšœ3˜3J˜—šœ œœ˜7˜5Jšœœœ!œ ˜P—J˜Jšœœ˜(J˜—J˜Jšœœ ˜2Jšœ˜Jšœ˜—Jšœœ0˜IJ˜/Jšœ˜—J˜Jšœ œ˜J˜J˜-J˜/Jšœœ˜&˜LJšœ&˜(Jšœ8˜:Jšœ7˜9Jšœ9˜;Jšœ8˜:J˜—˜+JšœZ˜\Jšœ^˜`—J˜"J˜0J˜J˜——šœ4œ˜=J˜/J˜J˜—šŸ œœ œ˜$Jšœ œœ˜Jšœœ˜J˜&šœD˜DJ˜8J˜—š œœœœ ˜J˜Jšœ˜—Jšœ œ˜Jšœœœœ˜JJšœœœ0˜Bšœ2œœ˜BJ˜:—Jšœ;œ˜Nšœ2œœ˜BJ˜;—šœ˜Jš˜šœ0œ˜:J˜?—J˜Dšœ0œ˜:J˜;—Jšœ7œ˜<šœ1œ˜;J˜E—J˜Nšœ1œ˜;J˜F—Jšœ˜—J˜2J˜J˜"J˜J˜—šŸ œœœœ œœ)œ&œœ+œœœœ˜‡Jš˜šœœ ˜Jšœ œ¦˜±JšœΞ˜ΞJšœœ˜—Jšœ˜—J˜šŸœœ˜J˜5š˜J˜7Jšœ˜—J˜—J˜JšŸœœ˜˜šœ ™ J˜J˜"J˜J˜+J˜,J˜,J˜,J˜,J˜,J˜-J˜,J˜/J˜/J˜/J˜/J˜/J˜/J˜1J˜J˜9J˜J˜)J˜J˜*J˜*J˜*J˜*J˜+J˜*J˜*J˜*J˜*J˜+J˜+J˜,J˜,J˜+J˜J˜-J˜J˜5J˜9J˜7J˜9J˜6J˜9J˜6J˜9J˜9J˜9J˜:J˜:J˜7J˜9J˜7J˜9J˜8J˜9J˜8J˜9J˜J˜"J˜J˜,J˜-J˜(J˜'J˜'J˜(J˜7J˜&J˜2J˜2J˜,J˜'J˜,J˜,——J˜J˜šΟbœ˜2Jš˜Jšœ œ*œ˜EJšœ œ1œ˜OJš œ œ*œœœ˜Zšœœ ˜'Jšœ œ˜ Jšœ œB˜NJšœœ˜—J˜Jšœ œ=˜NJšœ˜—J˜˜Jšœ¨˜¨J˜šœ˜J˜J˜———…—nΪ‰υ