trace: make trace buffer resizeable
Trace buffers a re-allocated during subsequent calls to 'trace'. issue #3294
This commit is contained in:
parent
ac0ecdf855
commit
25484f870e
|
@ -79,19 +79,18 @@ class Genode::Trace::Subject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate new dataspace
|
* 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)
|
if (_size)
|
||||||
return false;
|
_ram_ptr->free(_ds);
|
||||||
|
|
||||||
_ram_ptr = &ram;
|
_ram_ptr = &ram;
|
||||||
_size = size;
|
_size = size;
|
||||||
_ds = ram.alloc(size);
|
_ds = ram.alloc(size);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,6 +102,9 @@ class Genode::Trace::Subject
|
||||||
if (!from_ds.valid())
|
if (!from_ds.valid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (_size)
|
||||||
|
flush();
|
||||||
|
|
||||||
_ram_ptr = &ram;
|
_ram_ptr = &ram;
|
||||||
_size = size;
|
_size = size;
|
||||||
_ds = ram.alloc(_size);
|
_ds = ram.alloc(_size);
|
||||||
|
@ -144,6 +146,7 @@ class Genode::Trace::Subject
|
||||||
Ram_dataspace _buffer { };
|
Ram_dataspace _buffer { };
|
||||||
Ram_dataspace _policy { };
|
Ram_dataspace _policy { };
|
||||||
Policy_id _policy_id { };
|
Policy_id _policy_id { };
|
||||||
|
size_t _allocated_memory { 0 };
|
||||||
|
|
||||||
Subject_info::State _state()
|
Subject_info::State _state()
|
||||||
{
|
{
|
||||||
|
@ -162,6 +165,18 @@ class Genode::Trace::Subject
|
||||||
return Subject_info::UNTRACED;
|
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:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,6 +199,9 @@ class Genode::Trace::Subject
|
||||||
*/
|
*/
|
||||||
bool has_source_id(unsigned id) const { return id == _source_id; }
|
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
|
* Start tracing
|
||||||
*
|
*
|
||||||
|
@ -199,21 +217,23 @@ class Genode::Trace::Subject
|
||||||
size_t policy_size, Ram_allocator &ram,
|
size_t policy_size, Ram_allocator &ram,
|
||||||
Region_map &local_rm, size_t size)
|
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;
|
_policy_id = policy_id;
|
||||||
|
|
||||||
if (!_buffer.setup(ram, size)
|
_buffer.setup(ram, size);
|
||||||
|| !_policy.setup(ram, local_rm, policy_ds, policy_size))
|
if(!_policy.setup(ram, local_rm, policy_ds, policy_size))
|
||||||
throw Already_traced();
|
throw Already_traced();
|
||||||
|
|
||||||
/* inform trace source about the new buffer */
|
/* inform trace source about the new buffer */
|
||||||
Locked_ptr<Source> source(_source);
|
Locked_ptr<Source> source(_source);
|
||||||
|
|
||||||
if (!source.valid())
|
|
||||||
throw Source_is_dead();
|
|
||||||
|
|
||||||
if (!source->try_acquire(*this))
|
if (!source->try_acquire(*this))
|
||||||
throw Traced_by_other_session();
|
throw Traced_by_other_session();
|
||||||
|
|
||||||
|
_allocated_memory = policy_size + size;
|
||||||
|
|
||||||
source->trace(_policy.dataspace(), _buffer.dataspace());
|
source->trace(_policy.dataspace(), _buffer.dataspace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 policy_size = _policies.size(*this, policy_id);
|
||||||
size_t const required_ram = buffer_size + policy_size;
|
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
|
* Account RAM needed for trace buffer and policy buffer to the trace
|
||||||
* session.
|
* session.
|
||||||
*/
|
*/
|
||||||
if (!_md_alloc.withdraw(required_ram))
|
if (!_md_alloc.withdraw(required_ram)) {
|
||||||
throw Out_of_ram();
|
throw Out_of_ram();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Trace::Subject &subject = _subjects.lookup_by_id(subject_id);
|
|
||||||
subject.trace(policy_id, _policies.dataspace(*this, policy_id),
|
subject.trace(policy_id, _policies.dataspace(*this, policy_id),
|
||||||
policy_size, _ram, _local_rm, buffer_size);
|
policy_size, _ram, _local_rm, buffer_size);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
/* revert withdrawal or quota */
|
/* revert withdrawal or quota */
|
||||||
_md_alloc.upgrade(required_ram);
|
_md_alloc.upgrade(required_ram);
|
||||||
throw Out_of_ram();
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user