From e61f6cfd3853d8867ea2686ced27c6d700079b9b Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 23 Sep 2020 11:41:22 +0200 Subject: [PATCH] base: add thread migration test Issue #3842 --- repos/base/run/migrate.run | 62 +++++++++ repos/base/src/test/migrate/main.cc | 173 ++++++++++++++++++++++++++ repos/base/src/test/migrate/target.mk | 3 + tool/autopilot.list | 1 + 4 files changed, 239 insertions(+) create mode 100644 repos/base/run/migrate.run create mode 100644 repos/base/src/test/migrate/main.cc create mode 100644 repos/base/src/test/migrate/target.mk diff --git a/repos/base/run/migrate.run b/repos/base/run/migrate.run new file mode 100644 index 0000000000..cc3cd573d3 --- /dev/null +++ b/repos/base/run/migrate.run @@ -0,0 +1,62 @@ +build "core init test/migrate timer" + +if {![have_include "power_on/qemu"]} { + puts "Run script is not supported on this platform" + exit 0 +} +if {[have_spec foc] && ([have_spec pbxa9] || [have_spec rpi3])} { + # foc kernel does detect solely 1 CPU */ + puts "Run script is not supported on this platform" + exit 0 +} +if {![have_spec nova] && ![have_spec foc] && ![have_spec sel4]} { + puts "Run script is not supported on this platform" + exit 0 +} + +create_boot_directory + +append config { + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +build_boot_image "core ld.lib.so init test-migrate timer" + +append qemu_args "-nographic " +append qemu_args "-smp 4,cores=4,threads=1" + +run_genode_until {.*test completed successfully.*\n} 70 + +grep_output {^\[init -> test-migrate\] \[ep\] thread 'migrate' migrated, .*} + +compare_output_to { +[init -> test-migrate] [ep] thread 'migrate' migrated, location=1x0 +[init -> test-migrate] [ep] thread 'migrate' migrated, location=2x0 +[init -> test-migrate] [ep] thread 'migrate' migrated, location=3x0 +[init -> test-migrate] [ep] thread 'migrate' migrated, location=0x0 +} diff --git a/repos/base/src/test/migrate/main.cc b/repos/base/src/test/migrate/main.cc new file mode 100644 index 0000000000..79d4dbac74 --- /dev/null +++ b/repos/base/src/test/migrate/main.cc @@ -0,0 +1,173 @@ +/* + * \brief Testing thread migration + * \author Alexander Boettcher + * \date 2020-08-13 + */ + +/* + * Copyright (C) 2020 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Genode includes */ +#include +#include +#include +#include +#include + +using namespace Genode; + + +enum { STACK_SIZE = 0x3000 }; + +/************************************************ + ** Migrate thread over all available CPU test ** + ************************************************/ + +struct Migrate_thread : Thread +{ + Blockade blockade { }; + Env &env; + + Migrate_thread(Env &env) + : Thread(env, "migrate", STACK_SIZE), env(env) + { } + + void entry() override + { + Cpu_thread_client thread_client(cap()); + + /* we are ready */ + blockade.wakeup(); + + while (true) { + log("[migrate] going to sleep"); + + blockade.block(); + + log("[migrate] woke up - got migrated ?"); + } + } +}; + +struct Migrate +{ + Env &env; + Timer::Connection timer { env }; + Migrate_thread thread { env }; + Trace::Connection trace { env, 15 * 4096 /* RAM quota */, + 11 * 4096 /* ARG_BUFFER RAM quota */, + 0 /* parent levels */ }; + + Signal_handler timer_handler { env.ep(), *this, + &Migrate::check_traces }; + + Trace::Subject_id trace_id { }; + Affinity::Location location { }; + unsigned loc_same { 0 }; + unsigned loc_pos { 0 }; + + unsigned test_rounds { 0 }; + + enum State { + LOOKUP_TRACE_ID, CHECK_AFFINITY, MIGRATE + } state { LOOKUP_TRACE_ID }; + + Migrate(Env &env) : env(env) + { + Affinity::Space cpus = env.cpu().affinity_space(); + log("Detected ", cpus.width(), "x", cpus.height(), " CPU", + cpus.total() > 1 ? "s." : "."); + + timer.sigh(timer_handler); + + thread.start(); + thread.blockade.block(); + + timer.trigger_periodic( 500 * 1000 /* us */); + } + + void check_traces() + { + switch (state) { + case LOOKUP_TRACE_ID: + { + auto count = trace.for_each_subject_info([&](Trace::Subject_id const &id, + Trace::Subject_info const &info) + { + if (info.thread_name() != "migrate") + return; + + trace_id = id; + location = info.affinity(); + state = CHECK_AFFINITY; + + log("[ep] thread '", info.thread_name(), "' started,", + " location=", location.xpos(), "x", location.ypos()); + }); + + if (count.count == count.limit && state == LOOKUP_TRACE_ID) { + error("trace argument buffer too small for the test"); + } + break; + } + case CHECK_AFFINITY: + { + Trace::Subject_info const info = trace.subject_info(trace_id); + + loc_same ++; + + if ((location.xpos() == info.affinity().xpos()) && + (location.ypos() == info.affinity().ypos()) && + (location.width() == info.affinity().width()) && + (location.height() == info.affinity().height())) + { + if (loc_same >= 1) { + loc_same = 0; + state = MIGRATE; + } + log ("[ep] ."); + break; + } + + loc_same = 0; + location = info.affinity(); + + log("[ep] thread '", info.thread_name(), "' migrated,", + " location=", location.xpos(), "x", location.ypos()); + + test_rounds ++; + if (test_rounds == 4) + log("--- test completed successfully ---"); + break; + } + case MIGRATE: + state = CHECK_AFFINITY; + + loc_pos ++; + Affinity::Location const loc = env.cpu().affinity_space().location_of_index(loc_pos); + + /* trigger migration */ + Cpu_thread_client client(thread.cap()); + client.affinity(loc); + + log("[ep] thread 'migrate' scheduled to migrate to location=", + loc.xpos(), "x", loc.ypos()); + + thread.blockade.wakeup(); + + break; + } + } +}; + + +void Component::construct(Env &env) +{ + log("--- migrate thread test started ---"); + + static Migrate migrate_test(env); +} diff --git a/repos/base/src/test/migrate/target.mk b/repos/base/src/test/migrate/target.mk new file mode 100644 index 0000000000..6ae4d742a4 --- /dev/null +++ b/repos/base/src/test/migrate/target.mk @@ -0,0 +1,3 @@ +TARGET = test-migrate +SRC_CC = main.cc +LIBS = base diff --git a/tool/autopilot.list b/tool/autopilot.list index 83d782dc20..3d5ff01d67 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -22,6 +22,7 @@ lx_hybrid_ctors lx_hybrid_exception lx_hybrid_pthread_ipc microcode +migrate moon netperf_lwip netperf_lwip_bridge