From 25484f870e6ec2bd22830fcd3034cf0cad84d307 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Mon, 6 May 2019 10:42:05 +0200 Subject: [PATCH] trace: make trace buffer resizeable Trace buffers a re-allocated during subsequent calls to 'trace'. issue #3294 --- .../src/core/include/trace/subject_registry.h | 44 ++++++++++++++----- .../base/src/core/trace_session_component.cc | 13 ++++-- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/repos/base/src/core/include/trace/subject_registry.h b/repos/base/src/core/include/trace/subject_registry.h index 87df4564c..7ac42d135 100644 --- a/repos/base/src/core/include/trace/subject_registry.h +++ b/repos/base/src/core/include/trace/subject_registry.h @@ -79,19 +79,18 @@ class Genode::Trace::Subject /** * Allocate new dataspace - * - * \return true on success, false on the attempt to call setup - * twice. */ - bool setup(Ram_allocator &ram, size_t size) + void setup(Ram_allocator &ram, size_t size) { + if (_size && _size == size) + return; + if (_size) - return false; + _ram_ptr->free(_ds); _ram_ptr = &ram; _size = size; _ds = ram.alloc(size); - return true; } /** @@ -103,6 +102,9 @@ class Genode::Trace::Subject if (!from_ds.valid()) return false; + if (_size) + flush(); + _ram_ptr = &ram; _size = size; _ds = ram.alloc(_size); @@ -144,6 +146,7 @@ class Genode::Trace::Subject Ram_dataspace _buffer { }; Ram_dataspace _policy { }; Policy_id _policy_id { }; + size_t _allocated_memory { 0 }; Subject_info::State _state() { @@ -162,6 +165,18 @@ class Genode::Trace::Subject return Subject_info::UNTRACED; } + void _traceable_or_throw() + { + switch(_state()) { + case Subject_info::DEAD : throw Source_is_dead(); + case Subject_info::FOREIGN : throw Traced_by_other_session(); + case Subject_info::ERROR : throw Source_is_dead(); + case Subject_info::INVALID : throw Nonexistent_subject(); + case Subject_info::UNTRACED: return; + case Subject_info::TRACED : return; + } + } + public: /** @@ -184,6 +199,9 @@ class Genode::Trace::Subject */ bool has_source_id(unsigned id) const { return id == _source_id; } + size_t allocated_memory() const { return _allocated_memory; } + void reset_allocated_memory() { _allocated_memory = 0; } + /** * Start tracing * @@ -199,21 +217,23 @@ class Genode::Trace::Subject size_t policy_size, Ram_allocator &ram, Region_map &local_rm, size_t size) { + /* check state and throw error in case subject is not traceable */ + _traceable_or_throw(); + _policy_id = policy_id; - if (!_buffer.setup(ram, size) - || !_policy.setup(ram, local_rm, policy_ds, policy_size)) - throw Already_traced(); + _buffer.setup(ram, size); + if(!_policy.setup(ram, local_rm, policy_ds, policy_size)) + throw Already_traced(); /* inform trace source about the new buffer */ Locked_ptr source(_source); - if (!source.valid()) - throw Source_is_dead(); - if (!source->try_acquire(*this)) throw Traced_by_other_session(); + _allocated_memory = policy_size + size; + source->trace(_policy.dataspace(), _buffer.dataspace()); } diff --git a/repos/base/src/core/trace_session_component.cc b/repos/base/src/core/trace_session_component.cc index 083f95cdd..b539dc8ea 100644 --- a/repos/base/src/core/trace_session_component.cc +++ b/repos/base/src/core/trace_session_component.cc @@ -82,21 +82,28 @@ void Session_component::trace(Subject_id subject_id, Policy_id policy_id, size_t const policy_size = _policies.size(*this, policy_id); size_t const required_ram = buffer_size + policy_size; + Trace::Subject &subject = _subjects.lookup_by_id(subject_id); + /* revert quota from previous call to trace */ + if (subject.allocated_memory()) { + _md_alloc.upgrade(subject.allocated_memory()); + subject.reset_allocated_memory(); + } + /* * Account RAM needed for trace buffer and policy buffer to the trace * session. */ - if (!_md_alloc.withdraw(required_ram)) + if (!_md_alloc.withdraw(required_ram)) { throw Out_of_ram(); + } try { - Trace::Subject &subject = _subjects.lookup_by_id(subject_id); subject.trace(policy_id, _policies.dataspace(*this, policy_id), policy_size, _ram, _local_rm, buffer_size); } catch (...) { /* revert withdrawal or quota */ _md_alloc.upgrade(required_ram); - throw Out_of_ram(); + throw; } }