diff --git a/kernel-src/include/kernel/timer.h b/kernel-src/include/kernel/timer.h index ecb148aa..a30eacca 100644 --- a/kernel-src/include/kernel/timer.h +++ b/kernel-src/include/kernel/timer.h @@ -5,13 +5,15 @@ #include #include #include +#include typedef struct timerentry_t { struct timerentry_t *next; time_t absolutetick; time_t repeatus; - void *private; - void (*func)(void *private, context_t* context); + dpcfn_t fn; + dpcarg_t arg; + dpc_t dpc; } timerentry_t; typedef struct { @@ -23,10 +25,11 @@ typedef struct { time_t (*stop)(); timerentry_t *queue; } timer_t; + void timer_resume(timer_t *timer); void timer_stop(timer_t *timer); void timer_isr(timer_t *timer, context_t *context); -void timer_insert(timer_t *timer, timerentry_t *entry, time_t us); +void timer_insert(timer_t *timer, timerentry_t *entry, dpcfn_t fn, dpcarg_t arg, time_t us, bool repeating); timer_t *timer_new(time_t ticksperus, void (*arm)(time_t), time_t (*stop)()); #endif diff --git a/kernel-src/sys/scheduler.c b/kernel-src/sys/scheduler.c index 698bb50b..f53bfd38 100644 --- a/kernel-src/sys/scheduler.c +++ b/kernel-src/sys/scheduler.c @@ -297,9 +297,10 @@ vnode_t *sched_getroot() { return getnodeslock(&proc->root); } -static void timerhook(void *private, context_t *context) { +static void timerhook(context_t *context, dpcarg_t arg) { thread_t* current = _cpu()->thread; + interrupt_set(false); spinlock_acquire(&runqueuelock); thread_t *next = runqueuenext(current->priority); @@ -338,8 +339,6 @@ void sched_init() { __assert(_cpu()->schedulerstack); _cpu()->schedulerstack = (void *)((uintptr_t)_cpu()->schedulerstack + SCHEDULER_STACK_SIZE); - _cpu()->schedtimerentry.func = timerhook; - _cpu()->schedtimerentry.repeatus = QUANTUM_US; SPINLOCK_INIT(runqueuelock); _cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL); @@ -347,7 +346,7 @@ void sched_init() { _cpu()->thread = sched_newthread(NULL, PAGE_SIZE * 32, 0, NULL, NULL); __assert(_cpu()->thread); - timer_insert(_cpu()->timer, &_cpu()->schedtimerentry, QUANTUM_US); + timer_insert(_cpu()->timer, &_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true); // XXX move this resume to a more appropriate place timer_resume(_cpu()->timer); } diff --git a/kernel-src/sys/timer.c b/kernel-src/sys/timer.c index 231dabec..d5d9dae1 100644 --- a/kernel-src/sys/timer.c +++ b/kernel-src/sys/timer.c @@ -38,11 +38,11 @@ void timer_isr(timer_t *timer, context_t *context) { timerentry_t *oldentry = timer->queue; timer->queue = timer->queue->next; - oldentry->func(oldentry->private, context); - if (oldentry->repeatus) insert(timer, oldentry, oldentry->repeatus); + dpc_enqueue(&oldentry->dpc, oldentry->fn, oldentry->arg); + if (timer->queue) { // TODO handle this __assert(timer->queue->absolutetick > timer->tickcurrent); @@ -79,13 +79,17 @@ void timer_stop(timer_t *timer) { interrupt_loweripl(oldipl); } -void timer_insert(timer_t *timer, timerentry_t* entry, time_t us) { +void timer_insert(timer_t *timer, timerentry_t *entry, dpcfn_t fn, dpcarg_t arg, time_t us, bool repeating) { long oldipl = interrupt_raiseipl(IPL_TIMER); spinlock_acquire(&timer->lock); if (timer->running) timer->tickcurrent += timer->stop(timer); + entry->repeatus = repeating ? us : 0; + entry->fn = fn; + entry->arg = arg; + insert(timer, entry, us); if (timer->running) {