namespace Time; struct Time inline { long seconds; // 0 is Jan 1, 1970 at midnight UTC; negative values // can be used for historical dates or intervals uint nanos; // Values greater than 999,999,999 are errors and // should cause an exception to be thrown. }; struct ITime inline { Time value; Time interval; }; // A Clock will generally also implement TimerFactory and ITimerFactory, // producing timers that are tied to the clock in question. The kernel // clock objects do not implement ITimerFactory. interface Clock { guid: "C7F53E18-FD5C-11D9-B176-000A95BB581A"; // Get the current time according to this clock. get_time(Time time out); // Get the clock's resolution. This is the largest // amount by which the clock may quantize its timekeeping. get_resolution(Time res out); }; // FIXME: Implement generic Factory interface TimerFactory { guid: "94BB5C90-41B6-11DA-8815-000A95BB581A"; new_timer(Timer timer out); }; interface ITimerFactory { guid: "97C7A4DA-41B6-11DA-8615-000A95BB581A"; new_itimer(ITimer itimer out); }; interface SettableClock { guid: "CED0AD0B-FD5C-11D9-954F-000A95BB581A"; // Set the clock's time. This may be rounded off to no coarser // a precision than the clock's resolution. set_time(Time time); // Return a reference to the read-only Clock interface associated // with this object. get_readonly_clock(Clock clock out); }; bitfield TimerFlags { // If set, set_time and get_time use Times relative to the current // time, rather than absolute time. RelTime, }; interface Timer { guid: "F78C769F-146E-11DA-897A-000A95BB581A"; // Set/get the time at which this timer expires. arm(Time expiry); get_expiry(Time expiry out, bool was_armed out); // Stop the timer from firing. This may be called regardless of // whether the timer is currently armed. The timer is guaranteed to // not fire after the call completes, but may fire at any point during // the disarm() call. // // If the firing event is synchronous, it will have completed by the // time the disarm() call completes. Otherwise, though the final // firing has happened, the handler may still be running after // disarm() returns. disarm(); // Set the type of action to take when the timer fires. set_action(Events.Event event); }; interface ITimer { guid: "D19B0A25-FD5C-11D9-9A2F-000A95BB581A"; // Arm the timer with the specified expiry. If expiry.interval is not // zero, then when the timer expires, it will automatically be // re-armed with the time set to previous expiry plus the interval. // The previous expiry is atomically read and returned in oldexpiry. // // Nothing will happen on timer expiration unless an action has been // specified with set_action. arm(ITime expiry, TimerFlags flags, ITime oldexpiry out); // Return the expiry as with arm, but without setting a new // expiry. get_expiry(TimerFlags flags, ITime expiry out, bool was_armed out); // Disarm the timer. disarm(); // Return the number of times since the last call to get_overrun // that a timer has fired without the previous timer action having // completed. // // For synchronous events such as a TrapEvent, this // includes the user trap handler not finishing on time (and in // such a case, new traps will not be generated for overrun firings). // // For asynchronous events such as a NotifierEvent, this only includes // the system's ability to send the notification. If the user notify // method can't keep up, it will be reflected in a growing queue of // pending messages, not in the overrun count. get_overrun(uint overruns out); // Set the notifier to be used when the timer expires. For kernel // timers, only sync instances of the kernel event dispatcher may be // used (the sync notifier may be a trigger for an async // NotifierEvent, though). set_notifier(Notifiers.Notifier notifier); set_sync_notifier(Notifiers.SyncNotifier notifier); };