4 * @brief A simple timer implementation based on APIC with adjustable frequency
5 * and subscribable "timerlets"
9 * @copyright Copyright (c) 2022
13 #include <lunaix/mm/cake.h>
14 #include <lunaix/mm/valloc.h>
15 #include <lunaix/sched.h>
16 #include <lunaix/spike.h>
17 #include <lunaix/syslog.h>
18 #include <lunaix/timer.h>
19 #include <lunaix/hart_state.h>
21 #include <hal/hwtimer.h>
28 static DEFINE_LLIST(timers);
30 static volatile u32_t sched_ticks = 0;
31 static volatile u32_t sched_ticks_counter = 0;
33 static struct cake_pile* timer_pile;
38 timer_pile = cake_new_pile("timer", sizeof(struct lx_timer), 1, 0);
46 hwtimer_init(SYS_TIMER_FREQUENCY_HZ, timer_update);
48 sched_ticks = (SYS_TIMER_FREQUENCY_HZ * SCHED_TIME_SLICE) / 1000;
49 sched_ticks_counter = 0;
53 timer_run_second(u32_t second,
54 void (*callback)(void*),
58 ticks_t t = hwtimer_to_ticks(second, TIME_SEC);
59 return timer_run(t, callback, payload, flags);
63 timer_run_ms(u32_t millisecond,
64 void (*callback)(void*),
68 ticks_t t = hwtimer_to_ticks(millisecond, TIME_MS);
69 return timer_run(t, callback, payload, flags);
73 timer_run(ticks_t ticks, void (*callback)(void*), void* payload, u8_t flags)
75 struct lx_timer* timer = (struct lx_timer*)cake_grab(timer_pile);
80 timer->callback = callback;
81 timer->counter = ticks;
82 timer->deadline = ticks;
83 timer->payload = payload;
86 llist_append(&timers, &timer->link);
94 struct lx_timer *pos, *n;
96 llist_for_each(pos, n, &timers, link)
98 if (--(pos->counter)) {
102 pos->callback ? pos->callback(pos->payload) : 1;
104 if ((pos->flags & TIMER_MODE_PERIODIC)) {
105 pos->counter = pos->deadline;
107 llist_delete(&pos->link);
108 cake_release(timer_pile, pos);
112 sched_ticks_counter++;
114 if (sched_ticks_counter >= sched_ticks) {
115 sched_ticks_counter = 0;
116 thread_stats_update_entering(false);