mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
x86/irq: check_workqueues() after custom IRQ handler has run + refactoring
When HermitCore is compiled with periodic ticks, the timer handler will increase the local tick count, so check_workqueues() would only recognize the increased ticks on the next call, therefore call it after the IRQ handler.
This commit is contained in:
parent
3bd4859904
commit
cd3d953bce
1 changed files with 25 additions and 24 deletions
|
@ -91,7 +91,7 @@ extern void mmnif_irq(void);
|
|||
* This array is actually an array of function pointers. We use
|
||||
* this to handle custom IRQ handlers for a given IRQ
|
||||
*/
|
||||
static void* irq_routines[MAX_HANDLERS] = {[0 ... MAX_HANDLERS-1] = NULL};
|
||||
static irq_handler_t irq_routines[MAX_HANDLERS] = {[0 ... MAX_HANDLERS-1] = NULL};
|
||||
static uint64_t irq_counter[MAX_CORES][MAX_HANDLERS] = {[0 ... MAX_CORES-1][0 ... MAX_HANDLERS-1] = 0};
|
||||
#ifdef MEASURE_IRQ
|
||||
static int go = 0;
|
||||
|
@ -281,40 +281,41 @@ int irq_init(void)
|
|||
*/
|
||||
size_t** irq_handler(struct state *s)
|
||||
{
|
||||
size_t** ret = NULL;
|
||||
#ifdef MEASURE_IRQ
|
||||
uint64_t diff = 0;
|
||||
#endif
|
||||
|
||||
/* This is a blank function pointer */
|
||||
void (*handler) (struct state * s);
|
||||
|
||||
#ifdef MEASURE_IRQ
|
||||
if (go)
|
||||
diff = rdtsc();
|
||||
#endif
|
||||
|
||||
size_t** ret = NULL;
|
||||
|
||||
if(BUILTIN_EXPECT(s->int_no >= MAX_HANDLERS, 0)) {
|
||||
kprintf("[%d] Invalid IRQ number %d\n", CORE_ID, s->int_no);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
irq_counter[CORE_ID][s->int_no]++;
|
||||
|
||||
check_workqueues_in_irqhandler(s->int_no);
|
||||
|
||||
/*
|
||||
* Find out if we have a custom handler to run for this
|
||||
* IRQ and then finally, run it
|
||||
*/
|
||||
if (BUILTIN_EXPECT(s->int_no < MAX_HANDLERS, 1)) {
|
||||
handler = irq_routines[s->int_no];
|
||||
if (handler)
|
||||
handler(s);
|
||||
else
|
||||
kprintf("Unhandle IRQ %d\n", s->int_no);
|
||||
} else kprintf("Invalid interrupt number %d\n", s->int_no);
|
||||
// Find out if we have a custom handler to run for this IRQ and run it
|
||||
irq_handler_t handler = irq_routines[s->int_no];
|
||||
|
||||
// timer interrupt?
|
||||
if ((s->int_no == 32) || (s->int_no == 123))
|
||||
ret = scheduler(); // switch to a new task
|
||||
else if ((s->int_no >= 32) && (get_highest_priority() > per_core(current_task)->prio))
|
||||
if (handler) {
|
||||
handler(s);
|
||||
} else {
|
||||
kprintf("[%d] Unhandled IRQ %d\n", CORE_ID, s->int_no);
|
||||
}
|
||||
|
||||
// Check if timers have expired that would unblock tasks
|
||||
check_workqueues_in_irqhandler((int) s->int_no);
|
||||
|
||||
if ((s->int_no == 32) || (s->int_no == 123)) {
|
||||
// a timer interrupt may have caused unblocking of tasks
|
||||
ret = scheduler();
|
||||
} else if ((s->int_no >= 32) && (get_highest_priority() > per_core(current_task)->prio)) {
|
||||
// there's a ready task with higher priority
|
||||
ret = scheduler();
|
||||
}
|
||||
|
||||
apic_eoi(s->int_no);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue