From 2c357a4f04ac4e21d3bd049e69a8fa303d0ee6e8 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 3 Sep 2013 14:20:43 +0200 Subject: [PATCH] hw: scheduler in extra header & asserts reviewed ref #528 --- base-hw/src/core/kernel/scheduler.h | 195 ++++++++++++++++++++++++++ base-hw/src/core/kernel/thread.h | 203 +--------------------------- 2 files changed, 197 insertions(+), 201 deletions(-) create mode 100644 base-hw/src/core/kernel/scheduler.h diff --git a/base-hw/src/core/kernel/scheduler.h b/base-hw/src/core/kernel/scheduler.h new file mode 100644 index 0000000000..0547d36070 --- /dev/null +++ b/base-hw/src/core/kernel/scheduler.h @@ -0,0 +1,195 @@ +/* + * \brief Round-robin scheduler + * \author Martin Stein + * \date 2012-11-30 + */ + +/* + * Copyright (C) 2012-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _KERNEL__SCHEDULER_H_ +#define _KERNEL__SCHEDULER_H_ + +/* core includes */ +#include + +namespace Kernel +{ + /** + * Double connected list of objects of type T + */ + template + class Double_list; + + /** + * Round robin scheduler for objects of type T + */ + template + class Scheduler; +} + +template +class Kernel::Double_list +{ + public: + + /** + * Enable deriving objects to be inserted into a double list + */ + class Item; + + private: + + Item * _head; + Item * _tail; + + public: + + /** + * Constructor + */ + Double_list(): _head(0), _tail(0) { } + + /** + * Insert item 't' from behind into list + */ + void insert_tail(T * const t) + { + Item * i = static_cast(t); + assert(i && !i->Item::_list); + + /* update new item */ + i->_prev = _tail; + i->_next = 0; + i->_list = this; + + /* update rest of the list */ + if (_tail) { _tail->_next = i; } + else { _head = i; } + _tail = i; + } + + /** + * Remove item 't' from list + */ + void remove(T * const t) + { + Item * i = static_cast(t); + assert(_head && i && i->Item::_list == this); + + /* update next item or _tail */ + if (i != _tail) { i->_next->_prev = i->_prev; } + else { _tail = i->_prev; } + + /* update previous item or _head */ + if (i != _head) { i->_prev->_next = i->_next; } + else { _head = i->_next; } + + /* update removed item */ + i->_list = 0; + } + + /** + * Remove head from list and insert it at the end + */ + void head_to_tail() + { + /* exit if nothing to do */ + if (!_head || _head == _tail) { return; } + + /* remove head */ + Item * const i = _head; + _head = _head->_next; + i->_next = 0; + _head->_prev = 0; + + /* insert tail */ + _tail->_next = i; + i->_prev = _tail; + _tail = i; + } + + + /*************** + ** Accessors ** + ***************/ + + T * head() const { return static_cast(_head); } +}; + +template +class Kernel::Double_list::Item +{ + friend class Double_list; + + private: + + Item * _next; + Item * _prev; + Double_list * _list; + + public: + + /** + * Constructor + */ + Item() : _next(0), _prev(0), _list(0) { } +}; + +template +class Kernel::Scheduler +{ + public: + + /** + * Capability to be item in a scheduler through inheritance + */ + class Item : public Double_list::Item { }; + + protected: + + T * const _idle; + Double_list _items; + + public: + + /** + * Constructor + */ + Scheduler(T * const idle) : _idle(idle) { } + + /** + * Get currently scheduled item + */ + T * head() const + { + T * const i = _items.head(); + if (i) { return i; } + return _idle; + } + + /** + * End turn of currently scheduled item + */ + void yield() { _items.head_to_tail(); } + + /** + * Include 'i' in scheduling + */ + void insert(T * const i) + { + assert(i != _idle); + _items.insert_tail(i); + } + + /** + * Exclude 'i' from scheduling + */ + void remove(T * const i) { _items.remove(i); } +}; + +#endif /* _KERNEL__SCHEDULER_H_ */ diff --git a/base-hw/src/core/kernel/thread.h b/base-hw/src/core/kernel/thread.h index d9eb0ef29d..edccf362cb 100644 --- a/base-hw/src/core/kernel/thread.h +++ b/base-hw/src/core/kernel/thread.h @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace Genode @@ -42,213 +43,13 @@ namespace Kernel template class Fifo : public Genode::Fifo { }; - /** - * Double connected list - * - * \param _ENTRY_T list entry type - */ - template - class Double_list - { - private: - - _ENTRY_T * _head; - _ENTRY_T * _tail; - - public: - - /** - * Provide 'Double_list'-entry compliance by inheritance - */ - class Entry - { - friend class Double_list<_ENTRY_T>; - - private: - - _ENTRY_T * _next; - _ENTRY_T * _prev; - Double_list<_ENTRY_T> * _list; - - public: - - /** - * Constructor - */ - Entry() : _next(0), _prev(0), _list(0) { } - - - /*************** - ** Accessors ** - ***************/ - - _ENTRY_T * next() const { return _next; } - - _ENTRY_T * prev() const { return _prev; } - }; - - public: - - /** - * Constructor - * - * Start with an empty list. - */ - Double_list(): _head(0), _tail(0) { } - - /** - * Insert entry from behind into list - */ - void insert_tail(_ENTRY_T * const e) - { - /* avoid leaking lists */ - if (e->Entry::_list) - e->Entry::_list->remove(e); - - /* update new entry */ - e->Entry::_prev = _tail; - e->Entry::_next = 0; - e->Entry::_list = this; - - /* update previous entry or _head */ - if (_tail) _tail->Entry::_next = e; /* List was not empty */ - else _head = e; /* List was empty */ - _tail = e; - } - - /** - * Remove specific entry from list - */ - void remove(_ENTRY_T * const e) - { - /* sanity checks */ - if (!_head || e->Entry::_list != this) return; - - /* update next entry or _tail */ - if (e != _tail) e->Entry::_next->Entry::_prev = e->Entry::_prev; - else _tail = e->Entry::_prev; - - /* update previous entry or _head */ - if (e != _head) e->Entry::_prev->Entry::_next = e->Entry::_next; - else _head = e->Entry::_next; - - /* update removed entry */ - e->Entry::_list = 0; - } - - /** - * Remove head from list and return it - */ - _ENTRY_T * remove_head() - { - /* sanity checks */ - if (!_head) return 0; - - /* update _head */ - _ENTRY_T * const e = _head; - _head = e->Entry::_next; - - /* update next entry or _tail */ - if (_head) _head->Entry::_prev = 0; - else _tail = 0; - - /* update removed entry */ - e->Entry::_list = 0; - return e; - } - - /** - * Remove head from list and insert it at the end - */ - void head_to_tail() - { - /* sanity checks */ - if (!_head || _head == _tail) return; - - /* remove entry */ - _ENTRY_T * const e = _head; - _head = _head->Entry::_next; - e->Entry::_next = 0; - _head->Entry::_prev = 0; - - /* insert entry */ - _tail->Entry::_next = e; - e->Entry::_prev = _tail; - _tail = e; - } - - - /*************** - ** Accessors ** - ***************/ - - _ENTRY_T * head() const { return _head; } - - _ENTRY_T * tail() const { return _tail; } - }; - - /** - * Simple round robin scheduler for 'ENTRY_T' typed clients - */ - template - class Scheduler - { - public: - - /** - * Provides schedulability through inheritance - */ - class Entry : public Double_list::Entry { }; - - protected: - - /* gets scheduled when '_entries' is empty */ - ENTRY_T * const _idle; - - /* scheduling participants beside '_idle' */ - Double_list _entries; - - public: - - /** - * Constructor - */ - Scheduler(ENTRY_T * const idle) - : _idle(idle) { assert(_idle); } - - /** - * Get currently scheduled entry - */ - ENTRY_T * head() const { - return _entries.head() ? _entries.head() : _idle; } - - /** - * End turn of currently scheduled entry - */ - void yield() { _entries.head_to_tail(); } - - /** - * Include 'e' in scheduling - */ - void insert(ENTRY_T * const e) - { - if (e == _idle) return; - _entries.insert_tail(e); - } - - /** - * Exclude 'e' from scheduling - */ - void remove(ENTRY_T * const e) { _entries.remove(e); } - }; - class Schedule_context; typedef Scheduler Cpu_scheduler; /** * Kernel object that can be scheduled for the CPU */ - class Schedule_context : public Cpu_scheduler::Entry + class Schedule_context : public Cpu_scheduler::Item { public: