base: transition to new API for tests (ref #1987)
This commit is contained in:
parent
d07cd0e88e
commit
aa004cf211
|
@ -21,7 +21,7 @@ build_boot_image "core ld.lib.so init test-new_delete"
|
||||||
|
|
||||||
append qemu_args "-nographic -m 64"
|
append qemu_args "-nographic -m 64"
|
||||||
|
|
||||||
run_genode_until {child "test-new_delete" exited with exit value 0.*\n} 15
|
run_genode_until "Test done.*\n" 15
|
||||||
|
|
||||||
grep_output {^\[init -> test-new_delete\]}
|
grep_output {^\[init -> test-new_delete\]}
|
||||||
|
|
||||||
|
|
|
@ -28,4 +28,4 @@ build_boot_image "core ld.lib.so init test-rm_nested"
|
||||||
|
|
||||||
append qemu_args "-nographic -m 64"
|
append qemu_args "-nographic -m 64"
|
||||||
|
|
||||||
run_genode_until {child "test-rm_nested" exited with exit value 0.*} 300
|
run_genode_until ".*--- finished nested region map test ---.*\n" 300
|
||||||
|
|
|
@ -32,6 +32,6 @@ build_boot_image "core ld.lib.so init timer test-slab"
|
||||||
|
|
||||||
append qemu_args "-nographic -m 128"
|
append qemu_args "-nographic -m 128"
|
||||||
|
|
||||||
run_genode_until {child "test-slab" exited with exit value 0.*\n} 100
|
run_genode_until "Test done.*\n" 100
|
||||||
|
|
||||||
puts "Test succeeded"
|
puts "Test succeeded"
|
||||||
|
|
|
@ -12,39 +12,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/thread.h>
|
#include <base/component.h>
|
||||||
#include <base/sleep.h>
|
#include <base/heap.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
#include <base/thread.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
class Sync_signal_transmitter : public Signal_transmitter
|
class Fpu_user : public Thread
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Lock _lock;
|
float _x;
|
||||||
|
Signal_transmitter _st;
|
||||||
public:
|
Semaphore & _sem;
|
||||||
|
|
||||||
Sync_signal_transmitter(Signal_context_capability context = Signal_context_capability())
|
|
||||||
:
|
|
||||||
Signal_transmitter(context),
|
|
||||||
_lock(Lock::UNLOCKED)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void submit(unsigned cnt)
|
|
||||||
{
|
|
||||||
Lock::Guard guard(_lock);
|
|
||||||
Signal_transmitter::submit(cnt);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Fpu_user : public Thread_deprecated<0x2000>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
float _x;
|
|
||||||
Sync_signal_transmitter * _st;
|
|
||||||
|
|
||||||
void _calc(float volatile & x, float volatile & y)
|
void _calc(float volatile & x, float volatile & y)
|
||||||
{
|
{
|
||||||
|
@ -56,59 +37,50 @@ class Fpu_user : public Thread_deprecated<0x2000>
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Fpu_user() : Thread_deprecated("fpu_user"), _x(0), _st(0) { }
|
Fpu_user(Env & env, float x, Signal_context_capability c, Semaphore &s)
|
||||||
|
: Thread(env, "fpu_user", sizeof(size_t)*2048), _x(x), _st(c), _sem(s) {
|
||||||
void start(float const x, Sync_signal_transmitter * const st)
|
start(); }
|
||||||
{
|
|
||||||
_x = x;
|
|
||||||
_st = st;
|
|
||||||
Thread::start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void entry()
|
void entry()
|
||||||
{
|
{
|
||||||
Genode::log("FPU user started");
|
log("FPU user started");
|
||||||
bool submitted = false;
|
|
||||||
while (1) {
|
enum { TRIALS = 1000 };
|
||||||
enum { TRIALS = 1000 };
|
for (unsigned i = 0; i < TRIALS; i++) {
|
||||||
for (unsigned i = 0; i < TRIALS; i++) {
|
float volatile a = _x + (float)i * ((float)1 / TRIALS);
|
||||||
float volatile a = _x + (float)i * ((float)1 / TRIALS);
|
float volatile b = _x + (float)i * ((float)1 / TRIALS);
|
||||||
float volatile b = _x + (float)i * ((float)1 / TRIALS);
|
float volatile c = _x;
|
||||||
float volatile c = _x;
|
_calc(a, c);
|
||||||
_calc(a, c);
|
_calc(b, c);
|
||||||
_calc(b, c);
|
if (a != b) {
|
||||||
if (a != b) {
|
error("calculation error");
|
||||||
Genode::error("calculation error");
|
break;
|
||||||
_st->submit(1);
|
|
||||||
sleep_forever();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!submitted) {
|
|
||||||
_st->submit(1);
|
|
||||||
submitted = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sem.up();
|
||||||
|
_st.submit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
/* create ack signal */
|
|
||||||
Signal_context sc;
|
|
||||||
Signal_receiver sr;
|
|
||||||
Signal_context_capability const scc = sr.manage(&sc);
|
|
||||||
Sync_signal_transmitter st(scc);
|
|
||||||
|
|
||||||
/* start pseudo-parallel FPU users */
|
struct Main
|
||||||
|
{
|
||||||
enum { FPU_USERS = 10 };
|
enum { FPU_USERS = 10 };
|
||||||
Fpu_user fpu_users[FPU_USERS];
|
|
||||||
for (unsigned i = 0; i < FPU_USERS; i++) {
|
Semaphore sem;
|
||||||
float const x = (i + 1) * 1.234;
|
Env & env;
|
||||||
fpu_users[i].start(x, &st);
|
Heap heap { env.ram(), env.rm() };
|
||||||
}
|
Signal_handler<Main> handler { env.ep(), *this, &Main::handle };
|
||||||
/* wait for an ack of every FPU user */
|
|
||||||
for (unsigned i = 0; i < FPU_USERS;) { i += sr.wait_for_signal().num(); }
|
Main(Env & env) : env(env) {
|
||||||
log("test done");
|
for (unsigned i = 0; i < FPU_USERS; i++)
|
||||||
sleep_forever();
|
new (heap) Fpu_user(env, (i + 1) * 1.234, handler, sem); }
|
||||||
return 0;
|
|
||||||
}
|
void handle() {
|
||||||
|
if (sem.cnt() >= FPU_USERS) log("test done"); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Component::construct(Genode::Env & env) {
|
||||||
|
static Main main(env); }
|
||||||
|
|
|
@ -13,13 +13,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <base/component.h>
|
||||||
|
#include <base/heap.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/thread.h>
|
|
||||||
#include <base/env.h>
|
|
||||||
#include <base/sleep.h>
|
|
||||||
|
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#include <base/rpc_server.h>
|
#include <base/rpc_server.h>
|
||||||
|
#include <base/rpc_client.h>
|
||||||
|
|
||||||
namespace Test {
|
namespace Test {
|
||||||
|
|
||||||
|
@ -81,34 +79,35 @@ namespace Test {
|
||||||
/**
|
/**
|
||||||
* Set up a server running on every CPU one Rpc_entrypoint
|
* Set up a server running on every CPU one Rpc_entrypoint
|
||||||
*/
|
*/
|
||||||
int main(int argc, char **argv)
|
void Component::construct(Genode::Env & env)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
Heap heap(env.ram(), env.rm());
|
||||||
|
|
||||||
log("--- test-mp_server started ---");
|
log("--- test-mp_server started ---");
|
||||||
|
|
||||||
Affinity::Space cpus = env()->cpu_session()->affinity_space();
|
Affinity::Space cpus = env.cpu().affinity_space();
|
||||||
log("Detected ", cpus.width(), "x", cpus.height(), " CPU",
|
log("Detected ", cpus.width(), "x", cpus.height(), " CPU",
|
||||||
cpus.total() > 1 ? "s." : ".");
|
cpus.total() > 1 ? "s." : ".");
|
||||||
|
|
||||||
enum { STACK_SIZE = 2*1024*sizeof(long) };
|
enum { STACK_SIZE = 2*1024*sizeof(long) };
|
||||||
|
|
||||||
static Cap_connection cap;
|
Rpc_entrypoint ** eps = new (heap) Rpc_entrypoint*[cpus.total()];
|
||||||
Rpc_entrypoint ** eps = new (env()->heap()) Rpc_entrypoint*[cpus.total()];
|
|
||||||
for (unsigned i = 0; i < cpus.total(); i++)
|
for (unsigned i = 0; i < cpus.total(); i++)
|
||||||
eps[i] = new (env()->heap()) Rpc_entrypoint(&cap, STACK_SIZE, "rpc en",
|
eps[i] = new (heap) Rpc_entrypoint(&env.pd(), STACK_SIZE, "rpc en",
|
||||||
true, cpus.location_of_index(i));
|
true, cpus.location_of_index(i));
|
||||||
|
|
||||||
/* XXX using the same object and putting it to different queues fails XXX */
|
/* XXX using the same object and putting it to different queues fails XXX */
|
||||||
Test::Component * components = new (env()->heap()) Test::Component[cpus.total()];
|
Test::Component * components = new (heap) Test::Component[cpus.total()];
|
||||||
|
|
||||||
Test::Capability * caps = new (env()->heap()) Test::Capability[cpus.total()];
|
Test::Capability * caps = new (heap) Test::Capability[cpus.total()];
|
||||||
for (unsigned i = 0; i < cpus.total(); i++)
|
for (unsigned i = 0; i < cpus.total(); i++)
|
||||||
caps[i] = eps[i]->manage(&components[i]);
|
caps[i] = eps[i]->manage(&components[i]);
|
||||||
|
|
||||||
Test::Client ** clients = new (env()->heap()) Test::Client*[cpus.total()];
|
Test::Client ** clients = new (heap) Test::Client*[cpus.total()];
|
||||||
for (unsigned i = 0; i < cpus.total(); i++)
|
for (unsigned i = 0; i < cpus.total(); i++)
|
||||||
clients[i] = new (env()->heap()) Test::Client(caps[i]);
|
clients[i] = new (heap) Test::Client(caps[i]);
|
||||||
|
|
||||||
/* Test: Invoke RPC entrypoint on different CPUs */
|
/* Test: Invoke RPC entrypoint on different CPUs */
|
||||||
for (unsigned i = 0; i < cpus.total(); i++) {
|
for (unsigned i = 0; i < cpus.total(); i++) {
|
||||||
|
@ -132,6 +131,4 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
log("done");
|
log("done");
|
||||||
|
|
||||||
sleep_forever();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <base/component.h>
|
||||||
|
#include <base/heap.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/env.h>
|
|
||||||
|
|
||||||
using Genode::log;
|
using Genode::log;
|
||||||
using Genode::destroy;
|
using Genode::destroy;
|
||||||
|
@ -40,29 +41,24 @@ struct E : C, D
|
||||||
|
|
||||||
struct Allocator : Genode::Allocator
|
struct Allocator : Genode::Allocator
|
||||||
{
|
{
|
||||||
Genode::Allocator &heap = *Genode::env()->heap();
|
Genode::Heap heap;
|
||||||
|
Genode::Allocator & a { heap };
|
||||||
|
|
||||||
Allocator() { }
|
Allocator(Genode::Env & env) : heap(env.ram(), env.rm()) { }
|
||||||
virtual ~Allocator() { }
|
virtual ~Allocator() { }
|
||||||
|
|
||||||
Genode::size_t consumed() const override
|
Genode::size_t consumed() const override {
|
||||||
{
|
return a.consumed(); }
|
||||||
return heap.consumed();
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::size_t overhead(Genode::size_t size) const override
|
Genode::size_t overhead(Genode::size_t size) const override {
|
||||||
{
|
return a.overhead(size); }
|
||||||
return heap.overhead(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool need_size_for_free() const override
|
bool need_size_for_free() const override {
|
||||||
{
|
return a.need_size_for_free(); }
|
||||||
return heap.need_size_for_free();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool alloc(Genode::size_t size, void **p) override
|
bool alloc(Genode::size_t size, void **p) override
|
||||||
{
|
{
|
||||||
*p = heap.alloc(size);
|
*p = a.alloc(size);
|
||||||
|
|
||||||
log("Allocator::alloc()");
|
log("Allocator::alloc()");
|
||||||
|
|
||||||
|
@ -72,14 +68,14 @@ struct Allocator : Genode::Allocator
|
||||||
void free(void *p, Genode::size_t size) override
|
void free(void *p, Genode::size_t size) override
|
||||||
{
|
{
|
||||||
log("Allocator::free()");
|
log("Allocator::free()");
|
||||||
heap.free(p, size);
|
a.free(p, size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main()
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
Allocator a;
|
Allocator a(env);
|
||||||
|
|
||||||
/***********************
|
/***********************
|
||||||
** Allocator pointer **
|
** Allocator pointer **
|
||||||
|
@ -87,14 +83,14 @@ int main()
|
||||||
|
|
||||||
/* test successful allocation / successful construction */
|
/* test successful allocation / successful construction */
|
||||||
{
|
{
|
||||||
E *e = new (&a) E(false);
|
E *e = new (a) E(false);
|
||||||
destroy(&a, e);
|
destroy(a, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test successful allocation / exception in construction */
|
/* test successful allocation / exception in construction */
|
||||||
try {
|
try {
|
||||||
E *e = new (&a) E(true);
|
E *e = new (a) E(true);
|
||||||
destroy(&a, e);
|
destroy(a, e);
|
||||||
} catch (...) { log("exception caught"); }
|
} catch (...) { log("exception caught"); }
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
|
@ -104,12 +100,14 @@ int main()
|
||||||
/* test successful allocation / successful construction */
|
/* test successful allocation / successful construction */
|
||||||
{
|
{
|
||||||
E *e = new (a) E(false);
|
E *e = new (a) E(false);
|
||||||
destroy(&a, e);
|
destroy(a, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test successful allocation / exception in construction */
|
/* test successful allocation / exception in construction */
|
||||||
try {
|
try {
|
||||||
E *e = new (a) E(true);
|
E *e = new (a) E(true);
|
||||||
destroy(&a, e);
|
destroy(a, e);
|
||||||
} catch (...) { log("exception caught"); }
|
} catch (...) { log("exception caught"); }
|
||||||
|
|
||||||
|
log("Test done");
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,7 @@ void Component::construct(Env &env)
|
||||||
* Distinguish parent from child by requesting an service that is only
|
* Distinguish parent from child by requesting an service that is only
|
||||||
* available to the parent.
|
* available to the parent.
|
||||||
*/
|
*/
|
||||||
Rm_connection rm;
|
Rm_connection rm(env);
|
||||||
static Main_parent parent(env);
|
static Main_parent parent(env);
|
||||||
log("-- parent role started --");
|
log("-- parent role started --");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,7 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/env.h>
|
#include <base/component.h>
|
||||||
#include <base/thread.h>
|
|
||||||
#include <base/signal.h>
|
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#include <rm_session/connection.h>
|
#include <rm_session/connection.h>
|
||||||
#include <region_map/client.h>
|
#include <region_map/client.h>
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
|
@ -38,22 +35,15 @@ enum {
|
||||||
/**
|
/**
|
||||||
* Region-manager fault handler resolves faults by attaching new dataspaces
|
* Region-manager fault handler resolves faults by attaching new dataspaces
|
||||||
*/
|
*/
|
||||||
class Local_fault_handler : public Thread_deprecated<4096>
|
class Local_fault_handler : public Entrypoint
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Region_map &_region_map;
|
Env & _env;
|
||||||
Signal_receiver &_receiver;
|
Region_map & _region_map;
|
||||||
|
Signal_handler<Local_fault_handler> _handler;
|
||||||
|
|
||||||
public:
|
void _handle_fault()
|
||||||
|
|
||||||
Local_fault_handler(Region_map ®ion_map, Signal_receiver &receiver)
|
|
||||||
:
|
|
||||||
Thread_deprecated("local_fault_handler"),
|
|
||||||
_region_map(region_map), _receiver(receiver)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void handle_fault()
|
|
||||||
{
|
{
|
||||||
Region_map::State state = _region_map.state();
|
Region_map::State state = _region_map.state();
|
||||||
|
|
||||||
|
@ -64,45 +54,44 @@ class Local_fault_handler : public Thread_deprecated<4096>
|
||||||
", pf_addr=", Hex(state.addr, Hex::PREFIX));
|
", pf_addr=", Hex(state.addr, Hex::PREFIX));
|
||||||
|
|
||||||
log("allocate dataspace and attach it to sub region map");
|
log("allocate dataspace and attach it to sub region map");
|
||||||
Dataspace_capability ds = env()->ram_session()->alloc(PAGE_SIZE);
|
Dataspace_capability ds = _env.ram().alloc(PAGE_SIZE);
|
||||||
_region_map.attach_at(ds, state.addr & ~(PAGE_SIZE - 1));
|
_region_map.attach_at(ds, state.addr & ~(PAGE_SIZE - 1));
|
||||||
|
|
||||||
log("returning from handle_fault");
|
log("returning from handle_fault");
|
||||||
}
|
}
|
||||||
|
|
||||||
void entry()
|
public:
|
||||||
|
|
||||||
|
Local_fault_handler(Genode::Env & env, Region_map ®ion_map)
|
||||||
|
: Entrypoint(env, sizeof(addr_t)*2048, "local_fault_handler"),
|
||||||
|
_env(env),
|
||||||
|
_region_map(region_map),
|
||||||
|
_handler(*this, *this, &Local_fault_handler::_handle_fault)
|
||||||
{
|
{
|
||||||
while (true) {
|
region_map.fault_handler(_handler);
|
||||||
log("fault handler: waiting for fault signal");
|
|
||||||
Signal signal = _receiver.wait_for_signal();
|
log("fault handler: waiting for fault signal");
|
||||||
log("received ", signal.num(), " fault signals");
|
|
||||||
for (unsigned i = 0; i < signal.num(); i++)
|
|
||||||
handle_fault();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dissolve() { Entrypoint::dissolve(_handler); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
void Component::construct(Genode::Env & env)
|
||||||
{
|
{
|
||||||
log("--- nested region map test ---");
|
log("--- nested region map test ---");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize sub region map and set up a local fault handler for it.
|
* Initialize sub region map and set up a local fault handler for it.
|
||||||
*/
|
*/
|
||||||
static Rm_connection rm;
|
static Rm_connection rm(env);
|
||||||
static Region_map_client region_map(rm.create(MANAGED_SIZE));
|
static Region_map_client region_map(rm.create(MANAGED_SIZE));
|
||||||
static Cap_connection cap;
|
static Local_fault_handler fault_handler(env, region_map);
|
||||||
static Signal_receiver receiver;
|
|
||||||
static Signal_context context;
|
|
||||||
region_map.fault_handler(receiver.manage(&context));
|
|
||||||
static Local_fault_handler fault_handler(region_map, receiver);
|
|
||||||
fault_handler.start();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attach region map as dataspace to the local address space.
|
* Attach region map as dataspace to the local address space.
|
||||||
*/
|
*/
|
||||||
void *addr = env()->rm_session()->attach(region_map.dataspace());
|
void *addr = env.rm().attach(region_map.dataspace());
|
||||||
|
|
||||||
log("attached sub dataspace at local address ", addr);
|
log("attached sub dataspace at local address ", addr);
|
||||||
Dataspace_client client(region_map.dataspace());
|
Dataspace_client client(region_map.dataspace());
|
||||||
|
@ -118,12 +107,11 @@ int main(int argc, char **argv)
|
||||||
managed[i] = 13;
|
managed[i] = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
receiver.dissolve(&context);
|
fault_handler.dissolve();
|
||||||
|
|
||||||
log("test destruction of region_map");
|
log("test destruction of region_map");
|
||||||
Capability<Region_map> rcap = rm.create(4096);
|
Capability<Region_map> rcap = rm.create(4096);
|
||||||
rm.destroy(rcap);
|
rm.destroy(rcap);
|
||||||
|
|
||||||
log("--- finished nested region map test ---");
|
log("--- finished nested region map test ---");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
* \date 2012-11-01
|
* \date 2012-11-01
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <base/component.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
void Component::construct(Genode::Env &)
|
||||||
{
|
{
|
||||||
Genode::log("going to produce a segmentation fault...");
|
Genode::log("going to produce a segmentation fault...");
|
||||||
|
|
||||||
*((int *)0x44) = 0x55;
|
*((int *)0x44) = 0x55;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/env.h>
|
#include <base/component.h>
|
||||||
|
#include <base/heap.h>
|
||||||
#include <base/slab.h>
|
#include <base/slab.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/allocator_guard.h>
|
#include <base/allocator_guard.h>
|
||||||
|
@ -26,7 +27,8 @@ using Genode::error;
|
||||||
|
|
||||||
struct Array_of_slab_elements
|
struct Array_of_slab_elements
|
||||||
{
|
{
|
||||||
Genode::Slab &slab;
|
Genode::Slab & slab;
|
||||||
|
Genode::Allocator & alloc;
|
||||||
|
|
||||||
size_t const num_elem;
|
size_t const num_elem;
|
||||||
size_t const slab_size;
|
size_t const slab_size;
|
||||||
|
@ -40,21 +42,14 @@ struct Array_of_slab_elements
|
||||||
|
|
||||||
struct Alloc_failed { };
|
struct Alloc_failed { };
|
||||||
|
|
||||||
/**
|
Array_of_slab_elements(Genode::Slab &slab, size_t num_elem, size_t slab_size,
|
||||||
* Constructor
|
Genode::Allocator & alloc)
|
||||||
*
|
: slab(slab), alloc(alloc), num_elem(num_elem), slab_size(slab_size),
|
||||||
* \throw Alloc_failed
|
elem((void**) alloc.alloc(_elem_array_size()))
|
||||||
*/
|
|
||||||
Array_of_slab_elements(Genode::Slab &slab, size_t num_elem, size_t slab_size)
|
|
||||||
:
|
|
||||||
slab(slab), num_elem(num_elem), slab_size(slab_size)
|
|
||||||
{
|
{
|
||||||
elem = (void **)Genode::env()->heap()->alloc(_elem_array_size());
|
|
||||||
|
|
||||||
log(" allocate ", num_elem, " elements");
|
log(" allocate ", num_elem, " elements");
|
||||||
for (size_t i = 0; i < num_elem; i++)
|
for (size_t i = 0; i < num_elem; i++)
|
||||||
if (!slab.alloc(slab_size, &elem[i]))
|
if (!slab.alloc(slab_size, &elem[i])) throw Alloc_failed();
|
||||||
throw Alloc_failed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Array_of_slab_elements()
|
~Array_of_slab_elements()
|
||||||
|
@ -63,19 +58,21 @@ struct Array_of_slab_elements
|
||||||
for (size_t i = 0; i < num_elem; i++)
|
for (size_t i = 0; i < num_elem; i++)
|
||||||
slab.free(elem[i], slab_size);
|
slab.free(elem[i], slab_size);
|
||||||
|
|
||||||
Genode::env()->heap()->free(elem, _elem_array_size());
|
alloc.free(elem, _elem_array_size());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
void Component::construct(Genode::Env & env)
|
||||||
{
|
{
|
||||||
|
Genode::Heap heap(env.ram(), env.rm());
|
||||||
|
|
||||||
log("--- slab test ---");
|
log("--- slab test ---");
|
||||||
|
|
||||||
static Timer::Connection timer;
|
static Timer::Connection timer(env);
|
||||||
|
|
||||||
enum { SLAB_SIZE = 16, BLOCK_SIZE = 256 };
|
enum { SLAB_SIZE = 16, BLOCK_SIZE = 256 };
|
||||||
static Genode::Allocator_guard alloc(Genode::env()->heap(), ~0UL);
|
static Genode::Allocator_guard alloc(&heap, ~0UL);
|
||||||
|
|
||||||
{
|
{
|
||||||
Genode::Slab slab(SLAB_SIZE, BLOCK_SIZE, nullptr, &alloc);
|
Genode::Slab slab(SLAB_SIZE, BLOCK_SIZE, nullptr, &alloc);
|
||||||
|
@ -85,7 +82,7 @@ int main(int argc, char **argv)
|
||||||
"used quota: ", alloc.consumed(), " "
|
"used quota: ", alloc.consumed(), " "
|
||||||
"time: ", timer.elapsed_ms(), " ms)");
|
"time: ", timer.elapsed_ms(), " ms)");
|
||||||
|
|
||||||
Array_of_slab_elements array(slab, i*100000, SLAB_SIZE);
|
Array_of_slab_elements array(slab, i*100000, SLAB_SIZE, heap);
|
||||||
log(" allocation completed (used quota: ", alloc.consumed(), ")");
|
log(" allocation completed (used quota: ", alloc.consumed(), ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +97,7 @@ int main(int argc, char **argv)
|
||||||
enum { HEAP_OVERHEAD = 36 };
|
enum { HEAP_OVERHEAD = 36 };
|
||||||
if (alloc.consumed() > 2*(BLOCK_SIZE + HEAP_OVERHEAD)) {
|
if (alloc.consumed() > 2*(BLOCK_SIZE + HEAP_OVERHEAD)) {
|
||||||
error("slab failed to release empty slab blocks");
|
error("slab failed to release empty slab blocks");
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +105,8 @@ int main(int argc, char **argv)
|
||||||
log("destructed slab (used quota: ", alloc.consumed(), ")");
|
log("destructed slab (used quota: ", alloc.consumed(), ")");
|
||||||
if (alloc.consumed() > 0) {
|
if (alloc.consumed() > 0) {
|
||||||
error("slab failed to release all backing store");
|
error("slab failed to release all backing store");
|
||||||
return -2;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
log("Test done");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <util/mmio.h>
|
#include <base/component.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
#include <util/mmio.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
@ -186,8 +187,11 @@ int compare_mem(uint8_t * base1, uint8_t * base2, size_t size)
|
||||||
void error(unsigned line) { error("Test in line ", line, " failed"); }
|
void error(unsigned line) { error("Test in line ", line, " failed"); }
|
||||||
|
|
||||||
|
|
||||||
int main()
|
void Component::construct(Genode::Env &)
|
||||||
{
|
{
|
||||||
|
using ::Cpu_state;
|
||||||
|
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
** 'Genode::Mmio::Register' tests **
|
** 'Genode::Mmio::Register' tests **
|
||||||
************************************/
|
************************************/
|
||||||
|
@ -465,6 +469,5 @@ int main()
|
||||||
}
|
}
|
||||||
|
|
||||||
log("Test done");
|
log("Test done");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <base/component.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/env.h>
|
#include <base/heap.h>
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <base/weak_ptr.h>
|
#include <base/weak_ptr.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
|
@ -35,7 +36,7 @@ void Genode::Weak_object_base::debug_info() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int weak_ptr_valid;
|
static bool weak_ptr_valid;
|
||||||
|
|
||||||
|
|
||||||
void Genode::Weak_ptr_base::debug_info() const
|
void Genode::Weak_ptr_base::debug_info() const
|
||||||
|
@ -91,7 +92,7 @@ struct Object : Genode::Weak_object<Object>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void test_weak_pointer_tracking()
|
static void test_weak_pointer_tracking(Genode::Heap & heap)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ static void test_weak_pointer_tracking()
|
||||||
assert_weak_ptr_valid(ptr, false);
|
assert_weak_ptr_valid(ptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *obj = new (env()->heap()) Object;
|
Object *obj = new (heap) Object;
|
||||||
|
|
||||||
Weak_ptr<Object> ptr_1 = obj->weak_ptr();
|
Weak_ptr<Object> ptr_1 = obj->weak_ptr();
|
||||||
assert_weak_ptr_valid(ptr_1, true);
|
assert_weak_ptr_valid(ptr_1, true);
|
||||||
|
@ -127,7 +128,7 @@ static void test_weak_pointer_tracking()
|
||||||
assert_weak_ptr_cnt(obj, 2);
|
assert_weak_ptr_cnt(obj, 2);
|
||||||
|
|
||||||
log("destruct object");
|
log("destruct object");
|
||||||
destroy(env()->heap(), obj);
|
destroy(heap, obj);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The destruction of the object should have invalidated all weak pointers
|
* The destruction of the object should have invalidated all weak pointers
|
||||||
|
@ -143,19 +144,21 @@ static void test_weak_pointer_tracking()
|
||||||
*******************************************/
|
*******************************************/
|
||||||
|
|
||||||
template <typename O>
|
template <typename O>
|
||||||
struct Destruct_thread : Genode::Thread_deprecated<4096>
|
struct Destruct_thread : Genode::Thread
|
||||||
{
|
{
|
||||||
O *obj;
|
O *obj;
|
||||||
|
Genode::Heap & heap;
|
||||||
|
|
||||||
void entry()
|
void entry()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
log("thread: going to destroy object");
|
log("thread: going to destroy object");
|
||||||
destroy(env()->heap(), obj);
|
destroy(heap, obj);
|
||||||
log("thread: destruction completed, job done");
|
log("thread: destruction completed, job done");
|
||||||
}
|
}
|
||||||
|
|
||||||
Destruct_thread(O *obj) : Thread_deprecated("object_destructor"), obj(obj) { }
|
Destruct_thread(O *obj, Genode::Env & env, Genode::Heap & heap)
|
||||||
|
: Thread(env, "object_destructor", 4096), obj(obj), heap(heap) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,13 +173,13 @@ static void assert_constructed(bool expect_constructed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void test_deferred_destruction()
|
static void test_deferred_destruction(Genode::Env & env, Genode::Heap &heap)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
static Timer::Connection timer;
|
static Timer::Connection timer(env);
|
||||||
|
|
||||||
Object *obj = new (env()->heap()) Object;
|
Object *obj = new (&heap) Object;
|
||||||
|
|
||||||
Weak_ptr<Object> ptr = obj->weak_ptr();
|
Weak_ptr<Object> ptr = obj->weak_ptr();
|
||||||
assert_weak_ptr_cnt(obj, 1);
|
assert_weak_ptr_cnt(obj, 1);
|
||||||
|
@ -184,7 +187,7 @@ static void test_deferred_destruction()
|
||||||
assert_constructed(true);
|
assert_constructed(true);
|
||||||
|
|
||||||
/* create thread that will be used to destruct the object */
|
/* create thread that will be used to destruct the object */
|
||||||
Destruct_thread<Object> destruct_thread(obj);
|
Destruct_thread<Object> destruct_thread(obj, env, heap);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* acquire possession over the object */
|
/* acquire possession over the object */
|
||||||
|
@ -218,12 +221,12 @@ static void test_deferred_destruction()
|
||||||
** Test the failed aquisition of a destructed object **
|
** Test the failed aquisition of a destructed object **
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
|
||||||
static void test_acquisition_failure()
|
static void test_acquisition_failure(Genode::Heap & heap)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
log("create object and weak pointer");
|
log("create object and weak pointer");
|
||||||
Object *obj = new (env()->heap()) Object;
|
Object *obj = new (&heap) Object;
|
||||||
Weak_ptr<Object> ptr = obj->weak_ptr();
|
Weak_ptr<Object> ptr = obj->weak_ptr();
|
||||||
|
|
||||||
log("try to acquire possession over the object");
|
log("try to acquire possession over the object");
|
||||||
|
@ -239,7 +242,7 @@ static void test_acquisition_failure()
|
||||||
}
|
}
|
||||||
|
|
||||||
log("destroy object");
|
log("destroy object");
|
||||||
destroy(env()->heap(), obj);
|
destroy(&heap, obj);
|
||||||
|
|
||||||
log("try again, this time we should get an invalid pointer");
|
log("try again, this time we should get an invalid pointer");
|
||||||
{
|
{
|
||||||
|
@ -262,7 +265,8 @@ struct Object_with_delayed_destruction
|
||||||
{
|
{
|
||||||
Timer::Connection timer;
|
Timer::Connection timer;
|
||||||
|
|
||||||
Object_with_delayed_destruction() { object_constructed = true; }
|
Object_with_delayed_destruction(Genode::Env & env) : timer(env) {
|
||||||
|
object_constructed = true; }
|
||||||
|
|
||||||
~Object_with_delayed_destruction()
|
~Object_with_delayed_destruction()
|
||||||
{
|
{
|
||||||
|
@ -273,14 +277,16 @@ struct Object_with_delayed_destruction
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void test_acquisition_during_destruction()
|
static void test_acquisition_during_destruction(Genode::Env & env,
|
||||||
|
Genode::Heap & heap)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
using Destruct_thread = Destruct_thread<Object_with_delayed_destruction>;
|
||||||
|
|
||||||
static Timer::Connection timer;
|
static Timer::Connection timer(env);
|
||||||
|
|
||||||
Object_with_delayed_destruction *obj =
|
Object_with_delayed_destruction *obj =
|
||||||
new (env()->heap()) Object_with_delayed_destruction();
|
new (&heap) Object_with_delayed_destruction(env);
|
||||||
|
|
||||||
Weak_ptr<Object_with_delayed_destruction> ptr = obj->weak_ptr();
|
Weak_ptr<Object_with_delayed_destruction> ptr = obj->weak_ptr();
|
||||||
assert_weak_ptr_cnt(obj, 1);
|
assert_weak_ptr_cnt(obj, 1);
|
||||||
|
@ -288,7 +294,7 @@ static void test_acquisition_during_destruction()
|
||||||
assert_constructed(true);
|
assert_constructed(true);
|
||||||
|
|
||||||
/* create and start thread that will be used to destruct the object */
|
/* create and start thread that will be used to destruct the object */
|
||||||
Destruct_thread<Object_with_delayed_destruction> destruct_thread(obj);
|
Destruct_thread destruct_thread(obj, env, heap);
|
||||||
destruct_thread.start();
|
destruct_thread.start();
|
||||||
|
|
||||||
/* wait so that the thread enters the destructor */
|
/* wait so that the thread enters the destructor */
|
||||||
|
@ -310,24 +316,25 @@ static void test_acquisition_during_destruction()
|
||||||
** Main program **
|
** Main program **
|
||||||
******************/
|
******************/
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
void Component::construct(Genode::Env & env)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
Heap heap(env.ram(), env.rm());
|
||||||
|
|
||||||
log("--- test-weak_ptr started ---");
|
log("--- test-weak_ptr started ---");
|
||||||
|
|
||||||
log("\n-- test tracking of weak pointers --");
|
log("\n-- test tracking of weak pointers --");
|
||||||
test_weak_pointer_tracking();
|
test_weak_pointer_tracking(heap);
|
||||||
|
|
||||||
log("\n-- test deferred destruction --");
|
log("\n-- test deferred destruction --");
|
||||||
test_deferred_destruction();
|
test_deferred_destruction(env, heap);
|
||||||
|
|
||||||
log("\n-- test acquisition failure --");
|
log("\n-- test acquisition failure --");
|
||||||
test_acquisition_failure();
|
test_acquisition_failure(heap);
|
||||||
|
|
||||||
log("\n-- test acquisition during destruction --");
|
log("\n-- test acquisition during destruction --");
|
||||||
test_acquisition_during_destruction();
|
test_acquisition_during_destruction(env, heap);
|
||||||
|
|
||||||
log("\n--- finished test-weak_ptr ---");
|
log("\n--- finished test-weak_ptr ---");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user