diff --git a/repos/os/run/cpu_balancer.run b/repos/os/run/cpu_balancer.run
index fb9f0316ba..6fb6dd2eb0 100644
--- a/repos/os/run/cpu_balancer.run
+++ b/repos/os/run/cpu_balancer.run
@@ -1,4 +1,4 @@
-build "core init timer server/cpu_balancer app/cpu_burner app/top"
+build "core init timer server/cpu_balancer app/cpu_burner app/top server/dynamic_rom"
if {![have_include "power_on/qemu"]} {
puts "Run script is not supported on this platform"
@@ -63,6 +63,53 @@ append_if [expr $report_config eq "yes"] config {
}
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
append config {
@@ -70,20 +117,10 @@ append config {
-
-
-
-
-
-
-
-
+
+
+
@@ -125,7 +162,7 @@ append config {
install_config $config
-build_boot_image { core ld.lib.so init timer cpu_balancer cpu_burner top }
+build_boot_image { core ld.lib.so init timer cpu_balancer cpu_burner top dynamic_rom }
append qemu_args " -nographic"
append qemu_args " -smp [expr $cpu_width * $cpu_height],cores=$cpu_width,threads=$cpu_height"
diff --git a/repos/os/src/server/cpu_balancer/component.cc b/repos/os/src/server/cpu_balancer/component.cc
index 631b1f1654..8223963c4c 100644
--- a/repos/os/src/server/cpu_balancer/component.cc
+++ b/repos/os/src/server/cpu_balancer/component.cc
@@ -120,7 +120,13 @@ namespace Cpu {
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", remaining_ram_quota.value);
Arg_string::set_arg(argbuf, sizeof(argbuf), "cap_quota", remaining_cap_quota.value);
- return fn(argbuf);
+ try {
+ return fn(argbuf);
+ } catch (Out_of_ram) {
+ throw Insufficient_ram_quota();
+ } catch (Out_of_caps) {
+ throw Insufficient_cap_quota();
+ }
}
}
@@ -244,15 +250,9 @@ struct Cpu::Balancer : Rpc_object>
Mutex::Guard guard(list_mutex);
- auto * session = new (slice) Registered(list, env,
- affinity,
- session_args,
- list, verbose);
-
- /* check for config of new session */
- Cpu::Config::apply(config.xml(), list);
-
- return session->cap();
+ return (new (slice) Registered(list, env, affinity,
+ session_args, list, config,
+ verbose))->cap();
});
}
diff --git a/repos/os/src/server/cpu_balancer/config.cc b/repos/os/src/server/cpu_balancer/config.cc
index 01e5ab7088..c745d33ade 100644
--- a/repos/os/src/server/cpu_balancer/config.cc
+++ b/repos/os/src/server/cpu_balancer/config.cc
@@ -18,9 +18,6 @@
void Cpu::Config::apply(Xml_node const &start, Child_list &sessions)
{
- using Genode::Session_label;
- using Genode::String;
-
typedef String Label;
start.for_each_sub_node("component", [&](Xml_node const &node) {
@@ -54,8 +51,46 @@ void Cpu::Config::apply(Xml_node const &start, Child_list &sessions)
thread.attribute_value("ypos", 0U),
1, 1);
- session.config(name, policy, location);
+ session.update_if_active(name, policy, location);
});
});
});
}
+
+void Cpu::Config::apply_for_thread(Xml_node const &start, Cpu::Session &session,
+ Thread::Name const &target_thread)
+{
+ typedef String Label;
+
+ start.for_each_sub_node("component", [&](Xml_node const &node) {
+ if (!node.has_attribute("label"))
+ return;
+
+ Label const label = node.attribute_value("label", Label(""));
+
+ if (!session.match(label))
+ return;
+
+ node.for_each_sub_node("thread", [&](Xml_node const &thread) {
+ if (!thread.has_attribute("name") || !thread.has_attribute("policy"))
+ return;
+
+ Thread::Name const name = thread.attribute_value("name", Thread::Name());
+ Cpu::Policy::Name const policy = thread.attribute_value("policy", Cpu::Policy::Name());
+
+ if (target_thread != name)
+ return;
+
+ /* explicitly create invalid width/height */
+ /* used during thread construction in policy static case */
+ Affinity::Location location { 0, 0, 0, 0};
+
+ if (thread.has_attribute("xpos") && thread.has_attribute("ypos"))
+ location = Affinity::Location(thread.attribute_value("xpos", 0U),
+ thread.attribute_value("ypos", 0U),
+ 1, 1);
+
+ session.update(name, policy, location);
+ });
+ });
+}
diff --git a/repos/os/src/server/cpu_balancer/config.h b/repos/os/src/server/cpu_balancer/config.h
index 0cdce6a025..98b94de38d 100644
--- a/repos/os/src/server/cpu_balancer/config.h
+++ b/repos/os/src/server/cpu_balancer/config.h
@@ -29,6 +29,8 @@ class Cpu::Config {
public:
static void apply(Xml_node const &, Child_list &);
+ static void apply_for_thread(Xml_node const &, Cpu::Session &,
+ Thread::Name const &);
};
#endif /* _CONFIG_H_ */
diff --git a/repos/os/src/server/cpu_balancer/session.cc b/repos/os/src/server/cpu_balancer/session.cc
index 509102b766..b72929ec48 100644
--- a/repos/os/src/server/cpu_balancer/session.cc
+++ b/repos/os/src/server/cpu_balancer/session.cc
@@ -12,6 +12,7 @@
*/
#include "session.h"
+#include "config.h"
using namespace Genode;
using namespace Cpu;
@@ -37,6 +38,9 @@ Cpu::Session::create_thread(Pd_session_capability const pd,
throw Out_of_caps();
}
+ /* read in potential existing policy for thread */
+ Cpu::Config::apply_for_thread(_config.xml(), *this, name);
+
lookup(name, [&](Thread_capability &store_cap,
Cpu::Policy &policy)
{
@@ -126,13 +130,13 @@ Dataspace_capability Cpu::Session::trace_control()
return _parent.trace_control();
}
-Cpu::Session::Session(Env &env,
- Affinity const &affinity,
- char const * args,
- Child_list &list, bool const verbose)
+Cpu::Session::Session(Env &env, Affinity const &affinity, char const * args,
+ Child_list &list, Attached_rom_dataspace &config,
+ bool const verbose)
:
_list(list),
_env(env),
+ _config(config),
_ram_guard(ram_quota_from_args(args)),
_cap_guard(cap_quota_from_args(args)),
_parent(_env.session(_id.id(), _withdraw_quota(args), affinity)),
@@ -141,6 +145,17 @@ Cpu::Session::Session(Env &env,
_verbose(verbose)
{
try {
+ /* warm up the heap, we need space for at least one thread object */
+ construct(_default_policy, [&](Thread_capability &, Name &,
+ Cpu::Policy &) {});
+
+ _threads.for_each([&](Thread_client &thread) {
+ if (thread._policy)
+ destroy(_md_alloc, thread._policy);
+ destroy(_md_alloc, &thread);
+ });
+
+ /* finally, make object available via rpc */
_env.ep().rpc_ep().manage(this);
} catch (...) {
env.close(_id.id());
@@ -209,7 +224,7 @@ bool Cpu::Session::report_state(Xml_generator &xml) const
return _report;
}
-void Cpu::Session::config(Thread::Name const &thread,
+void Cpu::Session::update(Thread::Name const &thread,
Cpu::Policy::Name const &policy_name,
Affinity::Location const &relativ)
{
@@ -227,3 +242,27 @@ void Cpu::Session::config(Thread::Name const &thread,
_report = true;
}
+
+void Cpu::Session::update_if_active(Thread::Name const &thread,
+ Cpu::Policy::Name const &policy_name,
+ Affinity::Location const &location)
+{
+ /*
+ * Policies for existing threads are updated.
+ */
+ bool found = reconstruct_if_active(policy_name, thread,
+ [&](Thread_capability const &,
+ Cpu::Policy &policy)
+ {
+ policy.config(location);
+
+ if (_verbose) {
+ String<12> const loc { policy.location.xpos(), "x", policy.location.ypos() };
+ log("[", _label, "] name='", thread, "' "
+ "update policy to '", policy, "' ", loc);
+ }
+ });
+
+ if (found)
+ _report = true;
+}
diff --git a/repos/os/src/server/cpu_balancer/session.h b/repos/os/src/server/cpu_balancer/session.h
index 48c1c3dd33..27f6847d9a 100644
--- a/repos/os/src/server/cpu_balancer/session.h
+++ b/repos/os/src/server/cpu_balancer/session.h
@@ -15,6 +15,7 @@
#define _SESSION_H_
/* Genode includes */
+#include
#include
#include
#include
@@ -53,8 +54,9 @@ class Cpu::Session : public Rpc_object
{
private:
- Child_list &_list;
- Env &_env;
+ Child_list &_list;
+ Env &_env;
+ Attached_rom_dataspace &_config;
Ram_quota_guard _ram_guard;
Cap_quota_guard _cap_guard;
@@ -195,12 +197,12 @@ class Cpu::Session : public Rpc_object
}
template
- void reconstruct(Cpu::Policy::Name const &policy_name,
- Thread::Name const &thread_name,
- FUNC const &fn)
+ bool reconstruct_if_active(Cpu::Policy::Name const &policy_name,
+ Thread::Name const &thread_name,
+ FUNC const &fn)
{
if (!thread_name.valid())
- return;
+ return false;
bool done = false;
@@ -227,7 +229,18 @@ class Cpu::Session : public Rpc_object
return true;
});
- if (done)
+ return done;
+ }
+
+ template
+ void reconstruct(Cpu::Policy::Name const &policy_name,
+ Thread::Name const &thread_name,
+ FUNC const &fn)
+ {
+ if (!thread_name.valid())
+ return;
+
+ if (reconstruct_if_active(policy_name, thread_name, fn))
return;
construct(policy_name, [&](Thread_capability const &cap,
@@ -317,7 +330,8 @@ class Cpu::Session : public Rpc_object
public:
- Session(Env &, Affinity const &, char const *, Child_list &, bool);
+ Session(Env &, Affinity const &, char const *, Child_list &,
+ Attached_rom_dataspace &, bool);
~Session();
/***************************
@@ -341,8 +355,12 @@ class Cpu::Session : public Rpc_object
** internal interface **
************************/
bool match(Label const &label) const { return _label == label; };
- void config(Thread::Name const &, Cpu::Policy::Name const &,
+
+ void update(Thread::Name const &, Cpu::Policy::Name const &,
Affinity::Location const &);
+ void update_if_active(Thread::Name const &, Cpu::Policy::Name const &,
+ Affinity::Location const &);
+
void update_threads();
void update_threads(Trace &, Session_label const &);
bool report_state(Xml_generator &) const;