diff --git a/repos/base-codezero/src/core/include/platform_thread.h b/repos/base-codezero/src/core/include/platform_thread.h index 8651bd013..ae2e8c386 100644 --- a/repos/base-codezero/src/core/include/platform_thread.h +++ b/repos/base-codezero/src/core/include/platform_thread.h @@ -139,7 +139,7 @@ namespace Genode { /** * Get the executing CPU for this thread */ - Affinity::Location affinity() { return Affinity::Location(); } + Affinity::Location affinity() const { return Affinity::Location(); } /** * Get thread name @@ -157,6 +157,11 @@ namespace Genode { * Set CPU quota of the thread to 'quota' */ void quota(size_t const quota) { /* not supported*/ } + + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } }; } diff --git a/repos/base-fiasco/src/core/include/platform_thread.h b/repos/base-fiasco/src/core/include/platform_thread.h index 8f6fb54eb..e134ec9ae 100644 --- a/repos/base-fiasco/src/core/include/platform_thread.h +++ b/repos/base-fiasco/src/core/include/platform_thread.h @@ -126,7 +126,7 @@ namespace Genode { /** * Request the affinity of this thread */ - Affinity::Location affinity() { return Affinity::Location(); } + Affinity::Location affinity() const { return Affinity::Location(); } /** * Return the address space to which the thread is bound @@ -155,6 +155,11 @@ namespace Genode { */ void quota(size_t const quota) { /* not supported*/ } + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } + /******************************* ** Fiasco-specific Accessors ** diff --git a/repos/base-foc/src/core/include/cpu_session_component.h b/repos/base-foc/src/core/include/cpu_session_component.h index 2852b58ef..7661c0134 100644 --- a/repos/base-foc/src/core/include/cpu_session_component.h +++ b/repos/base-foc/src/core/include/cpu_session_component.h @@ -46,7 +46,8 @@ namespace Genode { class Cpu_thread_component : public Rpc_object, - public List::Element + public List::Element, + public Trace::Source::Info_accessor { public: @@ -55,6 +56,7 @@ namespace Genode { private: + Session_label const _session_label; Thread_name const _name; Platform_thread _platform_thread; bool _bound; /* pd binding flag */ @@ -73,15 +75,27 @@ namespace Genode { unsigned trace_control_index, Trace::Control &trace_control) : - _name(name), + _session_label(label), _name(name), _platform_thread(name.string(), priority, utcb), _bound(false), _sigh(sigh), _trace_control_index(trace_control_index), - _trace_source(label, _name, trace_control) + _trace_source(*this, trace_control) { update_exception_sigh(); } + /******************************************** + ** Trace::Source::Info_accessor interface ** + ********************************************/ + + Trace::Source::Info trace_source_info() const + { + return { _session_label, _name, + _platform_thread.execution_time(), + _platform_thread.affinity() }; + } + + /************************ ** Accessor functions ** ************************/ @@ -228,7 +242,7 @@ namespace Genode { Dataspace_capability trace_buffer(Thread_capability); Dataspace_capability trace_policy(Thread_capability); int ref_account(Cpu_session_capability c); - int transfer_quota(Cpu_session_capability c, size_t q); + int transfer_quota(Cpu_session_capability, size_t); Quota quota() override; diff --git a/repos/base-foc/src/core/include/platform_thread.h b/repos/base-foc/src/core/include/platform_thread.h index 1e94e559b..fe4da4fdc 100644 --- a/repos/base-foc/src/core/include/platform_thread.h +++ b/repos/base-foc/src/core/include/platform_thread.h @@ -143,7 +143,7 @@ namespace Genode { /** * Get the executing CPU for this thread */ - Affinity::Location affinity(); + Affinity::Location affinity() const; /** * Return the address space to which the thread is bound @@ -172,6 +172,11 @@ namespace Genode { */ void quota(size_t const quota) { /* not supported*/ } + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } + /******************************* ** Fiasco-specific Accessors ** diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index 151104122..320173b85 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -213,7 +213,7 @@ void Platform_thread::affinity(Affinity::Location location) } -Affinity::Location Platform_thread::affinity() +Affinity::Location Platform_thread::affinity() const { return _location; } diff --git a/repos/base-hw/src/core/include/platform_thread.h b/repos/base-hw/src/core/include/platform_thread.h index 5dbb89c40..cc72cfa0a 100644 --- a/repos/base-hw/src/core/include/platform_thread.h +++ b/repos/base-hw/src/core/include/platform_thread.h @@ -178,6 +178,11 @@ namespace Genode { */ Weak_ptr address_space(); + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } + /*************** ** Accessors ** diff --git a/repos/base-linux/src/core/include/cpu_session_component.h b/repos/base-linux/src/core/include/cpu_session_component.h index 266c788e5..f3dfe8bfb 100644 --- a/repos/base-linux/src/core/include/cpu_session_component.h +++ b/repos/base-linux/src/core/include/cpu_session_component.h @@ -45,7 +45,8 @@ namespace Genode { class Cpu_thread_component : public Rpc_object, - public List::Element + public List::Element, + public Trace::Source::Info_accessor { public: @@ -54,6 +55,7 @@ namespace Genode { private: + Session_label const _session_label; Thread_name const _name; Platform_thread _platform_thread; bool _bound; /* pd binding flag */ @@ -72,15 +74,27 @@ namespace Genode { unsigned trace_control_index, Trace::Control &trace_control) : - _name(name), + _session_label(label), _name(name), _platform_thread(name.string(), priority, utcb), _bound(false), _sigh(sigh), _trace_control_index(trace_control_index), - _trace_source(label, _name, trace_control) + _trace_source(*this, trace_control) { update_exception_sigh(); } + /******************************************** + ** Trace::Source::Info_accessor interface ** + ********************************************/ + + Trace::Source::Info trace_source_info() const + { + return { _session_label, _name, + _platform_thread.execution_time(), + _platform_thread.affinity() }; + } + + /************************ ** Accessor functions ** ************************/ @@ -218,7 +232,7 @@ namespace Genode { Dataspace_capability trace_buffer(Thread_capability); Dataspace_capability trace_policy(Thread_capability); int ref_account(Cpu_session_capability c); - int transfer_quota(Cpu_session_capability c, size_t q); + int transfer_quota(Cpu_session_capability, size_t); Quota quota() override; diff --git a/repos/base-linux/src/core/include/platform_thread.h b/repos/base-linux/src/core/include/platform_thread.h index 71257d964..0a45b6605 100644 --- a/repos/base-linux/src/core/include/platform_thread.h +++ b/repos/base-linux/src/core/include/platform_thread.h @@ -126,7 +126,7 @@ namespace Genode { /** * Request the affinity of this thread */ - Affinity::Location affinity() { return Affinity::Location(); } + Affinity::Location affinity() const { return Affinity::Location(); } /** * Register process ID and thread ID of thread @@ -158,6 +158,11 @@ namespace Genode { * Set CPU quota of the thread to 'quota' */ void quota(size_t const quota) { /* not supported*/ } + + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } }; } diff --git a/repos/base-nova/src/core/include/cpu_session_component.h b/repos/base-nova/src/core/include/cpu_session_component.h index df888df19..1bdc0189b 100644 --- a/repos/base-nova/src/core/include/cpu_session_component.h +++ b/repos/base-nova/src/core/include/cpu_session_component.h @@ -46,7 +46,8 @@ namespace Genode { class Cpu_thread_component : public Rpc_object, - public List::Element + public List::Element, + public Trace::Source::Info_accessor { public: @@ -55,6 +56,7 @@ namespace Genode { private: + Session_label const _session_label; Thread_name const _name; Platform_thread _platform_thread; bool _bound; /* pd binding flag */ @@ -73,15 +75,27 @@ namespace Genode { unsigned trace_control_index, Trace::Control &trace_control) : - _name(name), + _session_label(label), _name(name), _platform_thread(name.string(), priority, utcb), _bound(false), _sigh(sigh), _trace_control_index(trace_control_index), - _trace_source(label, _name, trace_control) + _trace_source(*this, trace_control) { update_exception_sigh(); } + /******************************************** + ** Trace::Source::Info_accessor interface ** + ********************************************/ + + Trace::Source::Info trace_source_info() const + { + return { _session_label, _name, + _platform_thread.execution_time(), + _platform_thread.affinity() }; + } + + /************************ ** Accessor functions ** ************************/ @@ -142,6 +156,10 @@ namespace Genode { Trace::Source_registry &_trace_sources; Trace::Control_area _trace_control_area; + /* + * Members for quota accounting + */ + size_t _weight; size_t _quota; Cpu_session_component * _ref; @@ -226,7 +244,7 @@ namespace Genode { Dataspace_capability trace_buffer(Thread_capability); Dataspace_capability trace_policy(Thread_capability); int ref_account(Cpu_session_capability c); - int transfer_quota(Cpu_session_capability c, size_t q); + int transfer_quota(Cpu_session_capability, size_t); Quota quota() override; diff --git a/repos/base-nova/src/core/include/platform_thread.h b/repos/base-nova/src/core/include/platform_thread.h index 9bf58d9ae..cc8763a6c 100644 --- a/repos/base-nova/src/core/include/platform_thread.h +++ b/repos/base-nova/src/core/include/platform_thread.h @@ -146,7 +146,7 @@ namespace Genode { /** * Get the executing CPU for this thread */ - Affinity::Location affinity(); + Affinity::Location affinity() const; /** * Get thread name @@ -169,6 +169,11 @@ namespace Genode { * Set CPU quota of the thread to 'quota' */ void quota(size_t const quota) { /* not supported*/ } + + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const; }; } diff --git a/repos/base-nova/src/core/platform_thread.cc b/repos/base-nova/src/core/platform_thread.cc index e48a126a2..bd5b8ecb6 100644 --- a/repos/base-nova/src/core/platform_thread.cc +++ b/repos/base-nova/src/core/platform_thread.cc @@ -45,7 +45,7 @@ void Platform_thread::affinity(Affinity::Location location) } -Affinity::Location Platform_thread::affinity() { return _location; } +Affinity::Location Platform_thread::affinity() const { return _location; } int Platform_thread::start(void *ip, void *sp) @@ -295,6 +295,21 @@ Weak_ptr Platform_thread::address_space() } +unsigned long long Platform_thread::execution_time() const +{ + unsigned long long time = 0; + + /* + * Ignore the return value, which indicates success only for global ECs. + * For local ECs, we simply return 0 as local ECs are executed with the + * time of their callers. + */ + (void) Nova::sc_ctrl(_sel_sc(), time); + + return time; +} + + Platform_thread::Platform_thread(const char *name, unsigned prio, int thread_id) : _pd(0), _pager(0), _id_base(cap_map()->insert(1)), diff --git a/repos/base-okl4/src/core/include/platform_thread.h b/repos/base-okl4/src/core/include/platform_thread.h index ff386d734..4762f94f1 100644 --- a/repos/base-okl4/src/core/include/platform_thread.h +++ b/repos/base-okl4/src/core/include/platform_thread.h @@ -145,13 +145,18 @@ namespace Genode { /** * Request the affinity of this thread */ - Affinity::Location affinity() { return Affinity::Location(); } + Affinity::Location affinity() const { return Affinity::Location(); } /** * Set CPU quota of the thread */ void quota(size_t) { /* not supported */ } + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } + /***************************** ** OKL4-specific Accessors ** diff --git a/repos/base-pistachio/src/core/include/platform_thread.h b/repos/base-pistachio/src/core/include/platform_thread.h index e5b78672b..1632cda63 100644 --- a/repos/base-pistachio/src/core/include/platform_thread.h +++ b/repos/base-pistachio/src/core/include/platform_thread.h @@ -146,13 +146,18 @@ namespace Genode { /** * Request the affinity of this thread */ - Affinity::Location affinity(); + Affinity::Location affinity() const; /** * Set CPU quota of the thread to 'quota' */ void quota(size_t const quota) { /* not supported*/ } + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } + /********************************** ** Pistachio-specific Accessors ** diff --git a/repos/base-pistachio/src/core/platform_thread.cc b/repos/base-pistachio/src/core/platform_thread.cc index 3274e5d35..e0b75699b 100644 --- a/repos/base-pistachio/src/core/platform_thread.cc +++ b/repos/base-pistachio/src/core/platform_thread.cc @@ -56,7 +56,7 @@ void Platform_thread::affinity(Affinity::Location location) } -Affinity::Location Platform_thread::affinity() +Affinity::Location Platform_thread::affinity() const { return _location; } diff --git a/repos/base-sel4/src/core/include/platform_thread.h b/repos/base-sel4/src/core/include/platform_thread.h index 00ff3fecd..cd57e0763 100644 --- a/repos/base-sel4/src/core/include/platform_thread.h +++ b/repos/base-sel4/src/core/include/platform_thread.h @@ -126,6 +126,11 @@ class Genode::Platform_thread : public List::Element */ Weak_ptr address_space(); + /** + * Return execution time consumed by the thread + */ + unsigned long long execution_time() const { return 0; } + /************************ ** Accessor functions ** @@ -151,7 +156,7 @@ class Genode::Platform_thread : public List::Element /** * Get the executing CPU for this thread */ - Affinity::Location affinity() { return Affinity::Location(); } + Affinity::Location affinity() const { return Affinity::Location(); } /** * Set CPU quota of the thread diff --git a/repos/base/include/base/trace/types.h b/repos/base/include/base/trace/types.h index c11080223..ec7c15ab3 100644 --- a/repos/base/include/base/trace/types.h +++ b/repos/base/include/base/trace/types.h @@ -9,6 +9,7 @@ /* Genode includes */ #include +#include namespace Genode { namespace Trace { @@ -26,10 +27,11 @@ namespace Genode { namespace Trace { struct Subject_not_traced : Exception { }; typedef String<160> Session_label; - typedef String<64> Thread_name; + typedef String<32> Thread_name; struct Policy_id; struct Subject_id; + struct Execution_time; struct Subject_info; } } @@ -62,6 +64,20 @@ struct Genode::Trace::Subject_id }; +/** + * Execution time of trace subject + * + * The value is kernel specific. + */ +struct Genode::Trace::Execution_time +{ + unsigned long long value; + + Execution_time() : value(0) { } + Execution_time(unsigned long long value) : value(value) { } +}; + + /** * Subject information */ @@ -86,10 +102,12 @@ class Genode::Trace::Subject_info private: - Session_label _session_label; - Thread_name _thread_name; - State _state; - Policy_id _policy_id; + Session_label _session_label; + Thread_name _thread_name; + State _state; + Policy_id _policy_id; + Execution_time _execution_time; + Affinity::Location _affinity; public: @@ -97,16 +115,21 @@ class Genode::Trace::Subject_info Subject_info(Session_label const &session_label, Thread_name const &thread_name, - State state, Policy_id policy_id) + State state, Policy_id policy_id, + Execution_time execution_time, + Affinity::Location affinity) : _session_label(session_label), _thread_name(thread_name), - _state(state), _policy_id(policy_id) + _state(state), _policy_id(policy_id), + _execution_time(execution_time), _affinity(affinity) { } - Session_label const &session_label() const { return _session_label; } - Thread_name const &thread_name() const { return _thread_name; } - State state() const { return _state; } - Policy_id policy_id() const { return _policy_id; } + Session_label const &session_label() const { return _session_label; } + Thread_name const &thread_name() const { return _thread_name; } + State state() const { return _state; } + Policy_id policy_id() const { return _policy_id; } + Execution_time execution_time() const { return _execution_time; } + Affinity::Location affinity() const { return _affinity; } }; #endif /* _INCLUDE__BASE__TRACE__TYPES_H_ */ diff --git a/repos/base/src/core/include/cpu_session_component.h b/repos/base/src/core/include/cpu_session_component.h index b9bd5e4da..82d808353 100644 --- a/repos/base/src/core/include/cpu_session_component.h +++ b/repos/base/src/core/include/cpu_session_component.h @@ -44,7 +44,8 @@ namespace Genode { class Cpu_thread_component : public Rpc_object, - public List::Element + public List::Element, + public Trace::Source::Info_accessor { public: @@ -54,6 +55,7 @@ namespace Genode { private: size_t const _weight; + Session_label const _session_label; Thread_name const _name; Platform_thread _platform_thread; bool _bound; /* pd binding flag */ @@ -83,16 +85,29 @@ namespace Genode { unsigned trace_control_index, Trace::Control &trace_control) : - _weight(weight), _name(name), + _weight(weight), + _session_label(label), _name(name), _platform_thread(quota, name.string(), priority, utcb), _bound(false), _sigh(sigh), _trace_control_index(trace_control_index), - _trace_source(label, _name, trace_control) + _trace_source(*this, trace_control) { update_exception_sigh(); } + /******************************************** + ** Trace::Source::Info_accessor interface ** + ********************************************/ + + Trace::Source::Info trace_source_info() const + { + return { _session_label, _name, + _platform_thread.execution_time(), + _platform_thread.affinity() }; + } + + /************************ ** Accessor functions ** ************************/ diff --git a/repos/base/src/core/include/trace/source_registry.h b/repos/base/src/core/include/trace/source_registry.h index 2ebbfe0b3..a76505c93 100644 --- a/repos/base/src/core/include/trace/source_registry.h +++ b/repos/base/src/core/include/trace/source_registry.h @@ -43,25 +43,40 @@ class Genode::Trace::Source public Genode::Weak_object, public Genode::List::Element { + public: + + struct Info + { + Session_label label; + Thread_name name; + Execution_time execution_time; + Affinity::Location affinity; + }; + + /** + * Interface for querying trace-source information + */ + struct Info_accessor + { + virtual Info trace_source_info() const = 0; + }; + private: unsigned const _unique_id; - Session_label const &_label; - Thread_name const _name; + Info_accessor const &_info; Control &_control; Dataspace_capability _policy; Dataspace_capability _buffer; - Source_owner const *_owner; + Source_owner const *_owner = nullptr; static unsigned _alloc_unique_id(); public: - Source(Session_label const &label, Thread_name const &name, - Control &control) + Source(Info_accessor const &info, Control &control) : - _unique_id(_alloc_unique_id()), - _label(label), _name(name), _control(control), _owner(0) + _unique_id(_alloc_unique_id()), _info(info), _control(control) { } @@ -69,8 +84,7 @@ class Genode::Trace::Source ** Interface used by TRACE service ** *************************************/ - Session_label const &label() const { return _label; } - Thread_name const &name() const { return _name; } + Info const info() const { return _info.trace_source_info(); } void trace(Dataspace_capability policy, Dataspace_capability buffer) { @@ -153,8 +167,10 @@ class Genode::Trace::Source_registry void export_sources(TEST &test, INSERT &insert) { for (Source *s = _entries.first(); s; s = s->next()) - if (!test(s->unique_id())) - insert(s->unique_id(), s->weak_ptr(), s->label(), s->name()); + if (!test(s->unique_id())) { + Source::Info const info = s->info(); + insert(s->unique_id(), s->weak_ptr(), info.label, info.name); + } } }; diff --git a/repos/base/src/core/include/trace/subject_registry.h b/repos/base/src/core/include/trace/subject_registry.h index 3c4fb96e2..caafcb27f 100644 --- a/repos/base/src/core/include/trace/subject_registry.h +++ b/repos/base/src/core/include/trace/subject_registry.h @@ -236,7 +236,21 @@ class Genode::Trace::Subject Subject_info info() { - return Subject_info(_label, _name, _state(), _policy_id); + Execution_time execution_time; + Affinity::Location affinity; + + { + Locked_ptr source(_source); + + if (source.is_valid()) { + Trace::Source::Info const info = source->info(); + execution_time = info.execution_time; + affinity = info.affinity; + } + } + + return Subject_info(_label, _name, _state(), _policy_id, + execution_time, affinity); } Dataspace_capability buffer() const { return _buffer.dataspace(); } diff --git a/repos/os/src/test/trace/main.cc b/repos/os/src/test/trace/main.cc index 195d836fa..304f48249 100644 --- a/repos/os/src/test/trace/main.cc +++ b/repos/os/src/test/trace/main.cc @@ -184,12 +184,13 @@ int main(int argc, char **argv) for (size_t i = 0; i < num_subjects; i++) { Trace::Subject_info info = trace.subject_info(subjects[i]); - printf("ID:%d label:\"%s\" name:\"%s\" state:%s policy:%d\n", + printf("ID:%d label:\"%s\" name:\"%s\" state:%s policy:%d time:%lld\n", subjects[i].id, info.session_label().string(), info.thread_name().string(), state_name(info.state()), - info.policy_id().id); + info.policy_id().id, + info.execution_time().value); /* enable tracing */ if (!policy_set