base-hw: update cpu_scheduler unit test

* Modernize routines, eliminate pointers, use constructibles, etc.
* Use absolute time instead of relative time consumption when
  updating the scheduler

Ref genodelabs/genode#4151
This commit is contained in:
Stefan Kalkowski 2022-09-07 16:48:44 +02:00 committed by Christian Helmuth
parent debd41081e
commit b85b3abe20

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (C) 2014-2017 Genode Labs GmbH * Copyright (C) 2014-2022 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -18,124 +18,109 @@
/* core includes */ /* core includes */
#include <kernel/cpu_scheduler.h> #include <kernel/cpu_scheduler.h>
/* using namespace Genode;
* Utilities using namespace Kernel;
*/
using Genode::size_t; struct Main
using Genode::addr_t;
using Genode::construct_at;
using Kernel::Cpu_share;
using Kernel::Cpu_scheduler;
struct Data
{ {
Cpu_share idle; enum { MAX_SHARES = 10 };
Constructible<Cpu_share> shares[MAX_SHARES] {};
Cpu_scheduler scheduler; Cpu_scheduler scheduler;
char shares[9][sizeof(Cpu_share)]; time_t current_time { 0 };
Data() : idle(0, 0), scheduler(idle, 1000, 100) { } Cpu_share & _idle()
}; {
if (!shares[0].constructed()) shares[0].construct(0, 0);
return *shares[0];
}
Main() : scheduler(_idle(), 1000, 100) { }
Data * data() void done()
{ {
static Data d;
return &d;
}
void done()
{
Genode::log("done"); Genode::log("done");
while (1) ; while (1) ;
} }
unsigned share_id(Cpu_share & share)
{
for (unsigned i = 0; i < MAX_SHARES; i++)
if (shares[i].constructed() && (&*shares[i] == &share))
return i;
return ~0U;
}
unsigned share_id(void * const pointer) Cpu_share & share(unsigned const id)
{ {
addr_t const address = (addr_t)pointer; return *shares[id];
addr_t const base = (addr_t)data()->shares; }
if (address < base || address >= base + sizeof(data()->shares)) {
return 0; }
return (unsigned)((address - base) / sizeof(Cpu_share) + 1);
}
void create(unsigned const id)
Cpu_share * share(unsigned const id) {
{
if (!id) { return &data()->idle; }
return reinterpret_cast<Cpu_share *>(&data()->shares[id - 1]);
}
void create(unsigned const id)
{
Cpu_share * const s = share(id);
void * const p = (void *)s;
switch (id) { switch (id) {
case 1: construct_at<Cpu_share>(p, 2, 230); break; case 1: shares[id].construct(2, 230); break;
case 2: construct_at<Cpu_share>(p, 0, 170); break; case 2: shares[id].construct(0, 170); break;
case 3: construct_at<Cpu_share>(p, 3, 110); break; case 3: shares[id].construct(3, 110); break;
case 4: construct_at<Cpu_share>(p, 1, 90); break; case 4: shares[id].construct(1, 90); break;
case 5: construct_at<Cpu_share>(p, 3, 120); break; case 5: shares[id].construct(3, 120); break;
case 6: construct_at<Cpu_share>(p, 3, 0); break; case 6: shares[id].construct(3, 0); break;
case 7: construct_at<Cpu_share>(p, 2, 180); break; case 7: shares[id].construct(2, 180); break;
case 8: construct_at<Cpu_share>(p, 2, 100); break; case 8: shares[id].construct(2, 100); break;
case 9: construct_at<Cpu_share>(p, 2, 0); break; case 9: shares[id].construct(2, 0); break;
default: return; default: return;
} }
data()->scheduler.insert(*s); scheduler.insert(*shares[id]);
} }
void destroy(unsigned const id)
{
if (!id || id >= MAX_SHARES)
return;
void destroy(unsigned const id) scheduler.remove(share(id));
{ shares[id].destruct();
Cpu_share * const s = share(id); }
data()->scheduler.remove(*s);
s->~Cpu_share();
}
unsigned time()
{
return scheduler.quota() - scheduler.residual();
}
unsigned time() void update_check(unsigned const l, unsigned const c, unsigned const t,
{
return data()->scheduler.quota() -
data()->scheduler.residual();
}
void update_check(unsigned const l, unsigned const c, unsigned const t,
unsigned const s, unsigned const q) unsigned const s, unsigned const q)
{ {
data()->scheduler.update(c); current_time += c;
scheduler.update(current_time);
unsigned const st = time(); unsigned const st = time();
if (t != st) { if (t != st) {
Genode::log("wrong time ", st, " in line ", l); log("wrong time ", st, " in line ", l);
done(); done();
} }
Cpu_share &hs = data()->scheduler.head(); Cpu_share & hs = scheduler.head();
unsigned const hq = data()->scheduler.head_quota(); unsigned const hq = scheduler.head_quota();
if (&hs != share(s)) { if (&hs != &share(s)) {
unsigned const hi = share_id(&hs); log("wrong share ", share_id(hs), " in line ", l);
Genode::log("wrong share ", hi, " in line ", l);
done(); done();
} }
if (hq != q) { if (hq != q) {
Genode::log("wrong quota ", hq, " in line ", l); log("wrong quota ", hq, " in line ", l);
done(); done();
} }
} }
void ready_check(unsigned const l, unsigned const s, bool const x)
void ready_check(unsigned const l, unsigned const s, bool const x) {
{ scheduler.ready(share(s));
data()->scheduler.ready_check(*share(s)); if (scheduler.need_to_schedule() != x) {
if (data()->scheduler.need_to_schedule() != x) { log("wrong check result ", scheduler.need_to_schedule(), " in line ", l);
Genode::log("wrong check result ", data()->scheduler.need_to_schedule(), " in line ", l);
done(); done();
} }
} }
void test();
};
/* /*
@ -144,10 +129,10 @@ void ready_check(unsigned const l, unsigned const s, bool const x)
#define C(s) create(s); #define C(s) create(s);
#define D(s) destroy(s); #define D(s) destroy(s);
#define A(s) data()->scheduler.ready(*share(s)); #define A(s) scheduler.ready(share(s));
#define I(s) data()->scheduler.unready(*share(s)); #define I(s) scheduler.unready(share(s));
#define Y data()->scheduler.yield(); #define Y scheduler.yield();
#define Q(s, q) data()->scheduler.quota(*share(s), q); #define Q(s, q) scheduler.quota(share(s), q);
#define U(c, t, s, q) update_check(__LINE__, c, t, s, q); #define U(c, t, s, q) update_check(__LINE__, c, t, s, q);
#define O(s) ready_check(__LINE__, s, true); #define O(s) ready_check(__LINE__, s, true);
#define N(s) ready_check(__LINE__, s, false); #define N(s) ready_check(__LINE__, s, false);
@ -157,6 +142,13 @@ void ready_check(unsigned const l, unsigned const s, bool const x)
* Main routine * Main routine
*/ */
void Component::construct(Genode::Env &) void Component::construct(Genode::Env &)
{
static Main main;
main.test();
}
void Main::test()
{ {
/* /*
* Step-by-step testing * Step-by-step testing