hw: rename head in scheduler to current

The name head is already extensively used in the context of the lists
managed by the scheduler. This terminology duplications does not simplify
reading the code. Instead we keep head for the first item in the list,
but use `current` in the variable name and API of the `Cpu_scheduler`
class to refer to the current scheduled share.

Moreover, the `_head_quota` is now `_current_time_left`, because it does
not denote quota but time left for the current schedule. The boolean
variable `_head_claims` gets removed at all. It duplicated the state of
whether a current share ist set, and whether it has so-called claim time
left.

Ref genodelabs/genode#5115
This commit is contained in:
Stefan Kalkowski 2024-02-07 13:00:29 +01:00 committed by Christian Helmuth
parent 2f727fb5c6
commit 9d72c21894
5 changed files with 277 additions and 292 deletions

View File

@ -151,7 +151,7 @@ Cpu_job & Cpu::schedule()
if (_scheduler.need_to_schedule()) {
_timer.process_timeouts();
_scheduler.update(_timer.time());
time_t t = _scheduler.head_quota();
time_t t = _scheduler.current_time_left();
_timer.set_timeout(this, t);
time_t duration = _timer.schedule_timeout();
old_job.update_execution_time(duration);

View File

@ -192,7 +192,7 @@ class Kernel::Cpu : public Core::Cpu, private Irq::Pool, private Timeout
* Returns the currently active job
*/
Job & scheduled_job() {
return *static_cast<Job *>(&_scheduler.head())->helping_destination(); }
return *static_cast<Job *>(&_scheduler.current())->helping_destination(); }
unsigned id() const { return _id; }
Cpu_scheduler &scheduler() { return _scheduler; }

View File

