mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-29 15:44:02 +00:00
parent
c146a215fb
commit
0d5f185267
@ -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(); }
|
||||
|
@ -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<Job *>(_scheduler.head())->helping_sink(); }
|
||||
return *static_cast<Job *>(&_scheduler.head())->helping_sink(); }
|
||||
|
||||
unsigned id() const { return _id; }
|
||||
Cpu_scheduler &scheduler() { return _scheduler; }
|
||||
|
@ -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<Cpu_share>::next(&s2->_claim_item) != nullptr ?
|
||||
&Double_list<Cpu_share>::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); }
|
||||
|
@ -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<Cpu_share> _rcl[Prio::MAX + 1]; /* ready claims */
|
||||
Double_list<Cpu_share> _ucl[Prio::MAX + 1]; /* unready claims */
|
||||
Double_list<Cpu_share> _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<Cpu_share> _rcl[Prio::MAX + 1]; /* ready claims */
|
||||
Double_list<Cpu_share> _ucl[Prio::MAX + 1]; /* unready claims */
|
||||
Double_list<Cpu_share> _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 <typename F> 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; }
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user