diff --git a/repos/ealanos/run/core_withdrawal_experiment.run b/repos/ealanos/run/core_withdrawal_experiment.run new file mode 100644 index 0000000000..590eedd8ea --- /dev/null +++ b/repos/ealanos/run/core_withdrawal_experiment.run @@ -0,0 +1,78 @@ +set build_components { + core init hoitaja timer lib/ld lib/libm lib/libc lib/stdcxx lib/vfs app/allocating_cell app/allocation_antagonist +} + +build $build_components +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2022-07-20 14:30 + + + + + + + + + + + + 2022-07-20 14:30 + + + + + + + + + + + + 2022-07-20 14:30 + + + + + + +} + +build_boot_image [build_artifacts] + +append qemu_args " -nographic " +run_genode_until forever \ No newline at end of file diff --git a/repos/ealanos/src/app/allocation_antagonist/config.h b/repos/ealanos/src/app/allocation_antagonist/config.h new file mode 120000 index 0000000000..2d5b04b6fb --- /dev/null +++ b/repos/ealanos/src/app/allocation_antagonist/config.h @@ -0,0 +1 @@ +/home/mml/loopbench/config.h \ No newline at end of file diff --git a/repos/ealanos/src/app/allocation_antagonist/loop.c b/repos/ealanos/src/app/allocation_antagonist/loop.c new file mode 120000 index 0000000000..28a2cf5277 --- /dev/null +++ b/repos/ealanos/src/app/allocation_antagonist/loop.c @@ -0,0 +1 @@ +/home/mml/loopbench/loop.c \ No newline at end of file diff --git a/repos/ealanos/src/app/allocation_antagonist/loop.h b/repos/ealanos/src/app/allocation_antagonist/loop.h new file mode 120000 index 0000000000..2d8b57437d --- /dev/null +++ b/repos/ealanos/src/app/allocation_antagonist/loop.h @@ -0,0 +1 @@ +/home/mml/loopbench/loop.h \ No newline at end of file diff --git a/repos/ealanos/src/app/allocation_antagonist/main.cc b/repos/ealanos/src/app/allocation_antagonist/main.cc new file mode 100644 index 0000000000..03f7c70e68 --- /dev/null +++ b/repos/ealanos/src/app/allocation_antagonist/main.cc @@ -0,0 +1,123 @@ +/** + * @file main.cc + * @author Michael Müller (michael.mueller@uos.de) + * @brief Antagonist for Core allocation + * @details This component acts as an antagonist to the allocating cell + * in allocating_cell by periodically allocating the maximum + * number of CPU cores, running in a loop for a specified time + * and then releasing the cores going to sleep for a certain + * amount of time. This way it will steal CPU cores from the + * allocating cell as well as getting all its cores borrowed + * by the allocating cell, prompting core withdrawals. + * @version 0.1 + * @date 2025-03-12 + * + * @copyright Copyright (c) 2025 + * + */ + +#include +#include +#include +#include +#include +#include +#include "loop.h" + +namespace Microbench { + class Antagonist; + class Worker; +} + +void short_loop(unsigned long k) +{ + for (unsigned long i = 0; i < k; i++) + { + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + } +} + +class Microbench::Worker : public Genode::Thread { + private: + unsigned _id; + + public: + void entry() override + { + Tukija::Cip::Worker *my_channel = &Tukija::Cip::cip()->worker_for_location(Genode::Thread::myself()->affinity()); + + unsigned cpu_id = Tukija::Cip::cip()->location_to_kernel_cpu(Genode::Thread::myself()->affinity()); + + Genode::log("Started antagonistic worker ", _id, " on CPU ", cpu_id); + + Tukija::release(Tukija::Resource_type::CPU_CORE); + + while(true) { + while (!(my_channel->yield_flag)) + short_loop(770); + //Genode::log("Antagonistic worker on CPU ", cpu_id, " got yield request."); + Tukija::return_to_owner(Tukija::Resource_type::CPU_CORE); + //Genode::log("Reactivated antagonistic worker on CPU ", cpu_id); + } + } + + Worker(Genode::Env &env, unsigned id, Genode::Affinity::Location const &loc) + : Thread(env, Genode::Thread::Name("worker", _id), 4*4096, loc, Weight(), env.cpu()), _id(id) {} +}; + +class Microbench::Antagonist +{ + private: + Genode::Env &_env; + Timer::Connection _timer{_env}; + + public: + Antagonist(Genode::Env &env) : _env(env) + { + Genode::Heap heap{_env.ram(), _env.rm()}; + + unsigned cpu_id = Tukija::Cip::cip()->location_to_kernel_cpu(Genode::Thread::myself()->affinity()); + + Genode::Affinity::Space const &space = Tukija::Cip::cip()->habitat_affinity; + + /* Create worker threads */ + for (unsigned cpu = 1; cpu < space.total(); cpu++) { + Worker *worker = new (heap) Worker(env, cpu, space.location_of_index(cpu)); + worker->start(); + } + + _timer.msleep(cpu_id); + + unsigned cores_owned = Tukija::Cip::cip()->cores_reserved.count(); + Genode::log("Owning ", cores_owned," CPU cores: ", Tukija::Cip::cip()->cores_reserved); + + for (;;) { + unsigned allocated = 0; + do { + Tukija::alloc(Tukija::Resource_type::CPU_CORE, space.total() / 2); + allocated += Tukija::Cip::cip()->cores_new.count(); + } while (allocated < cores_owned); + + Genode::log("Antagonist got CPUs ", Tukija::Cip::cip()->cores_new); + + while (Tukija::Cip::cip()->cores_current.count() != cores_owned+21) { + __builtin_ia32_pause(); + } + + loop(5); + } + } +}; + +void Component::construct(Genode::Env &env) { + static Microbench::Antagonist antagonist(env); +} \ No newline at end of file diff --git a/repos/ealanos/src/app/allocation_antagonist/target.mk b/repos/ealanos/src/app/allocation_antagonist/target.mk new file mode 100644 index 0000000000..2a26a512f1 --- /dev/null +++ b/repos/ealanos/src/app/allocation_antagonist/target.mk @@ -0,0 +1,3 @@ +TARGET = allocation_antagonist +SRC_CC = main.cc loop.c +LIBS += base \ No newline at end of file