mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-03 12:34:12 +00:00
parent
f545fa0e36
commit
49bf33e404
@ -277,12 +277,28 @@ extern "C" void init_kernel_multiprocessor()
|
|||||||
*/
|
*/
|
||||||
extern "C" void kernel()
|
extern "C" void kernel()
|
||||||
{
|
{
|
||||||
|
/* ensure that no other processor accesses kernel data while we do */
|
||||||
data_lock().lock();
|
data_lock().lock();
|
||||||
|
|
||||||
|
/* determine local processor scheduler */
|
||||||
unsigned const processor_id = Processor::executing_id();
|
unsigned const processor_id = Processor::executing_id();
|
||||||
Processor * const processor = processor_pool()->select(processor_id);
|
Processor * const processor = processor_pool()->select(processor_id);
|
||||||
Processor_scheduler * const scheduler = processor->scheduler();
|
Processor_scheduler * const scheduler = processor->scheduler();
|
||||||
scheduler->head()->exception(processor_id);
|
|
||||||
scheduler->head()->proceed(processor_id);
|
/*
|
||||||
|
* Request the current processor occupant without any update. While this
|
||||||
|
* processor was outside the kernel, another processor may have changed the
|
||||||
|
* scheduling of the local activities in a way that an update would return
|
||||||
|
* an occupant other than that whose exception caused the kernel entry.
|
||||||
|
*/
|
||||||
|
scheduler->occupant()->exception(processor_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The processor local as well as remote exception-handling may have
|
||||||
|
* changed the scheduling of the local activities. Hence we must update the
|
||||||
|
* processor occupant.
|
||||||
|
*/
|
||||||
|
scheduler->update_occupant()->proceed(processor_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ void Kernel::Execution_context::_interrupt(unsigned const processor_id)
|
|||||||
if (timer()->interrupt_id(processor_id) == irq_id)
|
if (timer()->interrupt_id(processor_id) == irq_id)
|
||||||
{
|
{
|
||||||
/* handle scheduling timeout */
|
/* handle scheduling timeout */
|
||||||
__processor->scheduler()->yield();
|
__processor->scheduler()->yield_occupation();
|
||||||
timer()->clear_interrupt(processor_id);
|
timer()->clear_interrupt(processor_id);
|
||||||
reset_lap_time(processor_id);
|
reset_lap_time(processor_id);
|
||||||
} else {
|
} else {
|
||||||
@ -65,5 +65,5 @@ void Kernel::Execution_context::_unschedule()
|
|||||||
|
|
||||||
void Kernel::Execution_context::_yield()
|
void Kernel::Execution_context::_yield()
|
||||||
{
|
{
|
||||||
__processor->scheduler()->yield();
|
__processor->scheduler()->yield_occupation();
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ class Kernel::Scheduler
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
T * const _idle;
|
T * const _idle;
|
||||||
T * _current;
|
T * _occupant;
|
||||||
Double_list<T> _items[Priority::MAX + 1];
|
Double_list<T> _items[Priority::MAX + 1];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -250,27 +250,29 @@ class Kernel::Scheduler
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Scheduler(T * const idle) : _idle(idle), _current(0) { }
|
Scheduler(T * const idle) : _idle(idle), _occupant(0) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get currently scheduled item
|
* Adjust occupant reference to the current scheduling plan
|
||||||
|
*
|
||||||
|
* \return updated occupant reference
|
||||||
*/
|
*/
|
||||||
T * head()
|
T * update_occupant()
|
||||||
{
|
{
|
||||||
for (int i = Priority::MAX; i >= 0 ; i--) {
|
for (int i = Priority::MAX; i >= 0 ; i--) {
|
||||||
_current = _items[i].head();
|
_occupant = _items[i].head();
|
||||||
if (_current) return _current;
|
if (_occupant) { return _occupant; }
|
||||||
}
|
}
|
||||||
return _idle;
|
return _idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End turn of currently scheduled item
|
* Adjust scheduling plan to the fact that the current occupant yileds
|
||||||
*/
|
*/
|
||||||
void yield()
|
void yield_occupation()
|
||||||
{
|
{
|
||||||
if (!_current) return;
|
if (!_occupant) { return; }
|
||||||
_items[_current->priority()].head_to_tail();
|
_items[_occupant->priority()].head_to_tail();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,6 +294,8 @@ class Kernel::Scheduler
|
|||||||
** Accessors **
|
** Accessors **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
|
T * occupant() { return _occupant ? _occupant : _idle; }
|
||||||
|
|
||||||
T * idle() const { return _idle; }
|
T * idle() const { return _idle; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user