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:
parent
b4cb878b90
commit
fea0f31018
4 changed files with 41 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue