diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.cc b/repos/base-hw/src/core/kernel/cpu_scheduler.cc index 7333cab8d1..d177c1b07e 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.cc +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.cc @@ -18,14 +18,16 @@ using namespace Kernel; -void Cpu_scheduler::_reset(Claim &c) { - _share(&c)->_claim = _share(&c)->_quota; } +void Cpu_scheduler::_reset(Cpu_share &share) +{ + share._claim = share._quota; +} void Cpu_scheduler::_reset_claims(unsigned const p) { - _rcl[p].for_each([&] (Claim &c) { _reset(c); }); - _ucl[p].for_each([&] (Claim &c) { _reset(c); }); + _rcl[p].for_each([&] (Cpu_share &share) { _reset(share); }); + _ucl[p].for_each([&] (Cpu_share &share) { _reset(share); }); } @@ -63,13 +65,13 @@ void Cpu_scheduler::_head_claimed(unsigned const r) if (!_head->_quota) { return; } _head->_claim = r > _head->_quota ? _head->_quota : r; if (_head->_claim || !_head->_ready) { return; } - _rcl[_head->_prio].to_tail(_head); + _rcl[_head->_prio].to_tail(&_head->_claim_item); } void Cpu_scheduler::_head_filled(unsigned const r) { - if (_fills.head() != _head) { return; } + if (_fills.head() != &_head->_fill_item) { return; } if (r) { _head->_fill = r; } else { _next_fill(); } } @@ -78,10 +80,11 @@ void Cpu_scheduler::_head_filled(unsigned const r) bool Cpu_scheduler::_claim_for_head() { for (signed p = Prio::MAX; p > Prio::MIN - 1; p--) { - Share * const s = _share(_rcl[p].head()); - if (!s) { continue; } - if (!s->_claim) { continue; } - _set_head(s, s->_claim, 1); + Double_list_item *const item { _rcl[p].head() }; + if (!item) { continue; } + Cpu_share &share { item->payload() }; + if (!share._claim) { continue; } + _set_head(&share, share._claim, 1); return 1; } return 0; @@ -90,9 +93,12 @@ bool Cpu_scheduler::_claim_for_head() bool Cpu_scheduler::_fill_for_head() { - Share * const s = _share(_fills.head()); - if (!s) { return 0; } - _set_head(s, s->_fill, 0); + Double_list_item *const item { _fills.head() }; + if (!item) { + return 0; + } + Share &share = item->payload(); + _set_head(&share, share._fill, 0); return 1; } @@ -108,15 +114,15 @@ unsigned Cpu_scheduler::_trim_consumption(unsigned & q) void Cpu_scheduler::_quota_introduction(Share * const s) { - if (s->_ready) { _rcl[s->_prio].insert_tail(s); } - else { _ucl[s->_prio].insert_tail(s); } + 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) { - if (s->_ready) { _rcl[s->_prio].remove(s); } - else { _ucl[s->_prio].remove(s); } + if (s->_ready) { _rcl[s->_prio].remove(&s->_claim_item); } + else { _ucl[s->_prio].remove(&s->_claim_item); } } @@ -163,7 +169,13 @@ bool Cpu_scheduler::ready_check(Share * const s1) } else if (s1->_prio != s2->_prio) { _need_to_schedule = s1->_prio > s2->_prio; } else { - for (; s2 && s2 != s1; s2 = _share(Claim_list::next(s2))) ; + for ( + ; s2 && s2 != s1; + s2 = + Double_list::next(&s2->_claim_item) != nullptr ? + &Double_list::next(&s2->_claim_item)->payload() : + nullptr) ; + _need_to_schedule = !s2; } return _need_to_schedule; @@ -178,11 +190,11 @@ void Cpu_scheduler::ready(Share * const s) s->_ready = 1; s->_fill = _fill; - _fills.insert_tail(s); + _fills.insert_tail(&s->_fill_item); if (!s->_quota) { return; } - _ucl[s->_prio].remove(s); - if (s->_claim) { _rcl[s->_prio].insert_head(s); } - else { _rcl[s->_prio].insert_tail(s); } + _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); } } @@ -193,10 +205,10 @@ void Cpu_scheduler::unready(Share * const s) _need_to_schedule = true; s->_ready = 0; - _fills.remove(s); + _fills.remove(&s->_fill_item); if (!s->_quota) { return; } - _rcl[s->_prio].remove(s); - _ucl[s->_prio].insert_tail(s); + _rcl[s->_prio].remove(&s->_claim_item); + _ucl[s->_prio].insert_tail(&s->_claim_item); } @@ -213,10 +225,10 @@ void Cpu_scheduler::remove(Share * const s) _need_to_schedule = true; if (s == _head) _head = nullptr; - if (s->_ready) { _fills.remove(s); } + if (s->_ready) { _fills.remove(&s->_fill_item); } if (!s->_quota) { return; } - if (s->_ready) { _rcl[s->_prio].remove(s); } - else { _ucl[s->_prio].remove(s); } + if (s->_ready) { _rcl[s->_prio].remove(&s->_claim_item); } + else { _ucl[s->_prio].remove(&s->_claim_item); } } @@ -226,7 +238,7 @@ void Cpu_scheduler::insert(Share * const s) _need_to_schedule = true; if (!s->_quota) { return; } s->_claim = s->_quota; - _ucl[s->_prio].insert_head(s); + _ucl[s->_prio].insert_head(&s->_claim_item); } diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.h b/repos/base-hw/src/core/kernel/cpu_scheduler.h index b10cc04d58..3ca42eef80 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.h +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.h @@ -27,26 +27,6 @@ namespace Kernel */ class Cpu_priority; - /** - * Scheduling context that has quota and priority (low-latency) - */ - class Cpu_claim : public Double_list_item { - - public: - - Cpu_claim() : Double_list_item(*this) {} - }; - - /** - * Scheduling context that has no quota or priority (best effort) - */ - class Cpu_fill : public Double_list_item { - - public: - - Cpu_fill() : Double_list_item(*this) {} - }; - /** * Scheduling context that is both claim and fill */ @@ -89,17 +69,19 @@ class Kernel::Cpu_priority operator signed() const { return _value; } }; -class Kernel::Cpu_share : public Cpu_claim, public Cpu_fill +class Kernel::Cpu_share { friend class Cpu_scheduler; private: - signed const _prio; - unsigned _quota; - unsigned _claim; - unsigned _fill = 0; - bool _ready = false; + Double_list_item _fill_item { *this }; + Double_list_item _claim_item { *this }; + signed const _prio; + unsigned _quota; + unsigned _claim; + unsigned _fill { 0 }; + bool _ready { false }; public: @@ -124,34 +106,27 @@ class Kernel::Cpu_scheduler { private: - typedef Cpu_share Share; - typedef Cpu_fill Fill; - typedef Cpu_claim Claim; - typedef Double_list Claim_list; - typedef Double_list Fill_list; - typedef Cpu_priority Prio; + typedef Cpu_share Share; + typedef Cpu_priority Prio; - Claim_list _rcl[Prio::MAX + 1]; /* ready claims */ - Claim_list _ucl[Prio::MAX + 1]; /* unready claims */ - Fill_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 * 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 }; template void _for_each_prio(F f) { for (signed p = Prio::MAX; p > Prio::MIN - 1; p--) { f(p); } } - template - static Share * _share(T * const t) { return static_cast(t); } - - static void _reset(Claim &c); + static void _reset(Cpu_share &share); void _reset_claims(unsigned const p); void _next_round();