DIRECTORY Basics USING [LowHalf, LongDiv, LongNumber, HighHalf], Intime, Loader USING [MakeProcedureResident, MakeGlobalFrameResident], Process USING [SecondsToTicks, TicksToMsec], ProcessorFace USING [GetGreenwichMeanTime, GetClockPulses, gmtEpoch, microsecondsPerHundredPulses]; IntimeImpl: MONITOR IMPORTS Basics, Loader, Process, ProcessorFace EXPORTS Intime SHARES Intime = BEGIN OPEN Intime; MicrosecondsToPulses: PROC[ms: LONG CARDINAL] RETURNS[LONG CARDINAL] = { RETURN[(ms*100)/ProcessorFace.microsecondsPerHundredPulses]; -- RRA }; PulsesToMicroseconds: PROC[p: LONG CARDINAL] RETURNS[LONG CARDINAL] = { RETURN[(p*ProcessorFace.microsecondsPerHundredPulses)/100]; -- RRA }; msPerDeltaTick: PUBLIC MsTicks _ Process.TicksToMsec[1]; deltaTicksPerSecond: PUBLIC DeltaTicks _ Process.SecondsToTicks[1]; pulsesPerSecond: LONG CARDINAL = MicrosecondsToPulses[1000000]; adjustInterval: LONG CARDINAL = pulsesPerSecond-1; impossibleInterval: LONG CARDINAL = 30; -- seconds, must be < 64K/1000 seconds: LONG CARDINAL; -- seconds since System.gmtEpoch the last time we set milliseconds milliseconds: EventTime; -- milliseconds since System.gmtEpoch fastBase: LONG CARDINAL; ReadEventTime: PUBLIC ENTRY PROC [] RETURNS[res: EventTime] = { now: LONG CARDINAL; init: BOOL _ FALSE; WHILE (now _ ProcessorFace.GetClockPulses[]-fastBase)>adjustInterval DO InternalAdjustEventTime[init]; init_TRUE; ENDLOOP; -- repeats at most once. RETURN[Increment[by: Basics.LongDiv[num: PulsesToMicroseconds[now], den: 1000]]] }; Increment: INTERNAL PROC [by: --milliseconds--CARDINAL] RETURNS[res: EventTime] = INLINE { res_ [hiShort[higher: 0, lower: LONG[by] + LONG[milliseconds.lo]]]; res.hi _ res.hi + milliseconds.hi; }; AdjustEventTime: PUBLIC ENTRY PROC [initialize: BOOL] = { InternalAdjustEventTime[initialize] }; InternalAdjustEventTime: INTERNAL PROC [initialize: BOOL] = INLINE { newSeconds: LONG CARDINAL = ProcessorFace.GetGreenwichMeanTime[] - ProcessorFace.gmtEpoch; IF newSeconds < seconds OR newSeconds - seconds > impossibleInterval THEN initialize_TRUE; IF initialize THEN { milliseconds.higher _ 0; milliseconds.lower _ LONG[Basics.LowHalf[newSeconds]]*1000; milliseconds.hi _ milliseconds.hi + LONG[Basics.HighHalf[newSeconds]]*1000; fastBase _ ProcessorFace.GetClockPulses[]; } ELSE { dif: NAT _ newSeconds - seconds; milliseconds _ Increment[by: 1000*dif]; THROUGH [1..dif] DO fastBase _ fastBase+pulsesPerSecond ENDLOOP; }; seconds _ newSeconds }; BigDifference: PUBLIC PROC [t1, t2: LONG POINTER TO READONLY EventTime] RETURNS [MsTicks] = { tt: Basics.LongNumber _ [lc[t1.lower - t2.lower]]; RETURN[ IF t1.higher > t2.higher + 1 OR tt.highbits # 0 THEN LAST[CARDINAL] ELSE tt.lowbits ]; }; Loader.MakeProcedureResident[--e.g.--ReadEventTime]; Loader.MakeGlobalFrameResident[--e.g.--ReadEventTime]; END. ¨IntimeImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Dan Swinehart March 23, 1982 12:58 pm MBrown on 23-Mar-82 16:03:41 Dan Swinehart on April 14, 1982 11:04 am Paul Rovner on August 10, 1983 5:49 pm Russ Atkinson, September 16, 1983 6:00 pm Doug Wyatt, February 28, 1985 7:13:36 pm PST note: microsecondsPerHundredPulses/100 = microsecondsPerPulse value of System.GetClockPulses[] at time (in the recent past) when milliseconds = System.GetGreenwichMeanTime[]. things stop working if System.GetClockPulses[]-fastBase gets large (one minute or so). Frequently-running process is supposed to call AdjustEventTime often enough to update fastBase within adjustInterval pulses. Usually go through following loop zero or one times, never more than impossibleInterval times. t1 presumed later than or equal to t2. For time differences beyond the MsTicks range, BigDifference returns LAST[MsTicks] START HERE Κκ˜codešœ™Kšœ Οmœ1™Kšœžœ˜,KšœžœP˜c—K˜Kšœ ž˜Kšžœ(˜/Kšžœ˜Kšžœ˜ Kšœžœžœ˜K˜Kšœ=™=K˜šΟnœžœžœžœžœžœžœ˜HKšžœ7Οc˜CKšœ˜K˜—šŸœžœžœžœžœžœžœ˜GKšžœ6 ˜BKšœ˜K˜—Kšœžœ"˜8Kšœžœ(˜CK˜Kšœžœžœ!˜?Kšœžœžœ˜2Kšœžœžœ ˜FK˜Kšœ žœžœ B˜ZKšœ %˜>šœ žœžœ˜KšœΖ™Ζ—K˜š Ÿ œžœžœžœžœ˜?Kšœžœžœ˜Kšœž œ˜šžœ@ž˜GKšœ$žœžœ ˜K—KšžœJ˜PKšœ˜—K˜šŸ œžœž˜Kšœ žœžœžœ˜AKšœ žœžœ˜CK˜"K˜K˜—š Ÿœžœžœžœ žœ˜9K˜#K˜K˜—š Ÿœžœžœ žœžœ˜Dšœ žœžœ˜Kšœ>˜>—šžœžœ*˜DKšžœ žœ˜—šžœ žœ˜K˜Kšœžœ"˜;Kšœ$žœ#˜KKšœ*˜*K˜—šžœ˜Kšœžœ˜ ˜'Kšœ^™^—Kšžœ žœ'žœ˜BKšœ˜—K˜K˜—K˜šŸ œžœž˜Kš œ žœžœžœžœ žœ˜BKšœV œ ™zKšœ2˜2šžœ˜Kš žœžœžœžœžœ˜CKšžœ ˜Kšœ˜—Kšœ˜—K˜Kšœ ™ Kšœ œ˜4Kšœ œ˜6K˜Kšžœ˜—…—