mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
hw: don't do redundant inter-processor interrupts
At least with the ARM generic interrupt controller, inter-processor interrupts are edge triggered and banked for all source processors. Thus it might be possible that such an interrupt gets triggered redundantly until the targeted processor is able to grab the kernel lock. As we're only interested in making a processor recognize accumulative updates to its scheduler, we can omit further interrupts if there is one pending already at the targeted processor. ref #1088
This commit is contained in:
parent
852785324f
commit
18cee192e2
@ -42,12 +42,7 @@ void Kernel::Processor_client::_interrupt(unsigned const processor_id)
|
||||
/* check wether the interrupt is our inter-processor interrupt */
|
||||
} else if (ic->is_ip_interrupt(irq_id, processor_id)) {
|
||||
|
||||
/*
|
||||
* This interrupt solely denotes that another processor has
|
||||
* modified the scheduling plan of this processor and thus
|
||||
* a more prior user context than the current one might be
|
||||
* available.
|
||||
*/
|
||||
__processor->ip_interrupt();
|
||||
|
||||
/* after all it must be a user interrupt */
|
||||
} else {
|
||||
@ -61,15 +56,18 @@ void Kernel::Processor_client::_interrupt(unsigned const processor_id)
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Processor_client::_schedule()
|
||||
{
|
||||
/* schedule thread */
|
||||
__processor->scheduler()->insert(this);
|
||||
void Kernel::Processor_client::_schedule() { __processor->schedule(this); }
|
||||
|
||||
/* let processor of the scheduled thread notice the change immediately */
|
||||
unsigned const processor_id = __processor->id();
|
||||
if (processor_id != Processor::executing_id()) {
|
||||
pic()->trigger_ip_interrupt(processor_id);
|
||||
|
||||
void Kernel::Processor::schedule(Processor_client * const client)
|
||||
{
|
||||
/* schedule processor client */
|
||||
_scheduler.insert(client);
|
||||
|
||||
/* let the processor notice the change immediately */
|
||||
if (_id != executing_id() && !_ip_interrupt_pending) {
|
||||
pic()->trigger_ip_interrupt(_id);
|
||||
_ip_interrupt_pending = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,7 @@ class Kernel::Processor : public Processor_driver
|
||||
|
||||
unsigned const _id;
|
||||
Processor_scheduler _scheduler;
|
||||
bool _ip_interrupt_pending;
|
||||
|
||||
public:
|
||||
|
||||
@ -131,9 +132,30 @@ class Kernel::Processor : public Processor_driver
|
||||
*/
|
||||
Processor(unsigned const id, Processor_client * const idle_client)
|
||||
:
|
||||
_id(id), _scheduler(idle_client)
|
||||
_id(id), _scheduler(idle_client), _ip_interrupt_pending(false)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Notice that the inter-processor interrupt isn't pending anymore
|
||||
*/
|
||||
void ip_interrupt()
|
||||
{
|
||||
/*
|
||||
* This interrupt solely denotes that another processor has
|
||||
* modified the scheduling plan of this processor and thus
|
||||
* a more prior user context than the current one might be
|
||||
* available.
|
||||
*/
|
||||
_ip_interrupt_pending = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a processor client to the scheduling plan of the processor
|
||||
*
|
||||
* \param client targeted client
|
||||
*/
|
||||
void schedule(Processor_client * const client);
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
|
Loading…
x
Reference in New Issue
Block a user