diff --git a/repos/base-hw/src/test/cpu_quota/include/sync_session/capability.h b/repos/base-hw/src/test/cpu_quota/include/sync_session/capability.h deleted file mode 100644 index 15bc26766..000000000 --- a/repos/base-hw/src/test/cpu_quota/include/sync_session/capability.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * \brief Sync-session capability type - * \author Martin Stein - * \date 2015-04-07 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _SYNC_SESSION__CAPABILITY_H_ -#define _SYNC_SESSION__CAPABILITY_H_ - -/* Genode includes */ -#include - -/* local includes */ -#include - -namespace Sync -{ - using Genode::Capability; - - typedef Capability Session_capability; -} - -#endif /* _SYNC_SESSION__CAPABILITY_H_ */ diff --git a/repos/base-hw/src/test/cpu_quota/include/sync_session/client.h b/repos/base-hw/src/test/cpu_quota/include/sync_session/client.h deleted file mode 100644 index 17a6854e4..000000000 --- a/repos/base-hw/src/test/cpu_quota/include/sync_session/client.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * \brief Client-side Sync-session interface - * \author Martin Stein - * \date 2015-04-07 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _SYNC_SESSION__CLIENT_H_ -#define _SYNC_SESSION__CLIENT_H_ - -/* Genode includes */ -#include - -/* local includes */ -#include - -namespace Sync -{ - using Genode::Rpc_client; - - struct Session_client; -} - - -struct Sync::Session_client : Rpc_client -{ - explicit Session_client(Session_capability session) - : Rpc_client(session) { } - - void threshold(unsigned id, unsigned threshold) override { - call(id, threshold); } - - void submit(unsigned id, Signal_context_capability sigc) override { - call(id, sigc); } -}; - -#endif /* _SYNC_SESSION__CLIENT_H_ */ diff --git a/repos/base-hw/src/test/cpu_quota/include/sync_session/connection.h b/repos/base-hw/src/test/cpu_quota/include/sync_session/connection.h index 9cf58ef8c..da169fd47 100644 --- a/repos/base-hw/src/test/cpu_quota/include/sync_session/connection.h +++ b/repos/base-hw/src/test/cpu_quota/include/sync_session/connection.h @@ -16,45 +16,22 @@ /* Genode includes */ #include +#include /* local includes */ -#include +#include -namespace Sync +namespace Sync { class Connection; } + +struct Sync::Connection : public Genode::Connection, + public Genode::Rpc_client { - using Genode::Parent; + explicit Connection(Genode::Env &env) + : Genode::Connection(env, session("ram_quota=4K")), + Genode::Rpc_client(cap()) { } - class Connection; -} - - -class Sync::Connection : public Genode::Connection, - public Session_client -{ - public: - - class Connection_failed : public Parent::Exception { }; - - private: - - Session_capability _create_session() - { - try { return session("ram_quota=4K"); } - catch (...) { throw Connection_failed(); } - } - - public: - - /** - * Constructor - * - * \throw Connection_failed - */ - Connection() __attribute__((deprecated)) - : - Genode::Connection(_create_session()), - Session_client(cap()) - { } + void threshold(unsigned threshold) override { call(threshold); } + void submit(Signal_context_capability signal) override { call(signal); } }; #endif /* _SYNC_SESSION__CONNECTION_H_ */ diff --git a/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h b/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h index 25d4137fe..5500cfcb0 100644 --- a/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h +++ b/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h @@ -15,6 +15,7 @@ #define _SYNC_SESSION__SYNC_SESSION_H_ /* Genode includes */ +#include #include #include @@ -23,32 +24,20 @@ namespace Sync using Genode::Signal_context_capability; struct Session; + using Session_capability = Genode::Capability; } - struct Sync::Session : Genode::Session { static const char *service_name() { return "Sync"; } virtual ~Session() { } - /** - * Set the submission threshold of a synchronization signal - */ - virtual void threshold(unsigned id, unsigned threshold) = 0; + virtual void threshold(unsigned threshold) = 0; + virtual void submit(Signal_context_capability signal) = 0; - /** - * Submit to a synchronization signal - */ - virtual void submit(unsigned id, Signal_context_capability sigc) = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_threshold, void, threshold, unsigned, unsigned); - GENODE_RPC(Rpc_submit, void, submit, unsigned, Signal_context_capability); + GENODE_RPC(Rpc_threshold, void, threshold, unsigned); + GENODE_RPC(Rpc_submit, void, submit, Signal_context_capability); GENODE_RPC_INTERFACE(Rpc_threshold, Rpc_submit); }; diff --git a/repos/base-hw/src/test/cpu_quota/main.cc b/repos/base-hw/src/test/cpu_quota/main.cc index 5e014f6e5..4ba759612 100644 --- a/repos/base-hw/src/test/cpu_quota/main.cc +++ b/repos/base-hw/src/test/cpu_quota/main.cc @@ -12,166 +12,150 @@ */ /* Genode includes */ -#include #include +#include #include #include + +/* local includes */ #include using namespace Genode; -enum { SYNC_SIG = 0 }; - -namespace Sync { class Signal; } - -class Single_signal +struct Single_signal { - private: + Signal_receiver receiver; + Signal_context context; + Signal_context_capability cap; + Signal_transmitter transmitter; - Signal_receiver _sigr; - Signal_context _sigx; - Signal_context_capability _sigc; - Signal_transmitter _sigt; + Single_signal() : cap(receiver.manage(&context)), transmitter(cap) { } - public: - - Single_signal() : _sigc(_sigr.manage(&_sigx)), _sigt(_sigc) { } - - ~Single_signal() { _sigr.dissolve(&_sigx); } - - void receive() { _sigr.wait_for_signal(); } - - void submit() { _sigt.submit(); } - - operator Signal_context_capability() { return _sigc; } + ~Single_signal() { receiver.dissolve(&context); } + void receive() { receiver.wait_for_signal(); } + void submit() { transmitter.submit(); } }; -class Sync::Signal + +struct Synchronizer { - private: + Single_signal signal; + Sync::Session &session; - Signal_receiver _sigr; - Signal_context _sigx; - Signal_context_capability _sigc; - Session * const _session; - unsigned const _id; + Synchronizer(Sync::Session &session) : session(session) { } - public: + void threshold(unsigned threshold) { session.threshold(threshold); } - Signal(Session * const session, unsigned const id) - : _sigc(_sigr.manage(&_sigx)), _session(session), _id(id) { } - - ~Signal() { _sigr.dissolve(&_sigx); } - - void threshold(unsigned const threshold) { - _session->threshold(_id, threshold); } - - void sync() - { - _session->submit(_id, _sigc); - _sigr.wait_for_signal(); - } + void synchronize() + { + session.submit(signal.cap); + signal.receive(); + } }; -class Counter : private Thread_deprecated<2 * 1024 * sizeof(Genode::addr_t)> + +class Counter : public Thread { private: - String<64> _name; - unsigned long long volatile _value; - Sync::Signal _sync_sig; - unsigned volatile _stage; - Single_signal _stage_1_end; - Single_signal _stage_2_reached; + enum { STACK_SIZE = 2 * 1024 * sizeof(addr_t) }; - inline void _stage_0_and_1(unsigned long long volatile & value) - { - _stage_1_end.receive(); - _stage = 0; - _sync_sig.sync(); - while(_stage == 0) { value++; } - } + enum Stage { PAUSE, MEASUREMENT, DESTRUCTION }; + + Name const &_name; + unsigned long long volatile _value { 0 }; + Stage volatile _stage { PAUSE }; + Single_signal _start_measurement; + Single_signal _start_destruction; + Synchronizer _synchronizer; void entry() { unsigned long long volatile value = 0; - while (_stage < 2) { _stage_0_and_1(value); } + while (_stage == PAUSE) { + _start_measurement.receive(); + _stage = MEASUREMENT; + _synchronizer.synchronize(); + while (_stage == MEASUREMENT) { value++; } + } _value = value; - _stage_2_reached.submit(); - sleep_forever(); + _start_destruction.submit(); } public: - Counter(char const *name, size_t const weight, - Sync::Session * const sync) + Counter(Env &env, Name const &name, unsigned cpu_percent, Sync::Session &sync) : - Thread_deprecated(weight, "counter"), _name(name), _value(0) , - _sync_sig(sync, SYNC_SIG), _stage(1) - { - Thread::start(); - } + Thread(env, name, STACK_SIZE, Location(), + Weight(Cpu_session::quota_lim_upscale(cpu_percent, 100)), + env.cpu()), + _name(name), _synchronizer(sync) { start(); } void destruct() { - _stage = 2; - _stage_2_reached.receive(); + _stage = DESTRUCTION; + _start_destruction.receive(); this->~Counter(); } - void pause() { _stage = 1; } + void pause() { _stage = PAUSE; } + void measure() { _start_measurement.submit(); } - void go() { _stage_1_end.submit(); } - - void result() { log("counter ", _name, " ", _value); } + void print(Output &output) const { Genode::print(output, _name, " ", _value); } }; -void measure(Timer::Connection & timer, Single_signal & timer_sig, - Sync::Signal & sync_sig, unsigned const sec) +struct Main { - timer.trigger_once(sec * 1000 * 1000); - sync_sig.sync(); - timer_sig.receive(); -} + enum { DURATION_BASE_SEC = 20, + MEASUREMENT_1_NR_OF_THREADS = 9, + MEASUREMENT_2_NR_OF_THREADS = 6, + CONCLUSION_NR_OF_THREADS = 3, }; + + Env &env; + Single_signal timer_signal; + Timer::Connection timer { env }; + Sync::Connection sync { env }; + Synchronizer synchronizer { sync }; + Counter::Name const name_a { "counter A" }; + Counter::Name const name_b { "counter B" }; + Counter counter_a { env, name_a, 10, sync }; + Counter counter_b { env, name_b, 90, sync }; + + Main(Env &env) : env(env) + { + timer.sigh(timer_signal.cap); + + auto measure = [&] (unsigned duration_sec) { + timer.trigger_once(duration_sec * 1000 * 1000); + synchronizer.synchronize(); + timer_signal.receive(); + }; + /* measurement 1 */ + synchronizer.threshold(MEASUREMENT_1_NR_OF_THREADS); + counter_a.measure(); + counter_b.measure(); + measure(3 * DURATION_BASE_SEC); + counter_a.pause(); + counter_b.destruct(); + + /* measurement 2 */ + synchronizer.threshold(MEASUREMENT_2_NR_OF_THREADS); + counter_a.measure(); + measure(DURATION_BASE_SEC); + counter_a.destruct(); + + /* conclusion */ + synchronizer.threshold(CONCLUSION_NR_OF_THREADS); + synchronizer.synchronize(); + Cpu_session::Quota quota = env.cpu().quota(); + log("quota super period ", quota.super_period_us); + log("quota ", quota.us); + log(counter_a); + log(counter_b); + log("done"); + } +}; -int main() -{ - enum { DURATION_BASE_SEC = 20 }; - - /* prepare */ - Single_signal timer_sig; - Timer::Connection timer; - Sync::Connection sync; - Sync::Signal sync_sig(&sync, SYNC_SIG); - Counter counter_a("A", Cpu_session::quota_lim_upscale(10, 100), &sync); - Counter counter_b("B", Cpu_session::quota_lim_upscale(90, 100), &sync); - - timer.sigh(timer_sig); - - /* measure stage 1 */ - sync_sig.threshold(9); - counter_a.go(); - counter_b.go(); - measure(timer, timer_sig, sync_sig, 3 * DURATION_BASE_SEC); - counter_a.pause(); - counter_b.destruct(); - - /* measure stage 2 */ - sync_sig.threshold(6); - counter_a.go(); - measure(timer, timer_sig, sync_sig, DURATION_BASE_SEC); - counter_a.destruct(); - - /* print results */ - sync_sig.threshold(3); - sync_sig.sync(); - Cpu_session::Quota quota = Genode::env()->cpu_session()->quota(); - log("quota super period ", quota.super_period_us); - log("quota ", quota.us); - counter_a.result(); - counter_b.result(); - log("done"); - sleep_forever(); -} +void Component::construct(Env &env) { static Main main(env); } diff --git a/repos/base-hw/src/test/cpu_quota/sync/main.cc b/repos/base-hw/src/test/cpu_quota/sync/main.cc index ae0417d1d..f8ef44e8d 100644 --- a/repos/base-hw/src/test/cpu_quota/sync/main.cc +++ b/repos/base-hw/src/test/cpu_quota/sync/main.cc @@ -14,139 +14,76 @@ /* Genode includes */ #include #include +#include +#include /* local includes */ #include -namespace Sync +using namespace Genode; + +class Sync_root; + + +struct Session_component : public Rpc_object { - enum { NR_OF_SIGNALS = 1 }; + Sync_root &root; - using Server::Entrypoint; - using Genode::Rpc_object; - using Genode::env; - using Genode::Root_component; - using Genode::Allocator; - using Genode::Signal_transmitter; + Session_component(Sync_root &root) : root(root) { } - class Signal; - class Session_component; - class Root; - struct Main; + void threshold(unsigned threshold) override; + void submit(Signal_context_capability signal) override; +}; + + +struct Sync_root : public Root_component +{ + Signal_transmitter transmitters[9]; + unsigned submitted { 0 }; + unsigned threshold { 0 }; + + void check() + { + if (submitted < threshold) { return; } + for (unsigned i = 0; i < submitted; i++) { + transmitters[i].submit(); } + submitted = 0; + } + + Session_component *_create_session(char const *args) override + { + try { return new (md_alloc()) Session_component(*this); } + catch (...) { throw Root::Exception(); } + } + + Sync_root(Entrypoint &ep, Allocator &md_alloc) + : Root_component(ep, md_alloc) { } +}; + + +void Session_component::threshold(unsigned threshold) +{ + root.threshold = threshold; + root.check(); } -class Sync::Signal + +void Session_component::submit(Signal_context_capability signal) { - friend class Root; - - private: - - enum { NR_OF_TRANSMITTERS = 9 }; - - Signal_transmitter _transmitters[NR_OF_TRANSMITTERS]; - unsigned _submitted; - unsigned _threshold; - - void _check() - { - if (_submitted < _threshold) { return; } - for (unsigned i = 0; i < _submitted; i++) { - _transmitters[i].submit(); } - _submitted = 0; - } - - void _reset() - { - _submitted = 0; - _threshold = 0; - } - - public: - - void threshold(unsigned const threshold) - { - _threshold = threshold; - _check(); - } - - void submit(Signal_context_capability & sigc) - { - _transmitters[_submitted] = Signal_transmitter(sigc); - _submitted++; - _check(); - } -}; - -class Sync::Session_component : public Rpc_object -{ - private: - - Signal * const _signals; - - public: - - Session_component(Signal * const signals) : _signals(signals) { } - - void threshold(unsigned id, unsigned threshold) override - { - if (id >= NR_OF_SIGNALS) { return; } - _signals[id].threshold(threshold); - } - - void - submit(unsigned const id, Signal_context_capability sigc) override - { - if (id >= NR_OF_SIGNALS) { return; } - _signals[id].submit(sigc); - } -}; - -class Sync::Root : public Root_component -{ - private: - - Signal _signals[NR_OF_SIGNALS]; - - protected: - - Session_component *_create_session(const char *args) - { - try { return new (md_alloc()) Session_component(_signals); } - catch (...) { throw Root::Exception(); } - } - - public: - - Root(Entrypoint & ep, Allocator & md_alloc) - : Root_component(&ep.rpc_ep(), &md_alloc) - { - for (unsigned i = 0; i < NR_OF_SIGNALS; i++) { - _signals[i]._reset(); } - } -}; - -struct Sync::Main -{ - Server::Entrypoint & ep; - - Root root; - - Main(Server::Entrypoint & ep) : ep(ep), root(ep, *env()->heap()) { - env()->parent()->announce(ep.manage(root)); } -}; - - -/************ - ** Server ** - ************/ - -namespace Server -{ - using namespace Sync; - - char const *name() { return "sync_ep"; } - - size_t stack_size() { return 16*1024*sizeof(long); } - - void construct(Entrypoint & ep) { static Main main(ep); } + root.transmitters[root.submitted] = Signal_transmitter(signal); + root.submitted++; + root.check(); } + + +struct Main +{ + Env &env; + Heap heap { env.ram(), env.rm() }; + Sync_root root { env.ep(), heap }; + + Main(Env &env) : env(env) { env.parent().announce(env.ep().manage(root)); } +}; + + +void Component::construct(Env &env) { static Main main(env); } diff --git a/repos/base-hw/src/test/cpu_quota/sync/target.mk b/repos/base-hw/src/test/cpu_quota/sync/target.mk index eba2684db..ecb9731c4 100644 --- a/repos/base-hw/src/test/cpu_quota/sync/target.mk +++ b/repos/base-hw/src/test/cpu_quota/sync/target.mk @@ -1,17 +1,4 @@ -# -# \brief Provide cross-component synchronization -# \author Martin Stein -# \date 2014-10-13 -# - -# Set program name -TARGET = test-sync - -# Add C++ sources -SRC_CC = main.cc - -# Add include paths +TARGET = test-sync +SRC_CC += main.cc INC_DIR += $(PRG_DIR)/../include - -# Add libraries -LIBS = base server +LIBS += base diff --git a/repos/base-hw/src/test/cpu_quota/target.mk b/repos/base-hw/src/test/cpu_quota/target.mk index 2033599ff..1f3c91f70 100644 --- a/repos/base-hw/src/test/cpu_quota/target.mk +++ b/repos/base-hw/src/test/cpu_quota/target.mk @@ -1,17 +1,4 @@ -# -# \brief Test the distribution and application of CPU quota -# \author Martin Stein -# \date 2014-10-13 -# - -# Set program name -TARGET = test-cpu_quota - -# Add C++ sources -SRC_CC += main.cc - -# Add include paths +TARGET = test-cpu_quota +SRC_CC += main.cc INC_DIR += $(PRG_DIR)/include - -# Add libraries -LIBS += base +LIBS += base