Fix: interrupt preemption
This commit is contained in:
@@ -47,7 +47,7 @@ timer_t *_pop(timer_t *t)
|
||||
}
|
||||
|
||||
static inline
|
||||
void _set_timer_interrupt()
|
||||
void _check_enable_timer()
|
||||
{
|
||||
if (global_timer) {
|
||||
uint64_t cntpct_el0;
|
||||
@@ -59,8 +59,9 @@ void _set_timer_interrupt()
|
||||
else
|
||||
W_SYSREG(cntp_cval_el0, global_timer->data.firing_tick);
|
||||
|
||||
_enable_timer_irq(true);
|
||||
}
|
||||
W_SYSREG(cntp_ctl_el0, 1);
|
||||
} else
|
||||
W_SYSREG(cntp_ctl_el0, 0);
|
||||
}
|
||||
|
||||
static inline
|
||||
@@ -87,8 +88,23 @@ void add_timer_task(task_t task)
|
||||
|
||||
global_timer = _merge(global_timer, newtimer);
|
||||
|
||||
_traverse(global_timer);
|
||||
_set_timer_interrupt();
|
||||
// _traverse(global_timer);
|
||||
_check_enable_timer();
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
interrupt_callback_func_t func;
|
||||
uint64_t param;
|
||||
} _timer_task_wrapper_param_t;
|
||||
|
||||
static inline
|
||||
void _timer_task_wrapper(uint64_t param)
|
||||
{
|
||||
_timer_task_wrapper_param_t *data = (void *)param;
|
||||
data->func(data->param);
|
||||
kfree(data);
|
||||
|
||||
_enable_timer_irq(true);
|
||||
}
|
||||
|
||||
void timer_irq_handler(void)
|
||||
@@ -100,9 +116,15 @@ void timer_irq_handler(void)
|
||||
LOG("timer irq"); DEBUG_EXCEP(cntpct_el0);
|
||||
|
||||
if (global_timer) {
|
||||
add_interrupt_task(20, global_timer->data.func, global_timer->data.param);
|
||||
global_timer = _pop(global_timer);
|
||||
}
|
||||
_timer_task_wrapper_param_t *param =
|
||||
kmalloc(sizeof(_timer_task_wrapper_param_t));
|
||||
*param = (_timer_task_wrapper_param_t){
|
||||
.func = global_timer->data.func,
|
||||
.param = global_timer->data.param,
|
||||
};
|
||||
add_interrupt_task(20, _timer_task_wrapper, (uint64_t)param);
|
||||
|
||||
_set_timer_interrupt();
|
||||
global_timer = _pop(global_timer);
|
||||
_check_enable_timer();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user