X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/9440be3a5115a91dcdf8dff05a361cac4b6cea29..14b86eca7f36eedde35cb47b41afc36f9097ea7c:/lunaix-os/kernel/time/timer.c?ds=sidebyside diff --git a/lunaix-os/kernel/time/timer.c b/lunaix-os/kernel/time/timer.c index 03ef2b4..981b645 100644 --- a/lunaix-os/kernel/time/timer.c +++ b/lunaix-os/kernel/time/timer.c @@ -16,6 +16,7 @@ #include #include #include +#include #define LVT_ENTRY_TIMER(vector, mode) (LVT_DELIVERY_FIXED | mode | vector) @@ -38,6 +39,9 @@ static volatile struct lx_timer_context* timer_ctx = NULL; static volatile uint32_t rtc_counter = 0; static volatile uint8_t apic_timer_done = 0; +static volatile uint32_t sched_ticks = 0; +static volatile uint32_t sched_ticks_counter = 0; + #define APIC_CALIBRATION_CONST 0x100000 void @@ -51,6 +55,7 @@ timer_init_context() timer_ctx->active_timers = (struct lx_timer*)lxmalloc(sizeof(struct lx_timer)); llist_init_head(timer_ctx->active_timers); + } void @@ -131,26 +136,29 @@ timer_init(uint32_t frequency) intr_subscribe(APIC_TIMER_IV, timer_update); apic_write_reg(APIC_TIMER_ICR, timer_ctx->tphz); + + sched_ticks = timer_ctx->running_frequency / 1000 * SCHED_TIME_SLICE; + sched_ticks_counter = 0; } -int +struct lx_timer* timer_run_second(uint32_t second, void (*callback)(void*), void* payload, uint8_t flags) { return timer_run(second * timer_ctx->running_frequency, callback, payload, flags); } -int +struct lx_timer* timer_run_ms(uint32_t millisecond, void (*callback)(void*), void* payload, uint8_t flags) { return timer_run(timer_ctx->running_frequency / 1000 * millisecond, callback, payload, flags); } -int +struct lx_timer* timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags) { struct lx_timer* timer = (struct lx_timer*)lxmalloc(sizeof(struct lx_timer)); - if (!timer) return 0; + if (!timer) return NULL; timer->callback = callback; timer->counter = ticks; @@ -160,7 +168,7 @@ timer_run(ticks_t ticks, void (*callback)(void*), void* payload, uint8_t flags) llist_append(timer_ctx->active_timers, &timer->link); - return 1; + return timer; } static void @@ -171,19 +179,29 @@ timer_update(const isr_param* param) llist_for_each(pos, n, &timer_list_head->link, link) { - if (--pos->counter) { + if (!pos->counter) { + llist_delete(&pos->link); + lxfree(pos); + continue; + } + + if (--(pos->counter)) { continue; } pos->callback ? pos->callback(pos->payload) : 1; - if (pos->flags & TIMER_MODE_PERIODIC) { + if ((pos->flags & TIMER_MODE_PERIODIC)) { pos->counter = pos->deadline; - } else { - llist_delete(&pos->link); - lxfree(pos); } } + + sched_ticks_counter++; + + if (sched_ticks_counter >= sched_ticks) { + sched_ticks_counter = 0; + schedule(); + } } static void