(* Copyright (C) 1989, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* Last Modified On Fri Nov 8 18:20:15 PST 1991 By muller *) (* Modified On Thu Sep 19 18:23:39 1991 By kalsow *) UNSAFE MODULE Time; FROM Thread IMPORT Alerted; IMPORT RTScheduler; FROM Utime IMPORT struct_timeval, struct_timezone, gettimeofday, settimeofday; PROCEDURE Pause (interval: CARDINAL) = <*FATAL Alerted*> BEGIN XPause (interval, FALSE); END Pause; PROCEDURE AlertPause (interval: CARDINAL) RAISES {Alerted} = BEGIN XPause (interval, TRUE); END AlertPause; PROCEDURE XPause (interval: CARDINAL; alertable := FALSE) RAISES {Alerted} = VAR t: T := Now (); BEGIN INC (t.microseconds, interval MOD 1000000); INC (t.seconds, interval DIV 1000000); IF (t.microseconds >= 1000000) THEN DEC (t.microseconds, 1000000); INC (t.seconds); END; RTScheduler.Pause (t, alertable); END XPause; PROCEDURE LongPause (interval: CARDINAL) = <*FATAL Alerted*> BEGIN XLongPause (interval, FALSE); END LongPause; PROCEDURE AlertLongPause (interval: CARDINAL) RAISES {Alerted} = BEGIN XLongPause (interval, TRUE); END AlertLongPause; PROCEDURE XLongPause (interval: CARDINAL; alertable:= FALSE) RAISES {Alerted} = VAR t: T := Now (); BEGIN INC (t.seconds, interval); RTScheduler.Pause (t, alertable); END XLongPause; PROCEDURE PauseUntil (t: T) = <*FATAL Alerted*> BEGIN XPauseUntil (t, FALSE); END PauseUntil; PROCEDURE AlertPauseUntil (t: T) RAISES {Alerted} = BEGIN XPauseUntil (t, TRUE); END AlertPauseUntil; PROCEDURE XPauseUntil (t: T; alertable := FALSE) RAISES {Alerted} = BEGIN RTScheduler.Pause (t, alertable); END XPauseUntil; PROCEDURE Now (): T = VAR tv: T; tz: TimeZone; BEGIN EVAL gettimeofday (LOOPHOLE (tv, struct_timeval), LOOPHOLE (tz, struct_timezone)); RETURN tv; END Now; PROCEDURE ClockGrain (): Microseconds = BEGIN RETURN 10000; END ClockGrain; PROCEDURE Add (t1, t2: T): T = VAR res: T; BEGIN res.seconds := t1.seconds + t2.seconds; res.microseconds := t1.microseconds + t2.microseconds; IF res.microseconds > 1000000 THEN DEC (res.microseconds, 1000000); INC (res.seconds, 1); END; RETURN res; END Add; PROCEDURE Subtract (t1, t2: T): T = VAR res: T; BEGIN res.seconds := t1.seconds - t2.seconds; res.microseconds := t1.microseconds - t2.microseconds; IF res.microseconds < 0 THEN INC (res.microseconds, 1000000); DEC (res.seconds, 1); END; RETURN res; END Subtract; PROCEDURE Compare (t1, t2: T): [-1 .. 1] = BEGIN IF t1.seconds > t2.seconds THEN RETURN 1; ELSIF t1.seconds = t2.seconds THEN IF t1.microseconds > t2.microseconds THEN RETURN 1; ELSIF t1.microseconds = t2.microseconds THEN RETURN 0; ELSE RETURN -1; END; ELSE RETURN -1 END; END Compare; PROCEDURE GetTimeZone (): TimeZone = VAR tv: T; tz: TimeZone; BEGIN EVAL gettimeofday (LOOPHOLE (tv, struct_timeval), LOOPHOLE (tz, struct_timezone)); RETURN tz; END GetTimeZone; PROCEDURE SetTime (tv: T; tz: TimeZone) RAISES {NoPrivileges} = BEGIN IF settimeofday (LOOPHOLE (tv, struct_timeval), LOOPHOLE (tz, struct_timezone)) = -1 THEN RAISE NoPrivileges; END; END SetTime; BEGIN END Time.