trace: forward exceptions during construction

The control area is constructed during session creation and the caller can
handle the Out_of_* exception by increasing the quota by the next attempt.

Fixes #3917
This commit is contained in:
Alexander Boettcher 2020-10-14 15:35:59 +02:00 committed by Christian Helmuth
parent d16a1bd922
commit c6a2e287d0

View File

@ -16,6 +16,7 @@
#include <base/env.h> #include <base/env.h>
#include <dataspace/capability.h> #include <dataspace/capability.h>
#include <base/attached_ram_dataspace.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/trace_control.h> #include <base/internal/trace_control.h>
@ -33,25 +34,10 @@ class Genode::Trace::Control_area
Ram_allocator &_ram; Ram_allocator &_ram;
Region_map &_rm; Region_map &_rm;
Ram_dataspace_capability _ds; Attached_ram_dataspace const _area;
Trace::Control *_local_base;
static Ram_dataspace_capability _try_alloc(Ram_allocator &ram, size_t size) bool _index_valid(unsigned const index) const {
{ return index < SIZE / sizeof(Trace::Control); }
try { return ram.alloc(size); }
catch (...) { return Ram_dataspace_capability(); }
}
static Trace::Control *_try_attach(Region_map &rm, Dataspace_capability ds)
{
try { return rm.attach(ds); }
catch (...) { return nullptr; }
}
bool _index_valid(int index) const
{
return (index + 1)*sizeof(Trace::Control) < SIZE;
}
/* /*
* Noncopyable * Noncopyable
@ -59,48 +45,45 @@ class Genode::Trace::Control_area
Control_area(Control_area const &); Control_area(Control_area const &);
Control_area &operator = (Control_area const &); Control_area &operator = (Control_area const &);
Trace::Control * _local_base() const {
return _area.local_addr<Trace::Control>(); }
public: public:
Control_area(Ram_allocator &ram, Region_map &rm) Control_area(Ram_allocator &ram, Region_map &rm)
: :
_ram(ram), _rm(rm), _ram(ram), _rm(rm), _area(ram, rm, SIZE)
_ds(_try_alloc(ram, SIZE)),
_local_base(_try_attach(rm, _ds))
{ } { }
~Control_area() ~Control_area() { }
{
if (_local_base) _rm.detach(_local_base);
if (_ds.valid()) _ram.free(_ds);
}
Dataspace_capability dataspace() const { return _ds; } Dataspace_capability dataspace() const { return _area.cap(); }
bool alloc(unsigned &index_out) bool alloc(unsigned &index_out)
{ {
for (unsigned index = 0; _index_valid(index); index++) { for (unsigned index = 0; _index_valid(index); index++) {
if (!_local_base[index].is_free()) { if (!_local_base()[index].is_free()) {
continue; continue;
} }
_local_base[index].alloc(); _local_base()[index].alloc();
index_out = index; index_out = index;
return true; return true;
} }
error("trace-control allocaton failed"); error("trace-control allocation failed");
return false; return false;
} }
void free(unsigned index) void free(unsigned index)
{ {
if (_index_valid(index)) if (_index_valid(index))
_local_base[index].reset(); _local_base()[index].reset();
} }
Trace::Control *at(unsigned index) Trace::Control *at(unsigned index)
{ {
return _index_valid(index) ? &_local_base[index] : nullptr; return _index_valid(index) ? &(_local_base()[index]) : nullptr;
} }
}; };