DIRECTORY BasicTime, Commander, CommanderOps, Convert, Histograms, HistogramsOut, HistogramsViewing, IO, NetworkName, NetworkStream, Process, Rope; RoundTripDriver: CEDAR PROGRAM IMPORTS BasicTime, Commander, CommanderOps, Convert, Histograms, HistogramsOut, HistogramsViewing, IO, NetworkName, NetworkStream, Process = BEGIN Time: TYPE ~ RECORD [s, us: INT]; minTime: REAL ¬ -3.0; maxTime: REAL ¬ 30.0; dTime: REAL ¬ 0.05; dataTimeout: INT ¬ 10D3; unixOrg: BasicTime.GMT ~ BasicTime.Pack[[year: 1970, month: January, day: 1, hour: 0, minute: 0, second: 0, zone: 0, dst: no]]; Probe: Commander.CommandProc ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; nTests: INT ¬ 50; msPause: INT ¬ 500; toHost, fromHost: IO.STREAM ¬ NIL; rn: REF INT ¬ NEW [INT ¬ 0]; doer: PROCESS ¬ NIL; PutCard: PROC [c: CARD] ~ {PutShort[c/10000H]; PutShort[c MOD 10000H]}; PutShort: PROC [c: CARDINAL] ~ { toHost.PutChar[VAL[c/100H]]; toHost.PutChar[VAL[c MOD 100H]]}; IF argv.argc<1 OR argv.argc>4 THEN RETURN [$Failure, "Usage: RoundTripDriver [ []]"]; IF argv.argc > 2 THEN nTests ¬ Convert.IntFromRope[argv[2]]; IF argv.argc > 3 THEN msPause ¬ Convert.IntFromRope[argv[3]]; cmd.out.PutF["Probing %g %g times, %g milliseconds between probes.\n", [rope[argv[1]]], [integer[nTests]], [integer[msPause]] ]; {ENABLE { NetworkStream.Error => CommanderOps.Failed[IO.PutFR["NetworkStream.Error[LIST[%g, ..], %g]", [atom[codes.first]], [rope[msg]] ]]; NetworkName.Error => CommanderOps.Failed[IO.PutFR["NetworkName.Error[LIST[%g, ..], %g]", [atom[codes.first]], [rope[msg]] ]]; IO.Error => CommanderOps.Failed["IO.Error"]; NetworkStream.Timeout => CommanderOps.Failed[IO.PutFR1["No response within %g milliseconds", [integer[dataTimeout]] ]]; }; [fromHost, toHost] ¬ NetworkStream.CreateStreams[$ARPA, NetworkName.AddressFromName[$ARPA, argv[1], "58801"].addr, $basicStream, dataTimeout]; {ENABLE UNWIND => { toHost.Close[TRUE !IO.Error => CONTINUE]; fromHost.Close[TRUE !IO.Error => CONTINUE]}; doer ¬ FORK Receive[fromHost, rn, cmd]; THROUGH [1..nTests] DO start: Time ~ GetNow[]; PutCard[start.s]; PutCard[start.us]; NetworkStream.SendSoon[toHost, 0]; Process.PauseMsec[msPause]; ENDLOOP; }; toHost.Close[!IO.Error => CONTINUE]; Process.PauseMsec[1000]; fromHost.Close[TRUE !IO.Error => CONTINUE]; TRUSTED {JOIN doer}; RETURN}}; Receive: PROC [fromHost: IO.STREAM, rn: REF INT, cmd: Commander.Handle] ~ { GetShort: PROC RETURNS [CARDINAL] ~ { hi: BYTE ~ fromHost.GetChar[].ORD; RETURN [hi*100H + fromHost.GetChar[].ORD]}; GetCard: PROC RETURNS [CARD] ~ { hi: CARDINAL ~ GetShort[]; RETURN [hi*10000H + GetShort[]]}; GetTime: PROC RETURNS [Time] ~ { s: CARD ~ GetCard[]; us: CARD ~ GetCard[]; RETURN [[s, us]]}; upTime: Histograms.Histogram ~ Histograms.Create1D[factor: dTime, offset: minTime]; downTime: Histograms.Histogram ~ Histograms.Create1D[factor: dTime, offset: minTime]; roundTime: Histograms.Histogram ~ Histograms.Create1D[factor: dTime, offset: -1.0]; roundAvg, roundStd: REAL; [] ¬ HistogramsViewing.Show[h: upTime, format: "%5.2f", width: 5, viewerInit: [name: "rtd: Term -> host seconds"], base: 2.0, updatePeriod: 5]; [] ¬ HistogramsViewing.Show[h: downTime, format: "%5.2f", width: 5, viewerInit: [name: "rtd: host -> Term seconds"], base: 2.0, updatePeriod: 5]; [] ¬ HistogramsViewing.Show[h: roundTime, format: "%5.2f", width: 5, viewerInit: [name: "rtd: Term -> host -> Term seconds"], base: 2.0, updatePeriod: 5]; DO ENABLE IO.Error, IO.EndOfStream => EXIT; IF fromHost.EndOf[] THEN EXIT; {start: Time ~ GetTime[]; mid: Time ~ GetTime[]; end: Time ~ GetNow[]; dUp: INT ~ Diff[mid, start]; dDn: INT ~ Diff[end, mid]; dRound: INT ~ dUp+dDn; rn­ ¬ rn­+1; cmd.out.PutChar['.]; upTime.IncrementTransformed[minTime, maxTime, dUp/1.0E6]; downTime.IncrementTransformed[minTime, maxTime, dDn/1.0E6]; roundTime.IncrementTransformed[-1.0, maxTime, dRound/1.0E6]; }ENDLOOP; cmd.out.PutF1[" %g round trips done.\n", [integer[rn­]] ]; [avg: roundAvg, stdDev: roundStd] ¬ HistogramsOut.Stats1D[roundTime]; cmd.out.PutF["Round trip time: %g +- %g s.\n", [real[roundAvg]], [real[roundStd]] ]; RETURN}; GetNow: PROC RETURNS [Time] ~ { egmt: BasicTime.ExtendedGMT ~ BasicTime.ExtendedNow[]; RETURN [[BasicTime.Period[from: unixOrg, to: egmt.gmt], egmt.usecs]]}; Diff: PROC [a, b: Time] RETURNS [d: INT] ~ { d ¬ (a.s-b.s)*1D6 + (a.us-b.us); RETURN}; Commander.Register["RoundTripDriver", Probe, " [ []]"]; END. ΐ RoundTripDriver.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Last tweaked by Mike Spreitzer on October 31, 1990 11:22 am PST Willie-s, April 22, 1992 11:10 am PDT Κ"–(cedarcode) style•NewlineDelimiter ™code™Kšœ Οeœ1™