mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
a753b6ce46
commit
eef7b5e168
@ -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
|
||||
|
@ -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); });
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<Cpu_claim> {
|
||||
|
||||
public:
|
||||
|
||||
Cpu_claim() : Double_list_item<Cpu_claim>(*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<Cpu_fill> {
|
||||
|
||||
public:
|
||||
|
||||
Cpu_fill() : Double_list_item<Cpu_fill>(*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> Claim_list;
|
||||
typedef Double_list_typed<Fill> Fill_list;
|
||||
typedef Cpu_priority Prio;
|
||||
typedef Cpu_share Share;
|
||||
typedef Cpu_fill Fill;
|
||||
typedef Cpu_claim Claim;
|
||||
typedef Double_list<Claim> Claim_list;
|
||||
typedef Double_list<Fill> 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 <typename T>
|
||||
static Share * _share(T * const t) { return static_cast<Share *>(t); }
|
||||
|
||||
static void _reset(Claim * const c);
|
||||
static void _reset(Claim &c);
|
||||
|
||||
void _reset_claims(unsigned const p);
|
||||
void _next_round();
|
||||
|
@ -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 <kernel/double_list.h>
|
||||
|
||||
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;
|
||||
}
|
@ -19,78 +19,130 @@ namespace Kernel
|
||||
/**
|
||||
* Ability to be an item in a double connected list
|
||||
*/
|
||||
template <typename T>
|
||||
class Double_list_item;
|
||||
|
||||
/**
|
||||
* List of double connected items
|
||||
*/
|
||||
template <typename T>
|
||||
class Double_list;
|
||||
|
||||
/**
|
||||
* Double list over objects of type 'T' that inherits from double-list item
|
||||
*/
|
||||
template <typename T> class Double_list_typed;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class Kernel::Double_list_item
|
||||
{
|
||||
friend class Double_list;
|
||||
friend class Double_list<T>;
|
||||
|
||||
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 <typename T>
|
||||
class Kernel::Double_list
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Double_list_item Item;
|
||||
typedef Double_list_item<T> 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 <typename F> 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 <typename T> class Kernel::Double_list_typed : public Double_list
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Double_list_item Item;
|
||||
|
||||
static T * _typed(Item * const i) {
|
||||
return i ? static_cast<T *>(i) : 0; }
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* 'Double_list' interface
|
||||
*/
|
||||
|
||||
template <typename F> 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_ */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<Item>
|
||||
{
|
||||
unsigned _id;
|
||||
|
||||
Item(unsigned const id) : _id(id) { x = 1; y = 2; z = 3; }
|
||||
Item(unsigned const id) : Double_list_item<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<Item> list { };
|
||||
Double_list<Item> 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<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) {
|
||||
|
Loading…
Reference in New Issue
Block a user