mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-31 14:40:54 +00:00
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:
parent
debd41081e
commit
b85b3abe20
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user