diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index 8cace8526..8c6790e22 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -40,7 +40,7 @@ void Cpu_job::_activate_own_share() { _cpu->schedule(this); } void Cpu_job::_deactivate_own_share() { assert(_cpu->id() == Cpu::executing_id()); - _cpu->scheduler().unready(this); + _cpu->scheduler().unready(*this); } @@ -74,13 +74,13 @@ void Cpu_job::_interrupt(unsigned const /* cpu_id */) void Cpu_job::affinity(Cpu &cpu) { _cpu = &cpu; - _cpu->scheduler().insert(this); + _cpu->scheduler().insert(*this); } void Cpu_job::quota(unsigned const q) { - if (_cpu) { _cpu->scheduler().quota(this, q); } + if (_cpu) { _cpu->scheduler().quota(*this, q); } else { Cpu_share::quota(q); } } @@ -93,7 +93,7 @@ Cpu_job::Cpu_job(Cpu_priority const p, unsigned const q) Cpu_job::~Cpu_job() { if (!_cpu) { return; } - _cpu->scheduler().remove(this); + _cpu->scheduler().remove(*this); } @@ -115,8 +115,8 @@ Cpu::Idle_thread::Idle_thread(Cpu &cpu) void Cpu::schedule(Job * const job) { - if (_id == executing_id()) { _scheduler.ready(&job->share()); } - else if (_scheduler.ready_check(&job->share())) { trigger_ip_interrupt(); } + if (_id == executing_id()) { _scheduler.ready(job->share()); } + else if (_scheduler.ready_check(job->share())) { trigger_ip_interrupt(); } } @@ -162,7 +162,7 @@ Cpu::Cpu(unsigned const id, Inter_processor_work_list & global_work_list) : _id(id), _timer(*this), - _scheduler(&_idle, _quota(), _fill()), _idle(*this), + _scheduler(_idle, _quota(), _fill()), _idle(*this), _ipi_irq(*this), _global_work_list(global_work_list) { _arch_init(); } diff --git a/repos/base-hw/src/core/kernel/cpu.h b/repos/base-hw/src/core/kernel/cpu.h index 531884b17..802fdeee9 100644 --- a/repos/base-hw/src/core/kernel/cpu.h +++ b/repos/base-hw/src/core/kernel/cpu.h @@ -169,7 +169,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout * Returns the currently active job */ Job & scheduled_job() const { - return *static_cast(_scheduler.head())->helping_sink(); } + return *static_cast(&_scheduler.head())->helping_sink(); } unsigned id() const { return _id; } Cpu_scheduler &scheduler() { return _scheduler; } diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.cc b/repos/base-hw/src/core/kernel/cpu_scheduler.cc index d177c1b07..e9ba295cd 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.cc +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.cc @@ -45,11 +45,11 @@ void Cpu_scheduler::_consumed(unsigned const q) } -void Cpu_scheduler::_set_head(Share * const s, unsigned const q, bool const c) +void Cpu_scheduler::_set_head(Share &s, unsigned const q, bool const c) { _head_quota = q; _head_claims = c; - _head = s; + _head = &s; } @@ -84,7 +84,7 @@ bool Cpu_scheduler::_claim_for_head() if (!item) { continue; } Cpu_share &share { item->payload() }; if (!share._claim) { continue; } - _set_head(&share, share._claim, 1); + _set_head(share, share._claim, 1); return 1; } return 0; @@ -98,12 +98,12 @@ bool Cpu_scheduler::_fill_for_head() return 0; } Share &share = item->payload(); - _set_head(&share, share._fill, 0); + _set_head(share, share._fill, 0); return 1; } -unsigned Cpu_scheduler::_trim_consumption(unsigned & q) +unsigned Cpu_scheduler::_trim_consumption(unsigned &q) { q = Genode::min(Genode::min(q, _head_quota), _residual); if (!_head_yields) { return _head_quota - q; } @@ -112,23 +112,23 @@ unsigned Cpu_scheduler::_trim_consumption(unsigned & q) } -void Cpu_scheduler::_quota_introduction(Share * const s) +void Cpu_scheduler::_quota_introduction(Share &s) { - if (s->_ready) { _rcl[s->_prio].insert_tail(&s->_claim_item); } - else { _ucl[s->_prio].insert_tail(&s->_claim_item); } + if (s._ready) { _rcl[s._prio].insert_tail(&s._claim_item); } + else { _ucl[s._prio].insert_tail(&s._claim_item); } } -void Cpu_scheduler::_quota_revokation(Share * const s) +void Cpu_scheduler::_quota_revokation(Share &s) { - if (s->_ready) { _rcl[s->_prio].remove(&s->_claim_item); } - else { _ucl[s->_prio].remove(&s->_claim_item); } + if (s._ready) { _rcl[s._prio].remove(&s._claim_item); } + else { _ucl[s._prio].remove(&s._claim_item); } } -void Cpu_scheduler::_quota_adaption(Share * const s, unsigned const q) +void Cpu_scheduler::_quota_adaption(Share &s, unsigned const q) { - if (q) { if (s->_claim > q) { s->_claim = q; } } + if (q) { if (s._claim > q) { s._claim = q; } } else { _quota_revokation(s); } } @@ -153,7 +153,7 @@ void Cpu_scheduler::update(time_t time) } -bool Cpu_scheduler::ready_check(Share * const s1) +bool Cpu_scheduler::ready_check(Share &s1) { assert(_head); @@ -162,15 +162,15 @@ bool Cpu_scheduler::ready_check(Share * const s1) if (_need_to_schedule) return _need_to_schedule; Share * s2 = _head; - if (!s1->_claim) { - _need_to_schedule = s2 == _idle; + if (!s1._claim) { + _need_to_schedule = s2 == &_idle; } else if (!_head_claims) { _need_to_schedule = true; - } else if (s1->_prio != s2->_prio) { - _need_to_schedule = s1->_prio > s2->_prio; + } else if (s1._prio != s2->_prio) { + _need_to_schedule = s1._prio > s2->_prio; } else { for ( - ; s2 && s2 != s1; + ; s2 && s2 != &s1; s2 = Double_list::next(&s2->_claim_item) != nullptr ? &Double_list::next(&s2->_claim_item)->payload() : @@ -182,33 +182,33 @@ bool Cpu_scheduler::ready_check(Share * const s1) } -void Cpu_scheduler::ready(Share * const s) +void Cpu_scheduler::ready(Share &s) { - assert(!s->_ready && s != _idle); + assert(!s._ready && &s != &_idle); _need_to_schedule = true; - s->_ready = 1; - s->_fill = _fill; - _fills.insert_tail(&s->_fill_item); - if (!s->_quota) { return; } - _ucl[s->_prio].remove(&s->_claim_item); - if (s->_claim) { _rcl[s->_prio].insert_head(&s->_claim_item); } - else { _rcl[s->_prio].insert_tail(&s->_claim_item); } + s._ready = 1; + s._fill = _fill; + _fills.insert_tail(&s._fill_item); + if (!s._quota) { return; } + _ucl[s._prio].remove(&s._claim_item); + if (s._claim) { _rcl[s._prio].insert_head(&s._claim_item); } + else { _rcl[s._prio].insert_tail(&s._claim_item); } } -void Cpu_scheduler::unready(Share * const s) +void Cpu_scheduler::unready(Share &s) { - assert(s->_ready && s != _idle); + assert(s._ready && &s != &_idle); _need_to_schedule = true; - s->_ready = 0; - _fills.remove(&s->_fill_item); - if (!s->_quota) { return; } - _rcl[s->_prio].remove(&s->_claim_item); - _ucl[s->_prio].insert_tail(&s->_claim_item); + s._ready = 0; + _fills.remove(&s._fill_item); + if (!s._quota) { return; } + _rcl[s._prio].remove(&s._claim_item); + _ucl[s._prio].insert_tail(&s._claim_item); } @@ -219,39 +219,46 @@ void Cpu_scheduler::yield() } -void Cpu_scheduler::remove(Share * const s) +void Cpu_scheduler::remove(Share &s) { - assert(s != _idle); + assert(&s != &_idle); _need_to_schedule = true; - if (s == _head) _head = nullptr; - if (s->_ready) { _fills.remove(&s->_fill_item); } - if (!s->_quota) { return; } - if (s->_ready) { _rcl[s->_prio].remove(&s->_claim_item); } - else { _ucl[s->_prio].remove(&s->_claim_item); } + if (&s == _head) _head = nullptr; + if (s._ready) { _fills.remove(&s._fill_item); } + if (!s._quota) { return; } + if (s._ready) { _rcl[s._prio].remove(&s._claim_item); } + else { _ucl[s._prio].remove(&s._claim_item); } } -void Cpu_scheduler::insert(Share * const s) +void Cpu_scheduler::insert(Share &s) { - assert(!s->_ready); + assert(!s._ready); _need_to_schedule = true; - if (!s->_quota) { return; } - s->_claim = s->_quota; - _ucl[s->_prio].insert_head(&s->_claim_item); + if (!s._quota) { return; } + s._claim = s._quota; + _ucl[s._prio].insert_head(&s._claim_item); } -void Cpu_scheduler::quota(Share * const s, unsigned const q) +void Cpu_scheduler::quota(Share &s, unsigned const q) { - assert(s != _idle); - if (s->_quota) { _quota_adaption(s, q); } + assert(&s != &_idle); + if (s._quota) { _quota_adaption(s, q); } else if (q) { _quota_introduction(s); } - s->_quota = q; + s._quota = q; } -Cpu_scheduler::Cpu_scheduler(Share * const i, unsigned const q, +Cpu_share &Cpu_scheduler::head() const +{ + assert(_head); + return *_head; +} + + +Cpu_scheduler::Cpu_scheduler(Share &i, unsigned const q, unsigned const f) : _idle(i), _quota(q), _residual(q), _fill(f) { _set_head(i, f, 0); } diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.h b/repos/base-hw/src/core/kernel/cpu_scheduler.h index 3ca42eef8..e0b6dd079 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.h +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.h @@ -60,7 +60,7 @@ class Kernel::Cpu_priority * Standard operators */ - Cpu_priority & operator =(signed const v) + Cpu_priority &operator =(signed const v) { _value = Genode::min(v, MAX); return *this; @@ -109,19 +109,19 @@ class Kernel::Cpu_scheduler typedef Cpu_share Share; typedef Cpu_priority Prio; - Double_list _rcl[Prio::MAX + 1]; /* ready claims */ - Double_list _ucl[Prio::MAX + 1]; /* unready claims */ - Double_list _fills { }; /* ready fills */ - Share * const _idle; - Share * _head = nullptr; - unsigned _head_quota = 0; - bool _head_claims = false; - bool _head_yields = false; - unsigned const _quota; - unsigned _residual; - unsigned const _fill; - bool _need_to_schedule { true }; - time_t _last_time { 0 }; + Double_list _rcl[Prio::MAX + 1]; /* ready claims */ + Double_list _ucl[Prio::MAX + 1]; /* unready claims */ + Double_list _fills { }; /* ready fills */ + Share &_idle; + Share *_head = nullptr; + unsigned _head_quota = 0; + bool _head_claims = false; + bool _head_yields = false; + unsigned const _quota; + unsigned _residual; + unsigned const _fill; + bool _need_to_schedule { true }; + time_t _last_time { 0 }; template void _for_each_prio(F f) { for (signed p = Prio::MAX; p > Prio::MIN - 1; p--) { f(p); } } @@ -131,28 +131,28 @@ class Kernel::Cpu_scheduler void _reset_claims(unsigned const p); void _next_round(); void _consumed(unsigned const q); - void _set_head(Share * const s, unsigned const q, bool const c); + void _set_head(Share &s, unsigned const q, bool const c); void _next_fill(); void _head_claimed(unsigned const r); void _head_filled(unsigned const r); bool _claim_for_head(); bool _fill_for_head(); - unsigned _trim_consumption(unsigned & q); + unsigned _trim_consumption(unsigned &q); /** * Fill 's' becomes a claim due to a quota donation */ - void _quota_introduction(Share * const s); + void _quota_introduction(Share &s); /** * Claim 's' looses its state as claim due to quota revokation */ - void _quota_revokation(Share * const s); + void _quota_revokation(Share &s); /** * The quota of claim 's' changes to 'q' */ - void _quota_adaption(Share * const s, unsigned const q); + void _quota_adaption(Share &s, unsigned const q); public: @@ -164,7 +164,7 @@ class Kernel::Cpu_scheduler * \param q total amount of time quota that can be claimed by shares * \param f time-slice length of the fill round-robin */ - Cpu_scheduler(Share * const i, unsigned const q, unsigned const f); + Cpu_scheduler(Share &i, unsigned const q, unsigned const f); bool need_to_schedule() { return _need_to_schedule; } void timeout() { _need_to_schedule = true; } @@ -177,17 +177,17 @@ class Kernel::Cpu_scheduler /** * Set 's1' ready and return wether this outdates current head */ - bool ready_check(Share * const s1); + bool ready_check(Share &s1); /** * Set share 's' ready */ - void ready(Share * const s); + void ready(Share &s); /** * Set share 's' unready */ - void unready(Share * const s); + void unready(Share &s); /** * Current head looses its current claim/fill for this round @@ -197,23 +197,23 @@ class Kernel::Cpu_scheduler /** * Remove share 's' from scheduler */ - void remove(Share * const s); + void remove(Share &s); /** * Insert share 's' into scheduler */ - void insert(Share * const s); + void insert(Share &s); /** * Set quota of share 's' to 'q' */ - void quota(Share * const s, unsigned const q); + void quota(Share &s, unsigned const q); /* * Accessors */ - Share * head() const { return _head; } + Share &head() const; unsigned head_quota() const { return Genode::min(_head_quota, _residual); } unsigned quota() const { return _quota; } diff --git a/repos/base-hw/src/test/cpu_scheduler/test.cc b/repos/base-hw/src/test/cpu_scheduler/test.cc index 414228fcf..1bdcd3a7c 100644 --- a/repos/base-hw/src/test/cpu_scheduler/test.cc +++ b/repos/base-hw/src/test/cpu_scheduler/test.cc @@ -33,7 +33,7 @@ struct Data Cpu_scheduler scheduler; char shares[9][sizeof(Cpu_share)]; - Data() : idle(0, 0), scheduler(&idle, 1000, 100) { } + Data() : idle(0, 0), scheduler(idle, 1000, 100) { } }; Data * data() @@ -79,13 +79,13 @@ void create(unsigned const id) case 9: new (p) Cpu_share(2, 0); break; default: return; } - data()->scheduler.insert(s); + data()->scheduler.insert(*s); } void destroy(unsigned const id) { Cpu_share * const s = share(id); - data()->scheduler.remove(s); + data()->scheduler.remove(*s); s->~Cpu_share(); } @@ -104,10 +104,10 @@ void update_check(unsigned const l, unsigned const c, unsigned const t, Genode::log("wrong time ", st, " in line ", l); done(); } - Cpu_share * const hs = data()->scheduler.head(); + Cpu_share &hs = data()->scheduler.head(); unsigned const hq = data()->scheduler.head_quota(); - if (hs != share(s)) { - unsigned const hi = share_id(hs); + if (&hs != share(s)) { + unsigned const hi = share_id(&hs); Genode::log("wrong share ", hi, " in line ", l); done(); } @@ -119,7 +119,7 @@ void update_check(unsigned const l, unsigned const c, unsigned const t, void ready_check(unsigned const l, unsigned const s, bool const x) { - bool const y = data()->scheduler.ready_check(share(s)); + bool const y = data()->scheduler.ready_check(*share(s)); if (y != x) { Genode::log("wrong check result ", y, " in line ", l); done(); @@ -133,10 +133,10 @@ void ready_check(unsigned const l, unsigned const s, bool const x) #define C(s) create(s); #define D(s) destroy(s); -#define A(s) data()->scheduler.ready(share(s)); -#define I(s) data()->scheduler.unready(share(s)); +#define A(s) data()->scheduler.ready(*share(s)); +#define I(s) data()->scheduler.unready(*share(s)); #define Y data()->scheduler.yield(); -#define Q(s, q) data()->scheduler.quota(share(s), q); +#define Q(s, q) data()->scheduler.quota(*share(s), q); #define U(c, t, s, q) update_check(__LINE__, c, t, s, q); #define O(s) ready_check(__LINE__, s, true); #define N(s) ready_check(__LINE__, s, false);