@ -43,25 +43,24 @@ void Cpu_scheduler::_consumed(unsigned const q)
}
void Cpu_scheduler::_set_head(Share &s, unsigned const q, bool const c)
void Cpu_scheduler::_set_current(Share &s, unsigned const q)
{
_head_quota = q;
_head_claims = c;
_head = &s;
_current_quantum = q;
_current = &s;
}
void Cpu_scheduler::_head_claimed(unsigned const r)
void Cpu_scheduler::_current_claimed(unsigned const r)
{
if (!_head->_quota)
if (!_current->_quota)
return;
_head->_claim = r > _head->_quota ? _head->_quota : r;
_current->_claim = r > _current->_quota ? _current->_quota : r;
if (_head->_claim || !_head->_ready)
if (_current->_claim || !_current->_ready)
return;
_rcl[_head->_prio].to_tail(&_head->_claim_item);
_rcl[_current->_prio].to_tail(&_current->_claim_item);
/*
* This is an optimization for the case that a prioritized scheduling
@ -71,26 +70,26 @@ void Cpu_scheduler::_head_claimed(unsigned const r)
* at least ensure that it does not have to wait for all unprioritized
* scheduling contexts as well before being scheduled again.
*/
if (!_head_yields)
_fills.to_head(&_head->_fill_item);
if (!_yield)
_fills.to_head(&_current->_fill_item);
}
void Cpu_scheduler::_head_filled(unsigned const r)
void Cpu_scheduler::_current_filled(unsigned const r)
{
if (_fills.head() != _head)
if (_fills.head() != _current)
return;
if (r)
_head->_fill = r;
_current->_fill = r;
else {
_head->_fill = _fill;
_current->_fill = _fill;
_fills.head_to_tail();
}
}
bool Cpu_scheduler::_claim_for_head()
bool Cpu_scheduler::_schedule_claim()
{
bool result { false };
_for_each_prio([&] (Cpu_priority const p, bool &cancel_for_each_prio) {
@ -102,7 +101,7 @@ bool Cpu_scheduler::_claim_for_head()
if (!share->_claim)
return;
_set_head(*share, share->_claim, 1);
_set_current(*share, share->_claim);
result = true;
cancel_for_each_prio = true;
});
@ -110,22 +109,22 @@ bool Cpu_scheduler::_claim_for_head()
}
bool Cpu_scheduler::_fill_for_head()
bool Cpu_scheduler::_schedule_fill()
{
Cpu_share *const share = _fills.head();
if (!share)
return false;
_set_head(*share, share->_fill, 0);
_set_current(*share, share->_fill);
return true;
}
unsigned Cpu_scheduler::_trim_consumption(unsigned &q)
{
q = Genode::min(Genode::min(q, _head_quota), _super_period_left);
if (!_head_yields)
return _head_quota - q;
q = Genode::min(Genode::min(q, _current_quantum), _super_period_left);
if (!_yield)
return _current_quantum - q;
return 0;
}
@ -133,59 +132,50 @@ unsigned Cpu_scheduler::_trim_consumption(unsigned &q)
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 &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 &s, unsigned const q)
{
if (q) {
if (s._claim > q)
s._claim = q;
} else {
_quota_revokation(s);
}
if (s._claim > q) s._claim = q;
if (!q) _quota_revokation(s);
}
void Cpu_scheduler::update(time_t time)
{
using namespace Genode;
unsigned duration = (unsigned) (time - _last_time);
_last_time = time;
_need_to_schedule = false;
unsigned const r = _trim_consumption(duration);
/* do not detract the quota if the head context was removed even now */
if (_head) {
if (_head_claims)
_head_claimed(r);
else
_head_filled(r);
/* do not detract the quota if the current share was removed even now */
if (_current) {
if (_current->_claim) _current_claimed(r);
else _current_filled(r);
}
_head_yields = false;
_yield = false;
_consumed(duration);
if (_claim_for_head())
if (_schedule_claim())
return;
if (_fill_for_head())
if (_schedule_fill())
return;
_set_head(_idle, _fill, 0);
_set_current(_idle, _fill);
}
@ -200,9 +190,9 @@ void Cpu_scheduler::ready(Share &s)
if (s._claim) {
_rcl[s._prio].insert_head(&s._claim_item);
if (_head && _head_claims) {
if (_current && _current->_claim) {
if (s._prio >= _head->_prio)
if (s._prio >= _current->_prio)
_need_to_schedule = true;
} else
_need_to_schedule = true;
@ -215,7 +205,7 @@ void Cpu_scheduler::ready(Share &s)
s._fill = _fill;
_fills.insert_tail(&s._fill_item);
if (!_head || _head == &_idle) _need_to_schedule = true;
if (!_current || _current == &_idle) _need_to_schedule = true;
}
@ -223,7 +213,7 @@ void Cpu_scheduler::unready(Share &s)
{
assert(s._ready && &s != &_idle);
if (&s == _head)
if (&s == _current)
_need_to_schedule = true;
s._ready = false;
@ -239,7 +229,7 @@ void Cpu_scheduler::unready(Share &s)
void Cpu_scheduler::yield()
{
_head_yields = true;
_yield = true;
_need_to_schedule = true;
}
@ -250,8 +240,8 @@ void Cpu_scheduler::remove(Share &s)
if (s._ready) unready(s);
if (&s == _head)
_head = nullptr;
if (&s == _current)
_current = nullptr;
if (!s._quota)
return;
@ -285,13 +275,13 @@ void Cpu_scheduler::quota(Share &s, unsigned const q)
}
Cpu_share &Cpu_scheduler::head()
Cpu_share &Cpu_scheduler::current()
{
if (!_head) {
Genode::error("attempt to access invalid scheduler head");
if (!_current) {
Genode::error("attempt to access invalid scheduler's current share");
update(_last_time);
}
return *_head;
return *_current;
}
@ -301,8 +291,7 @@ Cpu_scheduler::Cpu_scheduler(Share &idle,
:
_idle(idle),
_super_period_length(super_period_length),
_super_period_left(super_period_length),
_fill(f)
{
_set_head(idle, f, 0);
_set_current(idle, f);
}

View File

@ -202,12 +202,11 @@ class Kernel::Cpu_scheduler
Share_list _ucl[Prio::max() + 1]; /* unready claims */
Share_list _fills { }; /* ready fills */
Share &_idle;
Share *_head = nullptr;
unsigned _head_quota = 0;
bool _head_claims = false;
bool _head_yields = false;
Share *_current = nullptr;
unsigned _current_quantum { 0 };
bool _yield = false;
unsigned const _super_period_length;
unsigned _super_period_left;
unsigned _super_period_left { _super_period_length };
unsigned const _fill;
bool _need_to_schedule { true };
time_t _last_time { 0 };
@ -224,13 +223,14 @@ class Kernel::Cpu_scheduler
static void _reset(Cpu_share &share);
void _reset_claims(unsigned const p);
void _consumed(unsigned const q);
void _set_head(Share &s, unsigned const q, bool const c);
void _head_claimed(unsigned const r);
void _head_filled(unsigned const r);
bool _claim_for_head();
bool _fill_for_head();
void _reset_claims(unsigned const p);
void _consumed(unsigned const q);
void _set_current(Share &s, unsigned const q);
void _current_claimed(unsigned const r);
void _current_filled(unsigned const r);
bool _schedule_claim();
bool _schedule_fill();
unsigned _trim_consumption(unsigned &q);
/**
@ -264,7 +264,7 @@ class Kernel::Cpu_scheduler
void timeout() { _need_to_schedule = true; }
/**
* Update head according to the current (absolute) time
* Update state according to the current (absolute) time
*/
void update(time_t time);
@ -279,7 +279,7 @@ class Kernel::Cpu_scheduler
void unready(Share &s);
/**
* Current head looses its current claim/fill for this round
* Current share likes another share to be scheduled now
*/
void yield();
@ -298,14 +298,10 @@ class Kernel::Cpu_scheduler
*/
void quota(Share &s, unsigned const q);
/*
* Accessors
*/
Share& current();
Share &head();
unsigned head_quota() const {
return Genode::min(_head_quota, _super_period_left); }
unsigned current_time_left() const {
return Genode::min(_current_quantum, _super_period_left); }
};
#endif /* _CORE__KERNEL__CPU_SCHEDULER_H_ */

View File

@ -184,13 +184,13 @@ class Cpu_scheduler_test::Main
_shares[id].destruct();
}
void _update_head_and_check(unsigned const consumed_quota,
unsigned const expected_round_time,
unsigned const expected_head_id,
unsigned const expected_head_quota,
unsigned const line_nr)
void _update_current_and_check(unsigned const consumed_time,
unsigned const expected_round_time,
unsigned const expected_current_id,
unsigned const expected_current_time_left,
unsigned const line_nr)
{
_current_time += consumed_quota;
_current_time += consumed_time;
_scheduler.update(_current_time);
unsigned const round_time {
_scheduler._super_period_length - _scheduler._super_period_left };
@ -200,28 +200,28 @@ class Cpu_scheduler_test::Main
error("wrong time ", round_time, " in line ", line_nr);
_env.parent().exit(-1);
}
Cpu_share &head { cast(_scheduler.head()) };
unsigned const head_quota { _scheduler.head_quota() };
if (&head != &_share(expected_head_id)) {
Cpu_share &current { cast(_scheduler.current()) };
unsigned const current_time_left { _scheduler.current_time_left() };
if (&current != &_share(expected_current_id)) {
error("wrong share ", _id_of_share(head), " in line ",
error("wrong share ", _id_of_share(current), " in line ",
line_nr);
_env.parent().exit(-1);
}
if (head_quota != expected_head_quota) {
if (current_time_left != expected_current_time_left) {
error("wrong quota ", head_quota, " in line ", line_nr);
error("wrong quota ", current_time_left, " in line ", line_nr);
_env.parent().exit(-1);
}
}
void _set_share_ready_and_check(unsigned const share_id,
bool const expect_head_outdated,
bool const expect_current_outdated,
unsigned const line_nr)
{
_scheduler.ready(_share(share_id));
if (_scheduler.need_to_schedule() != expect_head_outdated) {
if (_scheduler.need_to_schedule() != expect_current_outdated) {
error("wrong check result ",
_scheduler.need_to_schedule(), " in line ", line_nr);
@ -268,19 +268,19 @@ void Cpu_scheduler_test::Cpu_scheduler::print(Output &output) const
print(output, "need to schedule: ", _need_to_schedule ? "true" : "false", ", ");
print(output, "last_time: ", _last_time);
if (_head != nullptr) {
if (_current != nullptr) {
print(output, "\n head: ( ");
print(output, "\n current: ( ");
if (_need_to_schedule) {
print(output, "\033[31m");
} else {
print(output, "\033[32m");
}
print(output, "id: ", cast(*_head).label(), ", ");
print(output, "quota: ", _head_quota, ", ");
print(output, "id: ", cast(*_current).label(), ", ");
print(output, "quota: ", _current_quantum, ", ");
print(output, "\033[0m");
print(output, "claims: ", _head_claims ? "true" : "false", ", ");
print(output, "yields: ", _head_yields ? "true" : "false", " ");
print(output, "claims: ", (_current && _current->_claim) ? "true" : "false", ", ");
print(output, "yields: ", _yield ? "true" : "false", " ");
print(output, ")");
}
bool prios_empty { true };
@ -302,7 +302,7 @@ void Cpu_scheduler_test::Cpu_scheduler::print(Output &output) const
bool first_share { true };
_rcl[prio].for_each([&] (Kernel::Cpu_share const &share) {
if (&share == _head && _head_claims) {
if (&share == _current && _current->_claim) {
if (_need_to_schedule) {
print(output, "\033[31m");
} else {
@ -313,7 +313,7 @@ void Cpu_scheduler_test::Cpu_scheduler::print(Output &output) const
output, first_share ? "" : ", ", cast(share).label() , "-",
share._claim, "/", share._quota);
if (&share == _head && _head_claims) {
if (&share == _current && _current->_claim) {
print(output, "\033[0m");
}
first_share = false;
@ -342,7 +342,7 @@ void Cpu_scheduler_test::Cpu_scheduler::print(Output &output) const
bool first_share { true };
_fills.for_each([&] (Kernel::Cpu_share const &share) {
if (&share == _head && !_head_claims) {
if (&share == _current && !_current->_claim) {
if (_need_to_schedule) {
print(output, "\033[31m");
} else {
@ -355,7 +355,7 @@ void Cpu_scheduler_test::Cpu_scheduler::print(Output &output) const
first_share = false;
if (&share == _head && !_head_claims) {
if (&share == _current && !_current->_claim) {
print(output, "\033[0m");
}
});
@ -378,17 +378,17 @@ Cpu_scheduler_test::Main::Main(Env &env)
** Round #1: Idle **
********************/
_update_head_and_check( 10, 10, 0, 100, __LINE__);
_update_head_and_check( 90, 100, 0, 100, __LINE__);
_update_head_and_check(120, 200, 0, 100, __LINE__);
_update_head_and_check(130, 300, 0, 100, __LINE__);
_update_head_and_check(140, 400, 0, 100, __LINE__);
_update_head_and_check(150, 500, 0, 100, __LINE__);
_update_head_and_check(160, 600, 0, 100, __LINE__);
_update_head_and_check(170, 700, 0, 100, __LINE__);
_update_head_and_check(180, 800, 0, 100, __LINE__);
_update_head_and_check(190, 900, 0, 100, __LINE__);
_update_head_and_check(200, 0, 0, 100, __LINE__);
_update_current_and_check( 10, 10, 0, 100, __LINE__);
_update_current_and_check( 90, 100, 0, 100, __LINE__);
_update_current_and_check(120, 200, 0, 100, __LINE__);
_update_current_and_check(130, 300, 0, 100, __LINE__);
_update_current_and_check(140, 400, 0, 100, __LINE__);
_update_current_and_check(150, 500, 0, 100, __LINE__);
_update_current_and_check(160, 600, 0, 100, __LINE__);
_update_current_and_check(170, 700, 0, 100, __LINE__);
_update_current_and_check(180, 800, 0, 100, __LINE__);
_update_current_and_check(190, 900, 0, 100, __LINE__);
_update_current_and_check(200, 0, 0, 100, __LINE__);
/*************************************
@ -396,30 +396,30 @@ Cpu_scheduler_test::Main::Main(Env &env)
*************************************/
_construct_share(1, __LINE__);
_update_head_and_check(111, 100, 0, 100, __LINE__);
_update_current_and_check(111, 100, 0, 100, __LINE__);
_scheduler.ready(_share(1));
_update_head_and_check(123, 200, 1, 230, __LINE__);
_update_current_and_check(123, 200, 1, 230, __LINE__);
_scheduler.unready(_share(1));
_update_head_and_check(200, 400, 0, 100, __LINE__);
_update_current_and_check(200, 400, 0, 100, __LINE__);
_scheduler.ready(_share(1));
_update_head_and_check( 10, 410, 1, 30, __LINE__);
_update_head_and_check(100, 440, 1, 100, __LINE__);
_update_head_and_check(200, 540, 1, 100, __LINE__);
_update_current_and_check( 10, 410, 1, 30, __LINE__);
_update_current_and_check(100, 440, 1, 100, __LINE__);
_update_current_and_check(200, 540, 1, 100, __LINE__);
_scheduler.unready(_share(1));
_update_head_and_check(200, 640, 0, 100, __LINE__);
_update_head_and_check(200, 740, 0, 100, __LINE__);
_update_current_and_check(200, 640, 0, 100, __LINE__);
_update_current_and_check(200, 740, 0, 100, __LINE__);
_scheduler.ready(_share(1));
_update_head_and_check( 10, 750, 1, 100, __LINE__);
_update_head_and_check( 50, 800, 1, 50, __LINE__);
_update_head_and_check( 20, 820, 1, 30, __LINE__);
_update_head_and_check(100, 850, 1, 100, __LINE__);
_update_head_and_check(200, 950, 1, 50, __LINE__);
_update_head_and_check(200, 0, 1, 230, __LINE__);
_update_current_and_check( 10, 750, 1, 100, __LINE__);
_update_current_and_check( 50, 800, 1, 50, __LINE__);
_update_current_and_check( 20, 820, 1, 30, __LINE__);
_update_current_and_check(100, 850, 1, 100, __LINE__);
_update_current_and_check(200, 950, 1, 50, __LINE__);
_update_current_and_check(200, 0, 1, 230, __LINE__);
/**************************************
@ -428,47 +428,47 @@ Cpu_scheduler_test::Main::Main(Env &env)
_construct_share(2, __LINE__);
_scheduler.ready(_share(2));
_update_head_and_check( 50, 50, 1, 180, __LINE__);
_update_current_and_check( 50, 50, 1, 180, __LINE__);
_scheduler.unready(_share(1));
_update_head_and_check( 70, 120, 2, 170, __LINE__);
_update_current_and_check( 70, 120, 2, 170, __LINE__);
_scheduler.ready(_share(1));
_scheduler.unready(_share(2));
_update_head_and_check(110, 230, 1, 110, __LINE__);
_update_head_and_check( 90, 320, 1, 20, __LINE__);
_update_current_and_check(110, 230, 1, 110, __LINE__);
_update_current_and_check( 90, 320, 1, 20, __LINE__);
_scheduler.ready(_share(2));
_scheduler.unready(_share(1));
_update_head_and_check( 10, 330, 2, 60, __LINE__);
_update_current_and_check( 10, 330, 2, 60, __LINE__);
_construct_share(3, __LINE__);
_update_head_and_check( 40, 370, 2, 20, __LINE__);
_update_current_and_check( 40, 370, 2, 20, __LINE__);
_scheduler.ready(_share(3));
_update_head_and_check( 10, 380, 3, 110, __LINE__);
_update_head_and_check(150, 490, 2, 10, __LINE__);
_update_head_and_check( 10, 500, 2, 100, __LINE__);
_update_head_and_check( 60, 560, 2, 40, __LINE__);
_update_current_and_check( 10, 380, 3, 110, __LINE__);
_update_current_and_check(150, 490, 2, 10, __LINE__);
_update_current_and_check( 10, 500, 2, 100, __LINE__);
_update_current_and_check( 60, 560, 2, 40, __LINE__);
_construct_share(4, __LINE__);
_update_head_and_check( 60, 600, 3, 100, __LINE__);
_update_current_and_check( 60, 600, 3, 100, __LINE__);
_construct_share(6, __LINE__);
_scheduler.ready(_share(6));
_update_head_and_check(120, 700, 2, 100, __LINE__);
_update_current_and_check(120, 700, 2, 100, __LINE__);
_scheduler.ready(_share(4));
_update_head_and_check( 80, 780, 4, 90, __LINE__);
_update_current_and_check( 80, 780, 4, 90, __LINE__);
_scheduler.unready(_share(4));
_scheduler.ready(_share(1));
_update_head_and_check( 50, 830, 1, 10, __LINE__);
_update_head_and_check( 50, 840, 1, 100, __LINE__);
_update_head_and_check( 50, 890, 1, 50, __LINE__);
_update_head_and_check(100, 940, 2, 20, __LINE__);
_update_head_and_check( 60, 960, 6, 40, __LINE__);
_update_head_and_check( 60, 0, 3, 110, __LINE__);
_update_current_and_check( 50, 830, 1, 10, __LINE__);
_update_current_and_check( 50, 840, 1, 100, __LINE__);
_update_current_and_check( 50, 890, 1, 50, __LINE__);
_update_current_and_check(100, 940, 2, 20, __LINE__);
_update_current_and_check( 60, 960, 6, 40, __LINE__);
_update_current_and_check( 60, 0, 3, 110, __LINE__);
/********************************************
@ -476,73 +476,73 @@ Cpu_scheduler_test::Main::Main(Env &env)
********************************************/
_construct_share(5, __LINE__);
_update_head_and_check( 60, 60, 3, 50, __LINE__);
_update_current_and_check( 60, 60, 3, 50, __LINE__);
_scheduler.ready(_share(4));
_scheduler.unready(_share(3));
_update_head_and_check( 40, 100, 1, 230, __LINE__);
_update_current_and_check( 40, 100, 1, 230, __LINE__);
_construct_share(7, __LINE__);
_scheduler.ready(_share(7));
_update_head_and_check(200, 300, 7, 180, __LINE__);
_update_current_and_check(200, 300, 7, 180, __LINE__);
_construct_share(8, __LINE__);
_scheduler.ready(_share(5));
_update_head_and_check(100, 400, 5, 120, __LINE__);
_update_current_and_check(100, 400, 5, 120, __LINE__);
_scheduler.ready(_share(3));
_update_head_and_check(100, 500, 3, 10, __LINE__);
_update_head_and_check( 30, 510, 5, 20, __LINE__);
_update_current_and_check(100, 500, 3, 10, __LINE__);
_update_current_and_check( 30, 510, 5, 20, __LINE__);
_construct_share(9, __LINE__);
_scheduler.ready(_share(9));
_update_head_and_check( 10, 520, 5, 10, __LINE__);
_update_head_and_check( 50, 530, 7, 80, __LINE__);
_update_current_and_check( 10, 520, 5, 10, __LINE__);
_update_current_and_check( 50, 530, 7, 80, __LINE__);
_scheduler.ready(_share(8));
_scheduler.unready(_share(7));
_update_head_and_check( 10, 540, 8, 100, __LINE__);
_update_current_and_check( 10, 540, 8, 100, __LINE__);
_scheduler.unready(_share(8));
_update_head_and_check( 80, 620, 1, 30, __LINE__);
_update_head_and_check(200, 650, 4, 90, __LINE__);
_update_head_and_check(100, 740, 2, 170, __LINE__);
_update_current_and_check( 80, 620, 1, 30, __LINE__);
_update_current_and_check(200, 650, 4, 90, __LINE__);
_update_current_and_check(100, 740, 2, 170, __LINE__);
_scheduler.ready(_share(8));
_scheduler.ready(_share(7));
_update_head_and_check( 10, 750, 7, 70, __LINE__);
_update_current_and_check( 10, 750, 7, 70, __LINE__);
_scheduler.unready(_share(7));
_scheduler.unready(_share(3));
_update_head_and_check( 10, 760, 8, 20, __LINE__);
_update_current_and_check( 10, 760, 8, 20, __LINE__);
_scheduler.unready(_share(8));
_update_head_and_check( 10, 770, 2, 160, __LINE__);
_update_current_and_check( 10, 770, 2, 160, __LINE__);
_scheduler.unready(_share(2));
_update_head_and_check( 40, 810, 4, 100, __LINE__);
_update_current_and_check( 40, 810, 4, 100, __LINE__);
_scheduler.ready(_share(3));
_update_head_and_check( 30, 840, 4, 70, __LINE__);
_update_head_and_check( 80, 910, 1, 90, __LINE__);
_update_current_and_check( 30, 840, 4, 70, __LINE__);
_update_current_and_check( 80, 910, 1, 90, __LINE__);
_scheduler.ready(_share(7));
_scheduler.ready(_share(8));
_update_head_and_check( 10, 920, 8, 10, __LINE__);
_update_head_and_check( 30, 930, 7, 60, __LINE__);
_update_current_and_check( 10, 920, 8, 10, __LINE__);
_update_current_and_check( 30, 930, 7, 60, __LINE__);
_scheduler.ready(_share(2));
_scheduler.unready(_share(7));
_update_head_and_check( 10, 940, 2, 60, __LINE__);
_update_current_and_check( 10, 940, 2, 60, __LINE__);
_scheduler.unready(_share(3));
_scheduler.unready(_share(5));
_update_head_and_check( 40, 980, 2, 20, __LINE__);
_update_current_and_check( 40, 980, 2, 20, __LINE__);
_scheduler.unready(_share(9));
_scheduler.unready(_share(4));
_update_head_and_check( 10, 990, 2, 10, __LINE__);
_update_head_and_check( 40, 0, 1, 230, __LINE__);
_update_current_and_check( 10, 990, 2, 10, __LINE__);
_update_current_and_check( 40, 0, 1, 230, __LINE__);
/************************************
@ -550,116 +550,116 @@ Cpu_scheduler_test::Main::Main(Env &env)
************************************/
_scheduler.unready(_share(6));
_update_head_and_check( 30, 30, 1, 200, __LINE__);
_update_current_and_check( 30, 30, 1, 200, __LINE__);
_scheduler.yield();
_update_head_and_check( 20, 50, 8, 100, __LINE__);
_update_head_and_check(200, 150, 2, 170, __LINE__);
_update_current_and_check( 20, 50, 8, 100, __LINE__);
_update_current_and_check(200, 150, 2, 170, __LINE__);
_scheduler.yield();
_update_head_and_check( 70, 220, 8, 100, __LINE__);
_update_current_and_check( 70, 220, 8, 100, __LINE__);
_scheduler.unready(_share(8));
_scheduler.yield();
_update_head_and_check( 40, 260, 1, 90, __LINE__);
_update_current_and_check( 40, 260, 1, 90, __LINE__);
_scheduler.unready(_share(1));
_update_head_and_check( 50, 310, 2, 100, __LINE__);
_update_head_and_check( 10, 320, 2, 90, __LINE__);
_update_current_and_check( 50, 310, 2, 100, __LINE__);
_update_current_and_check( 10, 320, 2, 90, __LINE__);
_set_share_ready_and_check(1, false, __LINE__);
_update_head_and_check(200, 410, 1, 100, __LINE__);
_update_head_and_check( 10, 420, 1, 90, __LINE__);
_update_current_and_check(200, 410, 1, 100, __LINE__);
_update_current_and_check( 10, 420, 1, 90, __LINE__);
_scheduler.unready(_share(1));
_update_head_and_check( 10, 430, 2, 100, __LINE__);
_update_current_and_check( 10, 430, 2, 100, __LINE__);
_set_share_ready_and_check(5, true, __LINE__);
_update_head_and_check( 10, 440, 5, 120, __LINE__);
_update_current_and_check( 10, 440, 5, 120, __LINE__);
_scheduler.yield();
_update_head_and_check( 90, 530, 2, 90, __LINE__);
_update_current_and_check( 90, 530, 2, 90, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 540, 5, 100, __LINE__);
_update_current_and_check( 10, 540, 5, 100, __LINE__);
_set_share_ready_and_check(7, true, __LINE__);
_update_head_and_check( 10, 550, 7, 180, __LINE__);
_update_current_and_check( 10, 550, 7, 180, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 560, 5, 90, __LINE__);
_update_current_and_check( 10, 560, 5, 90, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 570, 2, 100, __LINE__);
_update_current_and_check( 10, 570, 2, 100, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 580, 7, 100, __LINE__);
_update_current_and_check( 10, 580, 7, 100, __LINE__);
_scheduler.unready(_share(5));
_update_head_and_check( 10, 590, 7, 90, __LINE__);
_update_current_and_check( 10, 590, 7, 90, __LINE__);
_scheduler.unready(_share(7));
_set_share_ready_and_check(5, true, __LINE__);
_update_head_and_check( 10, 600, 2, 100, __LINE__);
_update_current_and_check( 10, 600, 2, 100, __LINE__);
_set_share_ready_and_check(7, false, __LINE__);
_update_head_and_check(200, 700, 5, 100, __LINE__);
_update_current_and_check(200, 700, 5, 100, __LINE__);
_scheduler.unready(_share(5));
_scheduler.unready(_share(7));
_update_head_and_check( 10, 710, 2, 100, __LINE__);
_update_current_and_check( 10, 710, 2, 100, __LINE__);
_scheduler.unready(_share(2));
_update_head_and_check( 10, 720, 0, 100, __LINE__);
_update_head_and_check( 10, 730, 0, 100, __LINE__);
_update_head_and_check(100, 830, 0, 100, __LINE__);
_update_current_and_check( 10, 720, 0, 100, __LINE__);
_update_current_and_check( 10, 730, 0, 100, __LINE__);
_update_current_and_check(100, 830, 0, 100, __LINE__);
_set_share_ready_and_check(9, true, __LINE__);
_update_head_and_check( 10, 840, 9, 100, __LINE__);
_update_current_and_check( 10, 840, 9, 100, __LINE__);
_set_share_ready_and_check(6, false, __LINE__);
_update_head_and_check( 20, 860, 9, 80, __LINE__);
_update_current_and_check( 20, 860, 9, 80, __LINE__);
_set_share_ready_and_check(8, false, __LINE__);
_update_head_and_check( 10, 870, 9, 70, __LINE__);
_update_current_and_check( 10, 870, 9, 70, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 880, 6, 100, __LINE__);
_update_current_and_check( 10, 880, 6, 100, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 890, 8, 100, __LINE__);
_update_current_and_check( 10, 890, 8, 100, __LINE__);
_set_share_ready_and_check(7, false, __LINE__);
_scheduler.yield();
_update_head_and_check( 20, 910, 9, 90, __LINE__);
_update_current_and_check( 20, 910, 9, 90, __LINE__);
_scheduler.unready(_share(8));
_scheduler.unready(_share(9));
_update_head_and_check( 10, 920, 6, 80, __LINE__);
_update_current_and_check( 10, 920, 6, 80, __LINE__);
_scheduler.unready(_share(6));
_scheduler.unready(_share(7));
_update_head_and_check( 10, 930, 0, 70, __LINE__);
_update_current_and_check( 10, 930, 0, 70, __LINE__);
_set_share_ready_and_check(4, true, __LINE__);
_update_head_and_check( 20, 950, 4, 50, __LINE__);
_update_current_and_check( 20, 950, 4, 50, __LINE__);
_set_share_ready_and_check(3, true, __LINE__);
_set_share_ready_and_check(1, true, __LINE__);
_update_head_and_check( 10, 960, 3, 40, __LINE__);
_update_current_and_check( 10, 960, 3, 40, __LINE__);
_set_share_ready_and_check(5, false, __LINE__);
_scheduler.unready(_share(4));
_update_head_and_check( 10, 970, 3, 30, __LINE__);
_update_current_and_check( 10, 970, 3, 30, __LINE__);
_scheduler.unready(_share(3));
_update_head_and_check( 10, 980, 1, 20, __LINE__);
_update_current_and_check( 10, 980, 1, 20, __LINE__);
_set_share_ready_and_check(3, true, __LINE__);
_update_head_and_check( 10, 990, 3, 10, __LINE__);
_update_current_and_check( 10, 990, 3, 10, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 0, 5, 120, __LINE__);
_update_current_and_check( 10, 0, 5, 120, __LINE__);
/*************************************
@ -667,77 +667,77 @@ Cpu_scheduler_test::Main::Main(Env &env)
*************************************/
_destroy_share(3, __LINE__);
_update_head_and_check( 30, 30, 5, 90, __LINE__);
_update_current_and_check( 30, 30, 5, 90, __LINE__);
_scheduler.unready(_share(5));
_update_head_and_check( 30, 60, 1, 230, __LINE__);
_update_current_and_check( 30, 60, 1, 230, __LINE__);
_destroy_share(4, __LINE__);
_destroy_share(7, __LINE__);
_update_head_and_check( 20, 80, 1, 210, __LINE__);
_update_current_and_check( 20, 80, 1, 210, __LINE__);
_scheduler.unready(_share(1));
_set_share_ready_and_check(9, true, __LINE__);
_update_head_and_check( 40, 120, 9, 100, __LINE__);
_update_current_and_check( 40, 120, 9, 100, __LINE__);
_scheduler.ready(_share(5));
_set_share_ready_and_check(8, true, __LINE__);
_update_head_and_check( 70, 190, 5, 60, __LINE__);
_update_current_and_check( 70, 190, 5, 60, __LINE__);
_destroy_share(8, __LINE__);
_scheduler.unready(_share(5));
_update_head_and_check( 10, 200, 9, 30, __LINE__);
_update_current_and_check( 10, 200, 9, 30, __LINE__);
_set_share_ready_and_check(6, false, __LINE__);
_construct_share(4, __LINE__);
_update_head_and_check( 10, 210, 9, 20, __LINE__);
_update_current_and_check( 10, 210, 9, 20, __LINE__);
_destroy_share(5, __LINE__);
_set_share_ready_and_check(4, true, __LINE__);
_update_head_and_check( 10, 220, 4, 90, __LINE__);
_update_head_and_check(100, 310, 4, 100, __LINE__);
_update_head_and_check( 10, 320, 4, 90, __LINE__);
_update_current_and_check( 10, 220, 4, 90, __LINE__);
_update_current_and_check(100, 310, 4, 100, __LINE__);
_update_current_and_check( 10, 320, 4, 90, __LINE__);
_destroy_share(4, __LINE__);
_update_head_and_check(200, 410, 9, 10, __LINE__);
_update_current_and_check(200, 410, 9, 10, __LINE__);
_construct_share(5, __LINE__);
_scheduler.ready(_share(5));
_update_head_and_check( 10, 420, 5, 120, __LINE__);
_update_current_and_check( 10, 420, 5, 120, __LINE__);
_construct_share(4, __LINE__);
_scheduler.yield();
_update_head_and_check( 10, 430, 6, 100, __LINE__);
_update_current_and_check( 10, 430, 6, 100, __LINE__);
_set_share_ready_and_check(4, true, __LINE__);
_scheduler.yield();
_update_head_and_check( 50, 480, 4, 90, __LINE__);
_update_current_and_check( 50, 480, 4, 90, __LINE__);
_destroy_share(6, __LINE__);
_scheduler.yield();
_update_head_and_check( 20, 500, 5, 100, __LINE__);
_update_current_and_check( 20, 500, 5, 100, __LINE__);
_destroy_share(9, __LINE__);
_update_head_and_check(200, 600, 4, 100, __LINE__);
_update_current_and_check(200, 600, 4, 100, __LINE__);
_construct_share(7, __LINE__);
_construct_share(8, __LINE__);
_update_head_and_check(200, 700, 5, 100, __LINE__);
_update_current_and_check(200, 700, 5, 100, __LINE__);
_set_share_ready_and_check(1, true, __LINE__);
_set_share_ready_and_check(7, true, __LINE__);
_update_head_and_check( 10, 710, 7, 180, __LINE__);
_update_current_and_check( 10, 710, 7, 180, __LINE__);
_set_share_ready_and_check(8, true, __LINE__);
_update_head_and_check( 40, 750, 8, 100, __LINE__);
_update_current_and_check( 40, 750, 8, 100, __LINE__);
_destroy_share(7, __LINE__);
_update_head_and_check(200, 850, 1, 150, __LINE__);
_update_head_and_check( 50, 900, 1, 100, __LINE__);
_update_current_and_check(200, 850, 1, 150, __LINE__);
_update_current_and_check( 50, 900, 1, 100, __LINE__);
_scheduler.yield();
_update_head_and_check( 60, 960, 8, 40, __LINE__);
_update_head_and_check(100, 0, 5, 120, __LINE__);
_update_current_and_check( 60, 960, 8, 40, __LINE__);
_update_current_and_check(100, 0, 5, 120, __LINE__);
/**********************************************
@ -746,117 +746,117 @@ Cpu_scheduler_test::Main::Main(Env &env)
_scheduler.quota(_share(5), 100);
_construct_share(6, __LINE__);
_update_head_and_check( 40, 40, 5, 80, __LINE__);
_update_current_and_check( 40, 40, 5, 80, __LINE__);
_scheduler.quota(_share(5), 70);
_scheduler.ready(_share(6));
_update_head_and_check( 10, 50, 5, 70, __LINE__);
_update_current_and_check( 10, 50, 5, 70, __LINE__);
_scheduler.quota(_share(5), 40);
_construct_share(9, __LINE__);
_update_head_and_check( 10, 60, 5, 40, __LINE__);
_update_current_and_check( 10, 60, 5, 40, __LINE__);
_scheduler.quota(_share(5), 0);
_scheduler.ready(_share(9));
_update_head_and_check( 20, 80, 8, 100, __LINE__);
_update_current_and_check( 20, 80, 8, 100, __LINE__);
_scheduler.quota(_share(8), 120);
_update_head_and_check( 30, 110, 8, 70, __LINE__);
_update_current_and_check( 30, 110, 8, 70, __LINE__);
_scheduler.quota(_share(9), 40);
_update_head_and_check( 10, 120, 8, 60, __LINE__);
_update_current_and_check( 10, 120, 8, 60, __LINE__);
_scheduler.quota(_share(8), 130);
_update_head_and_check( 10, 130, 8, 50, __LINE__);
_update_current_and_check( 10, 130, 8, 50, __LINE__);
_scheduler.quota(_share(8), 50);
_update_head_and_check( 20, 150, 8, 30, __LINE__);
_update_current_and_check( 20, 150, 8, 30, __LINE__);
_scheduler.quota(_share(6), 60);
_update_head_and_check( 10, 160, 8, 20, __LINE__);
_update_current_and_check( 10, 160, 8, 20, __LINE__);
_scheduler.unready(_share(8));
_update_head_and_check( 10, 170, 1, 230, __LINE__);
_update_current_and_check( 10, 170, 1, 230, __LINE__);
_scheduler.unready(_share(1));
_update_head_and_check(100, 270, 4, 90, __LINE__);
_update_head_and_check(100, 360, 4, 100, __LINE__);
_update_current_and_check(100, 270, 4, 90, __LINE__);
_update_current_and_check(100, 360, 4, 100, __LINE__);
_scheduler.quota(_share(1), 110);
_update_head_and_check( 10, 370, 4, 90, __LINE__);
_update_current_and_check( 10, 370, 4, 90, __LINE__);
_scheduler.quota(_share(1), 120);
_update_head_and_check( 20, 390, 4, 70, __LINE__);
_update_current_and_check( 20, 390, 4, 70, __LINE__);
_scheduler.quota(_share(4), 210);
_update_head_and_check( 10, 400, 4, 60, __LINE__);
_update_current_and_check( 10, 400, 4, 60, __LINE__);
_scheduler.ready(_share(1));
_update_head_and_check( 10, 410, 1, 110, __LINE__);
_update_current_and_check( 10, 410, 1, 110, __LINE__);
_scheduler.quota(_share(1), 100);
_update_head_and_check( 30, 440, 1, 80, __LINE__);
_update_current_and_check( 30, 440, 1, 80, __LINE__);
_set_share_ready_and_check(8, true, __LINE__);
_update_head_and_check( 10, 450, 8, 10, __LINE__);
_update_current_and_check( 10, 450, 8, 10, __LINE__);
_set_share_ready_and_check(2, false, __LINE__);
_update_head_and_check( 10, 460, 1, 70, __LINE__);
_update_current_and_check( 10, 460, 1, 70, __LINE__);
_scheduler.quota(_share(1), 20);
_update_head_and_check( 30, 490, 1, 20, __LINE__);
_update_current_and_check( 30, 490, 1, 20, __LINE__);
_scheduler.quota(_share(1), 50);
_update_head_and_check( 10, 500, 1, 10, __LINE__);
_update_current_and_check( 10, 500, 1, 10, __LINE__);
_scheduler.quota(_share(1), 0);
_update_head_and_check( 30, 510, 2, 170, __LINE__);
_update_current_and_check( 30, 510, 2, 170, __LINE__);
_scheduler.quota(_share(2), 180);
_update_head_and_check( 50, 560, 2, 120, __LINE__);
_update_current_and_check( 50, 560, 2, 120, __LINE__);
_scheduler.unready(_share(2));
_scheduler.quota(_share(4), 80);
_update_head_and_check( 70, 630, 8, 100, __LINE__);
_update_head_and_check( 50, 680, 8, 50, __LINE__);
_update_current_and_check( 70, 630, 8, 100, __LINE__);
_update_current_and_check( 50, 680, 8, 50, __LINE__);
_scheduler.unready(_share(8));
_update_head_and_check( 10, 690, 4, 50, __LINE__);
_update_current_and_check( 10, 690, 4, 50, __LINE__);
_construct_share(3, __LINE__);
_update_head_and_check( 30, 720, 4, 20, __LINE__);
_update_current_and_check( 30, 720, 4, 20, __LINE__);
_scheduler.quota(_share(3), 210);
_scheduler.yield();
_scheduler.unready(_share(4));
_update_head_and_check( 20, 740, 5, 90, __LINE__);
_update_current_and_check( 20, 740, 5, 90, __LINE__);
_scheduler.unready(_share(9));
_set_share_ready_and_check(4, false, __LINE__);
_update_head_and_check( 50, 790, 5, 40, __LINE__);
_update_current_and_check( 50, 790, 5, 40, __LINE__);
_set_share_ready_and_check(2, true, __LINE__);
_update_head_and_check( 40, 830, 2, 50, __LINE__);
_update_head_and_check( 60, 880, 2, 100, __LINE__);
_update_head_and_check( 10, 890, 2, 90, __LINE__);
_update_current_and_check( 40, 830, 2, 50, __LINE__);
_update_current_and_check( 60, 880, 2, 100, __LINE__);
_update_current_and_check( 10, 890, 2, 90, __LINE__);
_scheduler.yield();
_set_share_ready_and_check(9, true, __LINE__);
_update_head_and_check( 60, 950, 6, 50, __LINE__);
_update_current_and_check( 60, 950, 6, 50, __LINE__);
_scheduler.unready(_share(6));
_update_head_and_check( 20, 970, 1, 30, __LINE__);
_update_current_and_check( 20, 970, 1, 30, __LINE__);
_scheduler.yield();
_scheduler.ready(_share(8));
_update_head_and_check( 10, 980, 4, 20, __LINE__);
_update_current_and_check( 10, 980, 4, 20, __LINE__);
_scheduler.unready(_share(8));
_scheduler.yield();
_update_head_and_check( 10, 990, 5, 10, __LINE__);
_update_current_and_check( 10, 990, 5, 10, __LINE__);
_scheduler.yield();
_update_head_and_check( 20, 0, 9, 40, __LINE__);
_update_current_and_check( 20, 0, 9, 40, __LINE__);
/***********************************************
@ -864,45 +864,45 @@ Cpu_scheduler_test::Main::Main(Env &env)
***********************************************/
_scheduler.ready(_share(3));
_update_head_and_check( 30, 30, 3, 210, __LINE__);
_update_current_and_check( 30, 30, 3, 210, __LINE__);
_scheduler.unready(_share(3));
_update_head_and_check(110, 140, 9, 10, __LINE__);
_update_head_and_check( 40, 150, 4, 80, __LINE__);
_update_head_and_check(100, 230, 2, 180, __LINE__);
_update_current_and_check(110, 140, 9, 10, __LINE__);
_update_current_and_check( 40, 150, 4, 80, __LINE__);
_update_current_and_check(100, 230, 2, 180, __LINE__);
_scheduler.quota(_share(2), 90);
_update_head_and_check( 40, 270, 2, 90, __LINE__);
_update_current_and_check( 40, 270, 2, 90, __LINE__);
_scheduler.yield();
_scheduler.quota(_share(8), 130);
_update_head_and_check( 40, 310, 4, 100, __LINE__);
_update_head_and_check(100, 410, 9, 100, __LINE__);
_update_current_and_check( 40, 310, 4, 100, __LINE__);
_update_current_and_check(100, 410, 9, 100, __LINE__);
_scheduler.quota(_share(3), 80);
_set_share_ready_and_check(3, true, __LINE__);
_update_head_and_check( 60, 470, 3, 80, __LINE__);
_update_current_and_check( 60, 470, 3, 80, __LINE__);
_set_share_ready_and_check(8, false, __LINE__);
_scheduler.quota(_share(8), 50);
_update_head_and_check(100, 550, 8, 50, __LINE__);
_update_head_and_check( 20, 570, 8, 30, __LINE__);
_update_current_and_check(100, 550, 8, 50, __LINE__);
_update_current_and_check( 20, 570, 8, 30, __LINE__);
_set_share_ready_and_check(6, true, __LINE__);
_scheduler.quota(_share(6), 50);
_update_head_and_check( 10, 580, 6, 50, __LINE__);
_update_head_and_check( 70, 630, 8, 20, __LINE__);
_update_head_and_check( 40, 650, 8, 100, __LINE__);
_update_head_and_check( 40, 690, 8, 60, __LINE__);
_update_current_and_check( 10, 580, 6, 50, __LINE__);
_update_current_and_check( 70, 630, 8, 20, __LINE__);
_update_current_and_check( 40, 650, 8, 100, __LINE__);
_update_current_and_check( 40, 690, 8, 60, __LINE__);
_destroy_share(6, __LINE__);
_update_head_and_check(200, 750, 3, 100, __LINE__);
_update_current_and_check(200, 750, 3, 100, __LINE__);
_destroy_share(3, __LINE__);
_update_head_and_check( 90, 840, 9, 40, __LINE__);
_update_head_and_check( 60, 880, 2, 100, __LINE__);
_update_head_and_check(120, 980, 1, 20, __LINE__);
_update_head_and_check( 80, 0, 9, 40, __LINE__);
_update_current_and_check( 90, 840, 9, 40, __LINE__);
_update_current_and_check( 60, 880, 2, 100, __LINE__);
_update_current_and_check(120, 980, 1, 20, __LINE__);
_update_current_and_check( 80, 0, 9, 40, __LINE__);
_env.parent().exit(0);