diff --git a/repos/base/src/core/cpu_session_component.cc b/repos/base/src/core/cpu_session_component.cc index 7e05c113cd..e487029c78 100644 --- a/repos/base/src/core/cpu_session_component.cc +++ b/repos/base/src/core/cpu_session_component.cc @@ -384,11 +384,11 @@ size_t Cpu_session_component::_weight_to_quota(size_t const weight) const ** Trace::Source_registry ** ****************************/ -unsigned Core::Trace::Source::_alloc_unique_id() +Core::Trace::Source::Id Core::Trace::Source::_alloc_unique_id() { static Mutex lock; static unsigned cnt; Mutex::Guard guard(lock); - return cnt++; + return { cnt++ }; } diff --git a/repos/base/src/core/include/trace/root.h b/repos/base/src/core/include/trace/root.h index fd52cedd65..5818bbae11 100644 --- a/repos/base/src/core/include/trace/root.h +++ b/repos/base/src/core/include/trace/root.h @@ -38,7 +38,6 @@ class Core::Trace::Root : public Root_component<Session_component> { size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); size_t arg_buffer_size = Arg_string::find_arg(args, "arg_buffer_size").ulong_value(0); - unsigned parent_levels = (unsigned)Arg_string::find_arg(args, "parent_levels").ulong_value(0); if (arg_buffer_size > ram_quota) throw Insufficient_ram_quota(); @@ -49,7 +48,7 @@ class Core::Trace::Root : public Root_component<Session_component> session_label_from_args(args), session_diag_from_args(args), _ram, _local_rm, - arg_buffer_size, parent_levels, + arg_buffer_size, _sources, _policies); } diff --git a/repos/base/src/core/include/trace/session_component.h b/repos/base/src/core/include/trace/session_component.h index 9859c14941..451de90a4b 100644 --- a/repos/base/src/core/include/trace/session_component.h +++ b/repos/base/src/core/include/trace/session_component.h @@ -47,6 +47,17 @@ class Core::Trace::Session_component unsigned _policy_cnt { 0 }; Attached_ram_dataspace _argument_buffer; + /* + * Whenever a trace session is deliberately labeled as empty by the + * top-level init instance, the session is granted global reach. + * Otherwise, the label is taken a prefix filter for the visibility + * of trace subjects within the session. + */ + Filter _filter() const + { + return (_label == "init -> ") ? Filter("") : Filter(_label); + } + public: /** @@ -59,7 +70,6 @@ class Core::Trace::Session_component Ram_allocator &ram, Region_map &local_rm, size_t arg_buffer_size, - unsigned parent_levels, Source_registry &sources, Policy_registry &policies); diff --git a/repos/base/src/core/include/trace/source_registry.h b/repos/base/src/core/include/trace/source_registry.h index 8a5f1e3969..124f3cccd6 100644 --- a/repos/base/src/core/include/trace/source_registry.h +++ b/repos/base/src/core/include/trace/source_registry.h @@ -30,6 +30,8 @@ namespace Core { namespace Trace { using namespace Genode::Trace; + using Filter = String<Session_label::capacity()>; + class Source; class Source_owner; class Source_registry; @@ -71,16 +73,18 @@ class Core::Trace::Source virtual Info trace_source_info() const = 0; }; + struct Id { unsigned value; }; + private: - unsigned const _unique_id; + Id const _unique_id; Info_accessor const &_info; Control &_control; Dataspace_capability _policy { }; Dataspace_capability _buffer { }; Source_owner const *_owner_ptr = nullptr; - static unsigned _alloc_unique_id(); + static Id _alloc_unique_id(); /* * Noncopyable @@ -144,7 +148,7 @@ class Core::Trace::Source Dataspace_capability buffer() const { return _buffer; } Dataspace_capability policy() const { return _policy; } - unsigned unique_id() const { return _unique_id; } + Id id() const { return _unique_id; } }; @@ -184,16 +188,11 @@ class Core::Trace::Source_registry ** Interface used by TRACE service ** *************************************/ - template <typename TEST, typename INSERT> - void export_sources(TEST &test, INSERT &insert) + void for_each_source(auto const &fn) { for (Source *s = _entries.first(); s; s = s->next()) - if (!test(s->unique_id())) { - Source::Info const info = s->info(); - insert(s->unique_id(), s->weak_ptr(), info.label, info.name); - } + fn(*s); } - }; #endif /* _CORE__INCLUDE__TRACE__SOURCE_REGISTRY_H_ */ diff --git a/repos/base/src/core/include/trace/subject_registry.h b/repos/base/src/core/include/trace/subject_registry.h index e97284bfa5..ee7be41d26 100644 --- a/repos/base/src/core/include/trace/subject_registry.h +++ b/repos/base/src/core/include/trace/subject_registry.h @@ -137,7 +137,7 @@ class Core::Trace::Subject friend class Subject_registry; Subject_id const _id; - unsigned const _source_id; + Source::Id const _source_id; Weak_ptr<Source> _source; Session_label const _label; Thread_name const _name; @@ -184,7 +184,7 @@ class Core::Trace::Subject /** * Constructor, called from 'Subject_registry' only */ - Subject(Subject_id id, unsigned source_id, Weak_ptr<Source> &source, + Subject(Subject_id id, Source::Id source_id, Weak_ptr<Source> &source, Session_label const &label, Thread_name const &name) : _id(id), _source_id(source_id), _source(source), @@ -212,7 +212,7 @@ class Core::Trace::Subject /** * Test if subject belongs to the specified unique source ID */ - bool has_source_id(unsigned id) const { return id == _source_id; } + bool has_source_id(Source::Id id) const { return id.value == _source_id.value; } /** * Start tracing @@ -325,51 +325,11 @@ class Core::Trace::Subject_registry Allocator &_md_alloc; Source_registry &_sources; + Filter const _filter; unsigned _id_cnt { 0 }; Mutex _mutex { }; Subjects _entries { }; - /** - * Functor for testing the existance of subjects for a given source - * - * This functor is invoked by 'Source_registry::export'. - */ - struct Tester - { - Subjects &subjects; - - Tester(Subjects &subjects) : subjects(subjects) { } - - bool operator () (unsigned source_id) - { - for (Subject *s = subjects.first(); s; s = s->next()) - if (s->has_source_id(source_id)) - return true; - return false; - } - } _tester { _entries }; - - /** - * Functor for inserting new subjects into the registry - * - * This functor is invoked by 'Source_registry::export'. - */ - struct Inserter - { - Subject_registry ®istry; - - Inserter(Subject_registry ®istry) : registry(registry) { } - - void operator () (unsigned source_id, Weak_ptr<Source> source, - Session_label const &label, Thread_name const &name) - { - Subject *subject = new (®istry._md_alloc) - Subject(Subject_id(++registry._id_cnt), source_id, source, label, name); - - registry._entries.insert(subject); - } - } _inserter { *this }; - /** * Destroy subject, and release policy and trace buffers */ @@ -398,23 +358,11 @@ class Core::Trace::Subject_registry public: - /** - * Constructor - * - * \param md_alloc meta-data allocator used for allocating 'Subject' - * objects. - * \param ram allocator used for the allocation of trace - * buffers and policy dataspaces. - */ - Subject_registry(Allocator &md_alloc, - Source_registry &sources) + Subject_registry(Allocator &md_alloc, Source_registry &sources, Filter const &filter) : - _md_alloc(md_alloc), _sources(sources) + _md_alloc(md_alloc), _sources(sources), _filter(filter) { } - /** - * Destructor - */ ~Subject_registry() { Mutex::Guard guard(_mutex); @@ -430,7 +378,32 @@ class Core::Trace::Subject_registry { Mutex::Guard guard(_mutex); - _sources.export_sources(_tester, _inserter); + auto already_known = [&] (Source::Id const unique_id) + { + for (Subject *s = _entries.first(); s; s = s->next()) + if (s->has_source_id(unique_id)) + return true; + return false; + }; + + auto filter_matches = [&] (Session_label const &label) + { + return strcmp(_filter.string(), label.string(), _filter.length() - 1) == 0; + }; + + _sources.for_each_source([&] (Source &source) { + + Source::Info const info = source.info(); + + if (!filter_matches(info.label) || already_known(source.id())) + return; + + Weak_ptr<Source> source_ptr = source.weak_ptr(); + + _entries.insert(new (_md_alloc) + Subject(Subject_id(++_id_cnt), source.id(), + source_ptr, info.label, info.name)); + }); } /** @@ -453,12 +426,25 @@ class Core::Trace::Subject_registry { Mutex::Guard guard(_mutex); + auto filtered = [&] (Session_label const &label) -> Session_label + { + return (label.length() <= _filter.length() || !_filter.length()) + ? Session_label("") /* this cannot happen */ + : Session_label(label.string() + _filter.length() - 1); + }; + unsigned i = 0; for (Subject *s = _entries.first(); s && i < len; s = s->next()) { - ids[i] = s->id(); - dst[i++] = s->info(); - } + ids[i] = s->id(); + Subject_info const info = s->info(); + + /* strip filter prefix from reported trace-subject label */ + dst[i++] = { + filtered(info.session_label()), info.thread_name(), info.state(), + info.policy_id(), info.execution_time(), info.affinity() + }; + } return i; } diff --git a/repos/base/src/core/trace_session_component.cc b/repos/base/src/core/trace_session_component.cc index e46950cc66..919e45c45c 100644 --- a/repos/base/src/core/trace_session_component.cc +++ b/repos/base/src/core/trace_session_component.cc @@ -132,7 +132,6 @@ Session_component::Session_component(Rpc_entrypoint &ep, Ram_allocator &ram, Region_map &local_rm, size_t arg_buffer_size, - unsigned /* parent_levels */, Source_registry &sources, Policy_registry &policies) : @@ -143,7 +142,7 @@ Session_component::Session_component(Rpc_entrypoint &ep, _policies_slab(&_md_alloc), _sources(sources), _policies(policies), - _subjects(_subjects_slab, _sources), + _subjects(_subjects_slab, _sources, _filter()), _argument_buffer(_ram, local_rm, arg_buffer_size) { } diff --git a/repos/os/recipes/pkg/test-trace/runtime b/repos/os/recipes/pkg/test-trace/runtime index 81cb89108e..b46a8d65b4 100644 --- a/repos/os/recipes/pkg/test-trace/runtime +++ b/repos/os/recipes/pkg/test-trace/runtime @@ -28,6 +28,7 @@ <service name="Timer"/> </parent-provides> <default-route> + <service name="TRACE"> <parent label=""/> </service> <any-service> <parent/> <any-child/> </any-service> </default-route> <default caps="200"/> @@ -37,21 +38,21 @@ <start name="test-trace"> <resource name="RAM" quantum="10M"/> <config> - <trace_policy label="init -> dynamic -> test-trace -> sequence -> test-trace" thread="test-thread" module="null"/> + <trace_policy label="sequence -> test-trace" thread="test-thread" module="null"/> </config> </start> <start name="test-trace"> <resource name="RAM" quantum="10M"/> <config> - <trace_policy label="init -> dynamic -> test-trace -> top" thread="ep" module="null"/> + <trace_policy label="top" thread="ep" module="null"/> </config> </start> <start name="test-trace"> <resource name="RAM" quantum="10M"/> <config> - <trace_policy label="init -> dynamic -> test-trace -> top" thread="ep" module="null"/> + <trace_policy label="top" thread="ep" module="null"/> </config> </start> </config> diff --git a/repos/os/recipes/pkg/test-trace_logger/runtime b/repos/os/recipes/pkg/test-trace_logger/runtime index 51dbf17007..0eddfb62d3 100644 --- a/repos/os/recipes/pkg/test-trace_logger/runtime +++ b/repos/os/recipes/pkg/test-trace_logger/runtime @@ -5,11 +5,11 @@ <fail after_seconds="20"/> <succeed> [init -> trace_logger] Report * - [init -> trace_logger] PD "init -> dynamic -> test-trace_logger -> cpu_burner.*"* + [init -> trace_logger] PD "cpu_burner.*"* [init -> trace_logger] Thread "ep" at (0,0) TRACED total:* recent:* - [init -> trace_logger] PD "init -> dynamic -> test-trace_logger -> dynamic_rom"* + [init -> trace_logger] PD "dynamic_rom"* [init -> trace_logger] Thread "ep" at (0,0) TRACED total:* recent:* - [init -> trace_logger] PD "init -> dynamic -> test-trace_logger -> test-trace_logger"* + [init -> trace_logger] PD "test-trace_logger"* [init -> trace_logger] Thread "ep" at (0,0) TRACED total:* recent:* [init -> trace_logger] 100 * [init -> trace_logger] trigger_once @@ -49,12 +49,16 @@ <resource name="RAM" quantum="80M"/> <config verbose="yes" priority="no" sc_time="no" session_ram="10M" session_parent_levels="1" session_arg_buffer="64K" period_sec="3" default_policy="null" default_buffer="1K"> - <policy label_prefix="init -> dynamic -> test-trace_logger -> cpu_burner" thread="ep"/> + <policy label_prefix="cpu_burner" thread="ep"/> - <policy label="init -> dynamic -> test-trace_logger -> test-trace_logger" thread="ep" buffer="4K" policy="rpc_name"/> + <policy label="test-trace_logger" thread="ep" buffer="4K" policy="rpc_name"/> - <policy label="init -> dynamic -> test-trace_logger -> dynamic_rom" thread="ep" buffer="8K" policy="log_output"/> + <policy label="dynamic_rom" thread="ep" buffer="8K" policy="log_output"/> </config> + <route> + <service name="TRACE"> <parent label=""/> </service> + <any-service> <parent/> <any-child/> </any-service> + </route> </start> <start name="dynamic_rom">