-- TimerImpl.mesa
-- Last Modified On 22-Dec-81 15:49:49 By Paul Rovner

DIRECTORY
      ShowTime USING[Microseconds, GetMark],
      Timer USING[Seconds];
      
TimerImpl: MONITOR
     LOCKS self USING self: Handle
     IMPORTS ShowTime
     EXPORTS Timer
= { 

--TYPEs
    Handle: TYPE = REF Object;

    Object: PUBLIC TYPE = MONITORED RECORD[bigBangTime, previousMark: ShowTime.Microseconds,
                                           secondsSinceFirstBigBang: Seconds ← 0.0];
     
    Seconds: TYPE = Timer.Seconds;  -- REAL--

-- PROCEDUREs

    Create: PUBLIC PROC RETURNS[Handle] =
      {startMark: ShowTime.Microseconds = ShowTime.GetMark[];
       RETURN[NEW[Object ← [LOCK:,
                            bigBangTime: startMark,
	                    previousMark: startMark]]]};
   
    Read: PUBLIC ENTRY PROC[self: Handle]
          RETURNS[time, deltaTime: Seconds] =
      {nextMark: ShowTime.Microseconds ← ShowTime.GetMark[];
       IF nextMark - self.bigBangTime > 10000000000B  -- 30 bits, ~20 mins
        THEN {self.secondsSinceFirstBigBang ← self.secondsSinceFirstBigBang + (self.previousMark-self.bigBangTime)*1.0E-6;
	      self.bigBangTime ← self.previousMark};
       deltaTime ← (nextMark - self.previousMark)*1.0E-6;
       time ← (nextMark-self.bigBangTime)*1.0E-6 + self.secondsSinceFirstBigBang;
       self.previousMark ← nextMark};
   
    Reset: PUBLIC ENTRY PROC[self: Handle] =
      {startMark: ShowTime.Microseconds = ShowTime.GetMark[];
       self.bigBangTime ← self.previousMark ← startMark;
       self.secondsSinceFirstBigBang ← 0.0};
   

 }.