From 1a94338389f233870bea0d6d0665b207fa63fab6 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 16 Jan 2020 18:00:30 +0100 Subject: [PATCH] trace: support to request subject infos batched Optimize requesting the Subject_infos from O(n) to O(1) RPC call. Issue #3610 --- repos/base/include/trace_session/client.h | 16 ++++++++++++++++ repos/base/include/trace_session/trace_session.h | 4 +++- .../src/core/include/trace/session_component.h | 1 + .../src/core/include/trace/subject_registry.h | 16 ++++++++++++++++ repos/base/src/core/trace_session_component.cc | 12 ++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/repos/base/include/trace_session/client.h b/repos/base/include/trace_session/client.h index 8d2ca33c3..ac61e0439 100644 --- a/repos/base/include/trace_session/client.h +++ b/repos/base/include/trace_session/client.h @@ -86,6 +86,22 @@ struct Genode::Trace::Session_client : Genode::Rpc_client + size_t for_each_subject_info(FN const &fn) + { + size_t const num_subjects = call(); + size_t const max_subjects = _argument_buffer.size / (sizeof(Subject_info) + sizeof(Subject_id)); + + Subject_info * const infos = reinterpret_cast(_argument_buffer.base); + Subject_id * const ids = reinterpret_cast(infos + max_subjects); + + for (unsigned i = 0; i < num_subjects; i++) { + fn(ids[i], infos[i]); + } + + return num_subjects; + } + Policy_id alloc_policy(size_t size) override { return call(size); } diff --git a/repos/base/include/trace_session/trace_session.h b/repos/base/include/trace_session/trace_session.h index 929f2cf7f..0db6d3c9f 100644 --- a/repos/base/include/trace_session/trace_session.h +++ b/repos/base/include/trace_session/trace_session.h @@ -142,6 +142,8 @@ struct Genode::Trace::Session : Genode::Session Subject_id); GENODE_RPC_THROW(Rpc_subjects, size_t, subjects, GENODE_TYPE_LIST(Out_of_ram, Out_of_caps)); + GENODE_RPC_THROW(Rpc_subject_infos, size_t, subject_infos, + GENODE_TYPE_LIST(Out_of_ram, Out_of_caps)); GENODE_RPC_THROW(Rpc_subject_info, Subject_info, subject_info, GENODE_TYPE_LIST(Nonexistent_subject), Subject_id); GENODE_RPC_THROW(Rpc_buffer, Dataspace_capability, buffer, @@ -153,7 +155,7 @@ struct Genode::Trace::Session : Genode::Session GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_alloc_policy, Rpc_policy, Rpc_unload_policy, Rpc_trace, Rpc_rule, Rpc_pause, Rpc_resume, Rpc_subjects, Rpc_subject_info, Rpc_buffer, - Rpc_free); + Rpc_free, Rpc_subject_infos); }; #endif /* _INCLUDE__TRACE_SESSION__TRACE_SESSION_H_ */ diff --git a/repos/base/src/core/include/trace/session_component.h b/repos/base/src/core/include/trace/session_component.h index d0d5049e8..f6e2a376e 100644 --- a/repos/base/src/core/include/trace/session_component.h +++ b/repos/base/src/core/include/trace/session_component.h @@ -74,6 +74,7 @@ class Genode::Trace::Session_component Dataspace_capability dataspace(); size_t subjects(); + size_t subject_infos(); Policy_id alloc_policy(size_t) override; Dataspace_capability policy(Policy_id) override; diff --git a/repos/base/src/core/include/trace/subject_registry.h b/repos/base/src/core/include/trace/subject_registry.h index 6d7c0fb37..d708fd8e7 100644 --- a/repos/base/src/core/include/trace/subject_registry.h +++ b/repos/base/src/core/include/trace/subject_registry.h @@ -436,6 +436,22 @@ class Genode::Trace::Subject_registry return i; } + /** + * Retrieve Subject_infos batched + */ + size_t subjects(Subject_info * const dst, Subject_id * ids, size_t const len) + { + Mutex::Guard guard(_mutex); + + unsigned i = 0; + for (Subject *s = _entries.first(); s && i < len; s = s->next()) { + ids[i] = s->id(); + dst[i++] = s->info(); + } + + return i; + } + /** * Remove subject and release resources * diff --git a/repos/base/src/core/trace_session_component.cc b/repos/base/src/core/trace_session_component.cc index b539dc8ea..bda700936 100644 --- a/repos/base/src/core/trace_session_component.cc +++ b/repos/base/src/core/trace_session_component.cc @@ -36,6 +36,18 @@ size_t Session_component::subjects() } +size_t Session_component::subject_infos() +{ + _subjects.import_new_sources(_sources); + + size_t const count = _argument_buffer.size() / (sizeof(Subject_info) + sizeof(Subject_id)); + Subject_info *infos = _argument_buffer.local_addr(); + Subject_id *ids = reinterpret_cast(infos + count); + + return _subjects.subjects(infos, ids, count); +} + + Policy_id Session_component::alloc_policy(size_t size) { if (size > _argument_buffer.size())