4 #include <kernel/time.h>
5 #include <util/spinlock.h>
8 // The clock timer ticks 20 times per second. This timer is only used
9 // for maintaining the wall clock time; user timers, rescheduling, and
10 // other purposes are dealt with separately, so this timer only needs
11 // to run often enough to avoid overrun problems.
13 static const int clock_tick_rate = 20;
15 static const Time clock_tick_increment = {
16 0, 1000000000 / clock_tick_rate
19 // KTimerEntry overrides the standard TimerEntry in order
20 // to bypass the asynchronous Notifier, so that low-level
21 // things like rescheduling timers can work.
23 struct KTimerEntry : public TimerEntry {
29 KTimerEntry(TimerMux *MUX) : TimerEntry(MUX)
33 typedef void (*functype)(KTimerEntry *kte);
43 // This clock does not change when the wall clock is changed, but
44 // rather increases monotonically. Most timers should use this
45 // rather than wall time.
47 class MonotonicClock {
48 s64 llclocks_per_second;
49 s64 llclocks_per_tick;
51 // The clock's value as of the last tick.
54 s64 last_tick_llclock;
58 s32 get_nanos(s32 llclocks)
60 return llclocks * 1000000000LL / llclocks_per_second;
63 KTimerEntry tick_timer;
65 static void timer_tick(KTimerEntry *entry);
68 #include <servers/core/time/Time/MonotonicClock.h>
75 virtual ~MonotonicClock()
79 void get_time(Time *time);
80 void get_resolution(Time *res);
82 void new_timer(Timer *timer);
84 void calibrate(u64 llclocks_per_second_init)
86 llclocks_per_second = llclocks_per_second_init;
87 llclocks_per_tick = llclocks_per_second / clock_tick_rate;
89 printf("MonotonicClock::calibrate: %lld llclocks per second, %lld per tick\n",
90 llclocks_per_second, llclocks_per_tick);
93 // This is called every clock tick to update last_tick_time
94 // and last_tick_nanos.
98 void init_tick_timer();
101 extern MonotonicClock monotonic_clock;
109 #include <servers/core/time/Time/HWTimer.h>
122 // If a hardware timer is slow to reprogram, it may ignore
123 // arm() if time is later than the currently programmed time.
124 // Returns true if the timer action should be run immediately.
126 virtual void arm(Time new_expiry) = 0;
127 virtual void disarm() = 0;
128 virtual void calibrate() = 0;
130 void get_expiry(Time *expiry, uint8_t *armed);
132 void set_action(System::Events::Event *event)
138 extern HWTimer *hw_timer;
139 extern TimerMux *monotonic_timers;
140 extern KTimerEntry *tick_timer;