From eef7b5e168fd353f2bf2f352ef6e35683283ec79 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 23 Dec 2019 23:01:20 +0100 Subject: [PATCH] base-hw: double list without inheritance Ref #3308 --- repos/base-hw/lib/mk/core-hw.inc | 1 - .../base-hw/src/core/kernel/cpu_scheduler.cc | 8 +- repos/base-hw/src/core/kernel/cpu_scheduler.h | 28 +++-- repos/base-hw/src/core/kernel/double_list.cc | 86 -------------- repos/base-hw/src/core/kernel/double_list.h | 110 +++++++++++------- .../base-hw/src/test/cpu_scheduler/target.mk | 2 +- repos/base-hw/src/test/double_list/target.mk | 2 +- repos/base-hw/src/test/double_list/test.cc | 31 ++--- 8 files changed, 110 insertions(+), 158 deletions(-) delete mode 100644 repos/base-hw/src/core/kernel/double_list.cc diff --git a/repos/base-hw/lib/mk/core-hw.inc b/repos/base-hw/lib/mk/core-hw.inc index 7517c011a0..1eb86d9f0c 100644 --- a/repos/base-hw/lib/mk/core-hw.inc +++ b/repos/base-hw/lib/mk/core-hw.inc @@ -52,7 +52,6 @@ SRC_CC += pager.cc SRC_CC += _main.cc SRC_CC += kernel/cpu.cc SRC_CC += kernel/cpu_scheduler.cc -SRC_CC += kernel/double_list.cc SRC_CC += kernel/init.cc SRC_CC += kernel/ipc_node.cc SRC_CC += kernel/irq.cc diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.cc b/repos/base-hw/src/core/kernel/cpu_scheduler.cc index c8ef27c025..7333cab8d1 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.cc +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.cc @@ -18,14 +18,14 @@ using namespace Kernel; -void Cpu_scheduler::_reset(Claim * const c) { - _share(c)->_claim = _share(c)->_quota; } +void Cpu_scheduler::_reset(Claim &c) { + _share(&c)->_claim = _share(&c)->_quota; } void Cpu_scheduler::_reset_claims(unsigned const p) { - _rcl[p].for_each([&] (Claim * const c) { _reset(c); }); - _ucl[p].for_each([&] (Claim * const c) { _reset(c); }); + _rcl[p].for_each([&] (Claim &c) { _reset(c); }); + _ucl[p].for_each([&] (Claim &c) { _reset(c); }); } diff --git a/repos/base-hw/src/core/kernel/cpu_scheduler.h b/repos/base-hw/src/core/kernel/cpu_scheduler.h index d6ec38345d..b10cc04d58 100644 --- a/repos/base-hw/src/core/kernel/cpu_scheduler.h +++ b/repos/base-hw/src/core/kernel/cpu_scheduler.h @@ -30,12 +30,22 @@ namespace Kernel /** * Scheduling context that has quota and priority (low-latency) */ - class Cpu_claim : public Double_list_item { }; + 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 { }; + class Cpu_fill : public Double_list_item { + + public: + + Cpu_fill() : Double_list_item(*this) {} + }; /** * Scheduling context that is both claim and fill @@ -114,12 +124,12 @@ class Kernel::Cpu_scheduler { private: - typedef Cpu_share Share; - typedef Cpu_fill Fill; - typedef Cpu_claim Claim; - typedef Double_list_typed Claim_list; - typedef Double_list_typed Fill_list; - typedef Cpu_priority Prio; + 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; Claim_list _rcl[Prio::MAX + 1]; /* ready claims */ Claim_list _ucl[Prio::MAX + 1]; /* unready claims */ @@ -141,7 +151,7 @@ class Kernel::Cpu_scheduler template static Share * _share(T * const t) { return static_cast(t); } - static void _reset(Claim * const c); + static void _reset(Claim &c); void _reset_claims(unsigned const p); void _next_round(); diff --git a/repos/base-hw/src/core/kernel/double_list.cc b/repos/base-hw/src/core/kernel/double_list.cc deleted file mode 100644 index 6b3af8cf92..0000000000 --- a/repos/base-hw/src/core/kernel/double_list.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - * \brief List of double connected items - * \author Martin Stein - * \date 2012-11-30 - */ - -/* - * Copyright (C) 2012-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* core includes */ -#include - -using namespace Kernel; - - -void Double_list::_connect_neighbors(Item * const i) -{ - i->_prev->_next = i->_next; - i->_next->_prev = i->_prev; -} - - -void Double_list::_to_tail(Item * const i) -{ - if (i == _tail) { return; } - _connect_neighbors(i); - i->_prev = _tail; - i->_next = 0; - _tail->_next = i; - _tail = i; -} - - -Double_list::Double_list(): _head(0), _tail(0) { } - - -void Double_list::to_tail(Item * const i) -{ - if (i == _head) { head_to_tail(); } - else { _to_tail(i); } -} - - -void Double_list::insert_tail(Item * const i) -{ - if (_tail) { _tail->_next = i; } - else { _head = i; } - i->_prev = _tail; - i->_next = 0; - _tail = i; -} - - -void Double_list::insert_head(Item * const i) -{ - if (_head) { _head->_prev = i; } - else { _tail = i; } - i->_next = _head; - i->_prev = 0; - _head = i; -} - - -void Double_list::remove(Item * const i) -{ - if (i == _tail) { _tail = i->_prev; } - else { i->_next->_prev = i->_prev; } - if (i == _head) { _head = i->_next; } - else { i->_prev->_next = i->_next; } -} - - -void Double_list::head_to_tail() -{ - if (!_head || _head == _tail) { return; } - _head->_prev = _tail; - _tail->_next = _head; - _head = _head->_next; - _head->_prev = 0; - _tail = _tail->_next; - _tail->_next = 0; -} diff --git a/repos/base-hw/src/core/kernel/double_list.h b/repos/base-hw/src/core/kernel/double_list.h index 6ee4deb41c..4f4001a001 100644 --- a/repos/base-hw/src/core/kernel/double_list.h +++ b/repos/base-hw/src/core/kernel/double_list.h @@ -19,78 +19,130 @@ namespace Kernel /** * Ability to be an item in a double connected list */ + template class Double_list_item; /** * List of double connected items */ + template class Double_list; - - /** - * Double list over objects of type 'T' that inherits from double-list item - */ - template class Double_list_typed; } +template class Kernel::Double_list_item { - friend class Double_list; + friend class Double_list; private: Double_list_item * _next = nullptr; Double_list_item * _prev = nullptr; + T & _payload; + + public: + + Double_list_item(T &payload) : _payload(payload) { } + + T &payload() { return _payload; } }; +template class Kernel::Double_list { private: - typedef Double_list_item Item; + typedef Double_list_item Item; Item * _head; Item * _tail; - void _connect_neighbors(Item * const i); - void _to_tail(Item * const i); + void _connect_neighbors(Item * const i) + { + i->_prev->_next = i->_next; + i->_next->_prev = i->_prev; + } + + void _to_tail(Item * const i) + { + if (i == _tail) { return; } + _connect_neighbors(i); + i->_prev = _tail; + i->_next = 0; + _tail->_next = i; + _tail = i; + } public: /** * Construct empty list */ - Double_list(); + Double_list() : _head(0), _tail(0) { } /** * Move item 'i' from its current list position to the tail */ - void to_tail(Item * const i); + void to_tail(Item * const i) + { + if (i == _head) { head_to_tail(); } + else { _to_tail(i); } + } /** * Insert item 'i' as new tail into list */ - void insert_tail(Item * const i); + void insert_tail(Item * const i) + { + if (_tail) { _tail->_next = i; } + else { _head = i; } + i->_prev = _tail; + i->_next = 0; + _tail = i; + } /** * Insert item 'i' as new head into list */ - void insert_head(Item * const i); + void insert_head(Item * const i) + { + if (_head) { _head->_prev = i; } + else { _tail = i; } + i->_next = _head; + i->_prev = 0; + _head = i; + } /** * Remove item 'i' from list */ - void remove(Item * const i); + void remove(Item * const i) + { + if (i == _tail) { _tail = i->_prev; } + else { i->_next->_prev = i->_prev; } + if (i == _head) { _head = i->_next; } + else { i->_prev->_next = i->_next; } + } /** * Move head item of list to tail position */ - void head_to_tail(); + void head_to_tail() + { + if (!_head || _head == _tail) { return; } + _head->_prev = _tail; + _tail->_next = _head; + _head = _head->_next; + _head->_prev = 0; + _tail = _tail->_next; + _tail->_next = 0; + } /** * Call function 'f' of type 'void (Item *)' for each item in the list */ template void for_each(F f) { - for (Item * i = _head; i; i = i->_next) { f(i); } } + for (Item * i = _head; i; i = i->_next) { f(i->payload()); } } /* * Accessors @@ -100,30 +152,4 @@ class Kernel::Double_list static Item * next(Item * const i) { return i->_next; } }; -template class Kernel::Double_list_typed : public Double_list -{ - private: - - typedef Double_list_item Item; - - static T * _typed(Item * const i) { - return i ? static_cast(i) : 0; } - - public: - - /* - * 'Double_list' interface - */ - - template void for_each(F f) { - Double_list::for_each([&] (Item * const i) { f(_typed(i)); }); } - - void to_tail(T * const t) { Double_list::to_tail(t); } - void insert_tail(T * const t) { Double_list::insert_tail(t); } - void insert_head(T * const t) { Double_list::insert_head(t); } - void remove(T * const t) { Double_list::remove(t); } - static T * next(T * const t) { return _typed(Double_list::next(t)); } - T * head() const { return _typed(Double_list::head()); } -}; - #endif /* _CORE__KERNEL__DOUBLE_LIST_H_ */ diff --git a/repos/base-hw/src/test/cpu_scheduler/target.mk b/repos/base-hw/src/test/cpu_scheduler/target.mk index 9512f86d35..1aad543c50 100644 --- a/repos/base-hw/src/test/cpu_scheduler/target.mk +++ b/repos/base-hw/src/test/cpu_scheduler/target.mk @@ -5,7 +5,7 @@ # TARGET = test-cpu_scheduler -SRC_CC = test.cc cpu_scheduler.cc double_list.cc +SRC_CC = test.cc cpu_scheduler.cc INC_DIR += $(REP_DIR)/src/core $(REP_DIR)/src/include $(BASE_DIR)/src/include LIBS = base diff --git a/repos/base-hw/src/test/double_list/target.mk b/repos/base-hw/src/test/double_list/target.mk index 159690dbf6..5fc7acf945 100644 --- a/repos/base-hw/src/test/double_list/target.mk +++ b/repos/base-hw/src/test/double_list/target.mk @@ -6,7 +6,7 @@ TARGET = test-double_list INC_DIR = $(REP_DIR)/src/core -SRC_CC = test.cc double_list.cc +SRC_CC = test.cc LIBS = base vpath double_list.cc $(REP_DIR)/src/core/kernel diff --git a/repos/base-hw/src/test/double_list/test.cc b/repos/base-hw/src/test/double_list/test.cc index 1f8bf12828..17d314bfa5 100644 --- a/repos/base-hw/src/test/double_list/test.cc +++ b/repos/base-hw/src/test/double_list/test.cc @@ -24,18 +24,18 @@ */ using Genode::size_t; -using Kernel::Double_list_typed; +using Kernel::Double_list; using Kernel::Double_list_item; void * operator new(__SIZE_TYPE__, void * p) { return p; } struct Item_load { char volatile x = 0, y = 0, z = 0; }; -struct Item : Item_load, Double_list_item +struct Item : Item_load, Double_list_item { unsigned _id; - Item(unsigned const id) : _id(id) { x = 1; y = 2; z = 3; } + Item(unsigned const id) : Double_list_item(*this), _id(id) { x = 1; y = 2; z = 3; } void iteration() { Genode::log(_id); } }; @@ -44,7 +44,7 @@ struct Data { static constexpr unsigned nr_of_items = 9; - Double_list_typed list { }; + Double_list list { }; char items[nr_of_items][sizeof(Item)]; Data() @@ -68,24 +68,27 @@ void done() void check(unsigned i1, unsigned l) { - Item * const i2 = data()->list.head(); - if (i1 && i2) { - if(i1 == i2->_id) { return; } - Genode::log("head ", i2->_id, " in line ", l); - done(); - } else if (i1 && !i2) { + Double_list_item * const li2 = data()->list.head(); + if (li2) { + Item * const i2 = &li2->payload(); + if (i1) { + if(i1 == i2->_id) { return; } + Genode::log("head ", i2->_id, " in line ", l); + done(); + } else { + Genode::log("non-empty ", i2->_id, " in line ", l); + done(); + } + } else if (i1) { Genode::log("empty in line ", l); done(); - } else if (!i1 && i2){ - Genode::log("non-empty ", i2->_id, " in line ", l); - done(); } } void print_each() { Genode::log("print each"); - data()->list.for_each([] (Item * const i) { i->iteration(); }); + data()->list.for_each([] (Item &i) { i.iteration(); }); } Item * item(unsigned const i) {