1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-30 00:00:15 +01:00

avoid busy waiting if the cpu feature mwait is missing

This commit is contained in:
Stefan Lankes 2017-06-07 21:54:28 +02:00
parent b4cb878b90
commit fea0f31018
4 changed files with 41 additions and 2 deletions

View file

@ -1033,6 +1033,24 @@ int apic_send_ipi(uint64_t dest, uint8_t irq)
return 0;
}
void wakeup_core(uint32_t core_id)
{
// if mwait is available, an IPI isn't required to wakeup the core
if (has_mwait())
return;
// no self IPI required
if (core_id == CORE_ID)
return;
// no IPI required if core is offline
if (!online[core_id])
return;
LOG_DEBUG("wakeup core %d\n", core_id);
apic_send_ipi(core_id, 82+32);
}
static void apic_err_handler(struct state *s)
{
LOG_ERROR("Got APIC error 0x%x\n", lapic_read(APIC_ESR));
@ -1091,6 +1109,11 @@ static void apic_shutdown(struct state * s)
LOG_DEBUG("Receive shutdown interrupt\n");
}
static void apic_wakeup_handler(struct state * s)
{
LOG_DEBUG("Receive wakeup interrupt\n");
}
int apic_init(void)
{
int ret;
@ -1105,6 +1128,7 @@ int apic_init(void)
irq_install_handler(80+32, apic_tlb_handler);
#endif
irq_install_handler(81+32, apic_shutdown);
irq_install_handler(82+32, apic_wakeup_handler);
if (apic_processors[boot_processor])
LOG_INFO("Boot processor %u (ID %u)\n", boot_processor, apic_processors[boot_processor]->id);
else

View file

@ -196,7 +196,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
void wait_for_task(void)
{
if (!has_mwait()) {
PAUSE;
HALT;
} else {
void* queue = get_readyqueue();

View file

@ -166,6 +166,14 @@ void reschedule(void);
*/
int wakeup_task(tid_t);
/** @brief Wake up a core_id
*
* Wakeup core to be sure that
* the core isn't in halt state
*
* @param core_id Specifies the core
*/
void wakeup_core(uint32_t core_id);
/** @brief Block current task
*

View file

@ -176,6 +176,10 @@ static void readyqueues_push_back(uint32_t core_id, task_t* task)
// increase the number of ready tasks
readyqueues[core_id].nr_tasks++;
// should we wakeup the core?
if (readyqueues[core_id].nr_tasks == 1)
wakeup_core(core_id);
}
@ -483,7 +487,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
task_table[i].stack = stack;
task_table[i].prio = prio;
task_table[i].heap = curr_task->heap;
task_table[i].start_tick = get_clock_tick();
task_table[i].start_tick = get_clock_tick();
task_table[i].last_tsc = 0;
task_table[i].parent = curr_task->id;
task_table[i].tls_addr = curr_task->tls_addr;
@ -513,6 +517,9 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
readyqueues[core_id].queue[prio-1].last->next = task_table+i;
readyqueues[core_id].queue[prio-1].last = task_table+i;
}
// should we wakeup the core?
if (readyqueues[core_id].nr_tasks == 1)
wakeup_core(core_id);
spinlock_irqsave_unlock(&readyqueues[core_id].lock);
break;
}