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 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 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 Êߘšœ™Jšœ%™%Jšœ™Jšœ(™(Jšœ&™&J™)—J˜šÏk ˜ Jšœœ*˜6J˜Jšœœ2˜>Jšœœ˜,šœœ˜JšœN˜N——J˜šœ ˜Jšœ(˜/Jšœ˜Jšœ˜ Jšœœœ˜—˜Jšœ=™=J˜šÏnœœœœœœœ˜HJšœ7Ïc˜CJšœ˜J˜—šžœœœœœœœ˜GJšœ6Ÿ˜BJšœ˜J˜—Jšœœ"˜8Jšœœ(˜CJ˜Jšœœœ!˜?Jšœœœ˜2JšœœœŸ˜FJ˜Jšœ œœD˜ZJšœ>˜>šœ œœ˜JšœÆ™Æ—J˜š ž œœœœœ˜?Jšœœœ˜Jšœ œ˜šœ@˜GJšœ$œœŸ˜K—JšœJ˜PJšœ˜—J˜šž œœ˜JšœŸœœœ˜AJšœ œœ˜CJ˜"J˜J˜—š žœœœœ œ˜9J˜#J˜J˜—š žœœœ œœ˜Dšœ œœ˜Jšœ>˜>—šœœ*˜DJšœ œ˜—šœ œ˜J˜Jšœœ"˜;Jšœ$œ#˜KJšœ*˜*J˜—šœ˜Jšœœ˜ ˜'Jšœ^™^—Jšœ œ'œ˜BJšœ˜—J˜J˜—J˜šž œœ˜Jš œ œœœœ œ˜BJšœVŸœŸ™zJšœ2˜2šœ˜Jš œœœœœ˜CJšœ ˜Jšœ˜—Jšœ˜—J˜—Jšœ ™ JšœŸœ˜4JšœŸœ˜6J˜Jšœ˜J˜—…— -