mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
ealanos: Test for class Superblock.
This commit is contained in:
52
repos/ealanos/run/superblock_test.run
Normal file
52
repos/ealanos/run/superblock_test.run
Normal file
@@ -0,0 +1,52 @@
|
||||
set build_components {
|
||||
core init hoitaja timer test/superblock_test
|
||||
}
|
||||
|
||||
build $build_components
|
||||
create_boot_directory
|
||||
|
||||
install_config {
|
||||
<config prio_levels="32" verbose="true">
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="CPU"/>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="RM"/>
|
||||
<service name="SIGNAL"/>
|
||||
<service name="TRACE"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service><parent/><any-child/></any-service>
|
||||
</default-route>
|
||||
<default caps="2000"/>
|
||||
<affinity-space width="32" height="1"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="3M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
<route>
|
||||
<any-service><parent/><any-child/></any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="cell1" priority="-1">
|
||||
<binary name="superblock_test"/>
|
||||
<resource name="RAM" quantum="3M"/>
|
||||
</start>
|
||||
<!--
|
||||
<start name="cell2" priority="-2">
|
||||
<binary name="empty_cell"/>
|
||||
<resource name="RAM" quantum="3M"/>
|
||||
</start>
|
||||
-->
|
||||
</config>
|
||||
}
|
||||
|
||||
build_boot_image [build_artifacts]
|
||||
|
||||
append qemu_args " -nographic "
|
||||
run_genode_until forever
|
||||
164
repos/ealanos/src/test/superblock_test/main.cpp
Normal file
164
repos/ealanos/src/test/superblock_test/main.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* @file main.cpp
|
||||
* @author Michael Müller
|
||||
* @brief Component for testing superblocks
|
||||
* @version 0.1
|
||||
* @date 2025-03-06
|
||||
*
|
||||
* @copyright Copyright (c) 2025
|
||||
*
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
#include <base/log.h>
|
||||
#include <ealanos/memory/superblock.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/heap.h>
|
||||
|
||||
namespace Ealan::Memory {
|
||||
class SuperblockTest;
|
||||
}
|
||||
|
||||
class Ealan::Memory::SuperblockTest
|
||||
{
|
||||
private:
|
||||
Genode::Env &_env;
|
||||
|
||||
class SuperblockTestThread : public Genode::Thread
|
||||
{
|
||||
private:
|
||||
Genode::Env &_env;
|
||||
Superblock<8192, 64> *_sb;
|
||||
Genode::size_t _blocks;
|
||||
|
||||
SuperblockTestThread(const SuperblockTestThread &);
|
||||
SuperblockTest &operator=(SuperblockTestThread &);
|
||||
|
||||
public:
|
||||
SuperblockTestThread(Genode::Env &env, Superblock<8192,64> *sb, Genode::size_t blocks, Genode::Affinity::Location loc) : Genode::Thread(env, Genode::Thread::Name("superblocktest"), 4 * 4096, loc, Genode::Cpu_session::Weight(), env.cpu()), _env(env), _sb(sb), _blocks(blocks)
|
||||
{}
|
||||
|
||||
void entry() override {
|
||||
void *blocks[_blocks];
|
||||
|
||||
Genode::log("Capacity of superblock ", _sb, " is ", _sb->free_blocks());
|
||||
|
||||
for (unsigned i = 0; i < _blocks; i++) {
|
||||
blocks[i] = _sb->alloc();
|
||||
Genode::log("blocks[", i, "]=", blocks[i]);
|
||||
_sb->free(blocks[i]);
|
||||
Genode::log("Freed ", blocks[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
SuperblockTest(Genode::Env &env) : _env(env)
|
||||
{
|
||||
Genode::Ram_dataspace_capability ds = _env.ram().alloc(8192);
|
||||
Genode::Region_map::Attr attr{};
|
||||
attr.writeable = true;
|
||||
Genode::Region_map::Attach_result const result = _env.rm().attach(ds, attr);
|
||||
Genode::Heap heap(_env.ram(), _env.rm());
|
||||
|
||||
void *sb_address = result.convert<void *>(
|
||||
[&](Genode::Region_map::Range r)
|
||||
{ return reinterpret_cast<void *>(r.start); },
|
||||
[&](Genode::Region_map::Attach_error)
|
||||
{
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
Genode::log("Attached dataspace for superblock");
|
||||
Superblock<8192, 64> *sb = new (sb_address) Superblock<8192, 64>(128);
|
||||
|
||||
Genode::log("Superblock has ", sb->free_blocks(), " free blocks.");
|
||||
Genode::log("Superblock blocks begin at ", sb->start());
|
||||
|
||||
Genode::size_t capacity = sb->free_blocks();
|
||||
|
||||
Genode::log("Allocating blocks until superblock is full");
|
||||
|
||||
void *blocks[capacity];
|
||||
|
||||
for (unsigned i = 0; i < capacity; i++)
|
||||
{
|
||||
blocks[i] = sb->alloc();
|
||||
Genode::log("block[", i, "]=", blocks[i], " left=", sb->free_blocks());
|
||||
}
|
||||
|
||||
Genode::log("Test if allocating from full block yields nullptr");
|
||||
if (!sb->alloc()) {
|
||||
Genode::log("Success.");
|
||||
} else {
|
||||
Genode::error("Got block despite superblock being full.");
|
||||
}
|
||||
|
||||
Genode::log("Freeing 1/2 of the blocks (every second block) and checking if capacity is ", capacity / 2);
|
||||
for (unsigned i = 1; i < capacity; i+=2) {
|
||||
sb->free(blocks[i]);
|
||||
}
|
||||
if (sb->free_blocks() == capacity/2) {
|
||||
Genode::log("Success.");
|
||||
} else {
|
||||
Genode::error("Capacity of superblock is: ", sb->free_blocks(), " but should be ", capacity / 2);
|
||||
}
|
||||
|
||||
Genode::log("The next block we allocate should be right after the first allocated block.");
|
||||
blocks[1] = sb->alloc();
|
||||
if (blocks[1] != reinterpret_cast<void*>(reinterpret_cast<Genode::addr_t>(blocks[0])+128)) {
|
||||
Genode::error("Allocator yielded wrong block: ", blocks[1]);
|
||||
} else {
|
||||
Genode::log("Success.");
|
||||
}
|
||||
|
||||
Genode::log("Testing aligned alloc with default alignment=64");
|
||||
blocks[3] = sb->aligned_alloc();
|
||||
if (reinterpret_cast<Genode::addr_t>(blocks[3]) % 64 == 0) {
|
||||
Genode::log("Success");
|
||||
} else {
|
||||
Genode::error("Alignment error: ", blocks[3], " is not 64-bytes aligned");
|
||||
}
|
||||
|
||||
Genode::log("Freeing all remaining blocks");
|
||||
|
||||
sb->free(blocks[3]);
|
||||
sb->free(blocks[1]);
|
||||
|
||||
for (unsigned i = 0; i < capacity; i+=2) {
|
||||
sb->free(blocks[i]);
|
||||
}
|
||||
|
||||
if (sb->free_blocks() == capacity) {
|
||||
Genode::log("Success. Full capacitiy restored.");
|
||||
} else {
|
||||
Genode::error("Could not free all blocks. Capacity is now: ", sb->free_blocks());
|
||||
}
|
||||
|
||||
Genode::log("Thread-safety test ");
|
||||
SuperblockTestThread *threads[8];
|
||||
for (unsigned i = 0; i < 8; i++)
|
||||
{
|
||||
threads[i] = new (heap) SuperblockTestThread(env, sb, capacity / 8, env.cpu().affinity_space().location_of_index(i));
|
||||
threads[i]->start();
|
||||
}
|
||||
|
||||
Genode::log("Threads started. Waiting for completion..");
|
||||
for (unsigned i = 0; i < 8; i++)
|
||||
{
|
||||
threads[i]->join();
|
||||
}
|
||||
Genode::log("Threads finished. There should be ", capacity, " blocks left now.");
|
||||
if (sb->free_blocks() == capacity) {
|
||||
Genode::log("Success.");
|
||||
} else {
|
||||
Genode::error("Failed: ", sb->free_blocks(), "left.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Ealan::Memory::SuperblockTest test(env);
|
||||
}
|
||||
6
repos/ealanos/src/test/superblock_test/target.mk
Normal file
6
repos/ealanos/src/test/superblock_test/target.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
TARGET = superblock_test
|
||||
SRC_CC = main.cpp
|
||||
LIBS = base
|
||||
INC_DIR = $(PRG_DIR)
|
||||
INC_DIR += $(REP_DIR)/include
|
||||
|
||||
Reference in New Issue
Block a user