base: remove int return types from 'Ram_session'

This patch replaces the existing C-style error codes with C++
exceptions.

Fixes #895
This commit is contained in:
Norman Feske 2017-05-08 12:33:56 +02:00 committed by Christian Helmuth
parent 58f44d39c5
commit 843dd179d7
21 changed files with 282 additions and 299 deletions

View File

@ -70,13 +70,13 @@ namespace Genode {
** RAM-session interface **
***************************/
Ram_dataspace_capability alloc(size_t size, bool cached)
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::alloc(size, cached);
}
void free(Ram_dataspace_capability ds)
void free(Ram_dataspace_capability ds) override
{
Lock::Guard lock_guard(_lock);
RAM_SESSION_IMPL::free(ds);
@ -88,16 +88,16 @@ namespace Genode {
return RAM_SESSION_IMPL::dataspace_size(ds);
}
int ref_account(Ram_session_capability session)
void ref_account(Ram_session_capability session) override
{
Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::ref_account(session);
RAM_SESSION_IMPL::ref_account(session);
}
int transfer_quota(Ram_session_capability session, Ram_quota size)
void transfer_quota(Ram_session_capability session, Ram_quota amount) override
{
Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::transfer_quota(session, size);
RAM_SESSION_IMPL::transfer_quota(session, amount);
}
Ram_quota ram_quota() const override

View File

@ -80,7 +80,6 @@ class Stack_area_region_map : public Genode::Region_map
struct Stack_area_ram_session : Genode::Ram_session
{
Genode::Ram_dataspace_capability alloc(Genode::size_t size,
Genode::Cache_attribute) override {
return Genode::Ram_dataspace_capability(); }
@ -89,9 +88,9 @@ struct Stack_area_ram_session : Genode::Ram_session
Genode::size_t dataspace_size(Genode::Ram_dataspace_capability) const override { return 0; }
int ref_account(Genode::Ram_session_capability) override { return 0; }
void ref_account(Genode::Ram_session_capability) override { }
int transfer_quota(Genode::Ram_session_capability, Genode::Ram_quota) override { return 0; }
void transfer_quota(Genode::Ram_session_capability, Genode::Ram_quota) override { }
Genode::Ram_quota ram_quota() const override { return { 0 }; }

View File

@ -130,10 +130,9 @@ struct Stack_area_ram_session : Ram_session
size_t dataspace_size(Ram_dataspace_capability) const override { return 0; }
int ref_account(Ram_session_capability ram_session) override { return 0; }
void ref_account(Ram_session_capability) override { }
int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override {
return 0; }
void transfer_quota(Ram_session_capability, Ram_quota) override { }
Ram_quota ram_quota() const override { return { 0 }; }

View File

@ -39,11 +39,11 @@ struct Genode::Ram_session_client : Rpc_client<Ram_session>
return ds.valid() ? Dataspace_client(ds).size() : 0;
}
int ref_account(Ram_session_capability ram_session) override {
return call<Rpc_ref_account>(ram_session); }
void ref_account(Ram_session_capability ram_session) override {
call<Rpc_ref_account>(ram_session); }
int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override {
return call<Rpc_transfer_ram_quota>(ram_session, amount); }
void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override {
call<Rpc_transfer_ram_quota>(ram_session, amount); }
Ram_quota ram_quota() const override { return call<Rpc_ram_quota>(); }

View File

@ -38,6 +38,14 @@ struct Genode::Ram_session : Session, Ram_allocator
typedef Ram_session_client Client;
/*********************
** Exception types **
*********************/
class Invalid_session : public Exception { };
class Undefined_ref_account : public Exception { };
/**
* Destructor
*/
@ -48,25 +56,28 @@ struct Genode::Ram_session : Session, Ram_allocator
*
* \param ram_session reference account
*
* \return 0 on success
* \throw Invalid_session
*
* Each RAM session requires another RAM session as reference
* account to transfer quota to and from. The reference account can
* be defined only once.
*/
virtual int ref_account(Ram_session_capability ram_session) = 0;
virtual void ref_account(Ram_session_capability ram_session) = 0;
/**
* Transfer quota to another RAM session
*
* \param ram_session receiver of quota donation
* \param amount amount of quota to donate
* \return 0 on success
*
* \throw Out_of_ram
* \throw Invalid_session
* \throw Undefined_ref_account
*
* Quota can only be transfered if the specified RAM session is
* either the reference account for this session or vice versa.
*/
virtual int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) = 0;
virtual void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) = 0;
/**
* Return current quota limit
@ -89,11 +100,13 @@ struct Genode::Ram_session : Session, Ram_allocator
*********************/
GENODE_RPC_THROW(Rpc_alloc, Ram_dataspace_capability, alloc,
GENODE_TYPE_LIST(Quota_exceeded, Out_of_metadata),
GENODE_TYPE_LIST(Quota_exceeded, Out_of_metadata, Undefined_ref_account),
size_t, Cache_attribute);
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
GENODE_RPC(Rpc_ref_account, int, ref_account, Ram_session_capability);
GENODE_RPC(Rpc_transfer_ram_quota, int, transfer_quota, Ram_session_capability, Ram_quota);
GENODE_RPC(Rpc_ref_account, void, ref_account, Capability<Ram_session>);
GENODE_RPC_THROW(Rpc_transfer_ram_quota, void, transfer_quota,
GENODE_TYPE_LIST(Out_of_ram, Invalid_session, Undefined_ref_account),
Capability<Ram_session>, Ram_quota);
GENODE_RPC(Rpc_ram_quota, Ram_quota, ram_quota);
GENODE_RPC(Rpc_used_ram, Ram_quota, used_ram);

View File

@ -3,9 +3,6 @@
* \author Norman Feske
* \author Christian Helmuth
* \date 2006-07-28
*
* The Core-specific environment ensures that all sessions of Core's
* environment a local (_component) not remote (_client).
*/
/*
@ -73,14 +70,15 @@ namespace Genode {
** RAM-session interface **
***************************/
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached)
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{
Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::alloc(size, cached);
}
void free(Ram_dataspace_capability ds)
void free(Ram_dataspace_capability ds) override
{
Lock::Guard lock_guard(_lock);
RAM_SESSION_IMPL::free(ds);
}
@ -90,16 +88,16 @@ namespace Genode {
return RAM_SESSION_IMPL::dataspace_size(ds);
}
int ref_account(Ram_session_capability session)
void ref_account(Ram_session_capability session) override
{
Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::ref_account(session);
RAM_SESSION_IMPL::ref_account(session);
}
int transfer_quota(Ram_session_capability session, Ram_quota size)
void transfer_quota(Ram_session_capability session, Ram_quota amount) override
{
Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::transfer_quota(session, size);
RAM_SESSION_IMPL::transfer_quota(session, amount);
}
Ram_quota ram_quota() const override

View File

@ -30,160 +30,161 @@ namespace Genode {
class Ram_session_component;
typedef List<Ram_session_component> Ram_ref_account_members;
class Ram_session_component : public Rpc_object<Ram_session>,
public Ram_ref_account_members::Element,
public Dataspace_owner
{
private:
class Invalid_dataspace : public Exception { };
/*
* Dimension 'Ds_slab' such that slab blocks (including the
* meta-data overhead of the sliced-heap blocks) are page sized.
*/
static constexpr size_t SBS = get_page_size() - Sliced_heap::meta_data_size();
using Ds_slab = Synced_allocator<Tslab<Dataspace_component, SBS> >;
Rpc_entrypoint *_ds_ep;
Rpc_entrypoint *_ram_session_ep;
Range_allocator *_ram_alloc;
size_t _quota_limit;
size_t _payload; /* quota used for payload */
Allocator_guard _md_alloc; /* guarded meta-data allocator */
Ds_slab _ds_slab; /* meta-data allocator */
Ram_session_component *_ref_account; /* reference ram session */
addr_t _phys_start;
addr_t _phys_end;
enum { MAX_LABEL_LEN = 64 };
char _label[MAX_LABEL_LEN];
/**
* List of RAM sessions that use us as their reference account
*/
Ram_ref_account_members _ref_members;
Lock _ref_members_lock; /* protect '_ref_members' */
/**
* Register RAM session to use us as reference account
*/
void _register_ref_account_member(Ram_session_component *new_member);
/**
* Dissolve reference-account relationship of a member account
*/
void _remove_ref_account_member(Ram_session_component *member);
void _unsynchronized_remove_ref_account_member(Ram_session_component *member);
/**
* Return portion of RAM quota that is currently in use
*/
size_t used_quota() { return _payload; }
/**
* Free dataspace
*/
void _free_ds(Dataspace_capability ds_cap);
/**
* Transfer quota to another RAM session
*/
int _transfer_quota(Ram_session_component *dst, size_t amount);
/********************************************
** Platform-implemented support functions **
********************************************/
/**
* Export RAM dataspace as shared memory block
*/
void _export_ram_ds(Dataspace_component *ds);
/**
* Revert export of RAM dataspace
*/
void _revoke_ram_ds(Dataspace_component *ds);
/**
* Zero-out content of dataspace
*/
void _clear_ds(Dataspace_component *ds);
public:
/**
* Constructor
*
* \param ds_ep server entry point to manage the
* dataspaces created by the Ram session
* \param ram_session_ep entry point that manages Ram sessions,
* used for looking up another ram session
* in transfer_quota()
* \param ram_alloc memory pool to manage
* \param md_alloc meta-data allocator
* \param md_ram_quota limit of meta-data backing store
* \param quota_limit initial quota limit
*
* The 'quota_limit' parameter is only used for the very
* first ram session in the system. All other ram session
* load their quota via 'transfer_quota'.
*/
Ram_session_component(Rpc_entrypoint *ds_ep,
Rpc_entrypoint *ram_session_ep,
Range_allocator *ram_alloc,
Allocator *md_alloc,
const char *args,
size_t quota_limit = 0);
/**
* Destructor
*/
~Ram_session_component();
/**
* Accessors
*/
Ram_session_component *ref_account() { return _ref_account; }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); }
/**
* Get physical address of the RAM that backs a dataspace
*
* \param ds targeted dataspace
*
* \throw Invalid_dataspace
*/
addr_t phys_addr(Ram_dataspace_capability ds);
/*****************************
** Ram_allocator interface **
*****************************/
Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability ds) const override;
/***************************
** RAM Session interface **
***************************/
int ref_account(Ram_session_capability);
int transfer_quota(Ram_session_capability, Ram_quota);
Ram_quota ram_quota() const override { return { _quota_limit}; }
Ram_quota used_ram() const override { return { _payload}; }
};
}
class Genode::Ram_session_component : public Rpc_object<Ram_session>,
public Ram_ref_account_members::Element,
public Dataspace_owner
{
private:
class Invalid_dataspace : public Exception { };
/*
* Dimension 'Ds_slab' such that slab blocks (including the
* meta-data overhead of the sliced-heap blocks) are page sized.
*/
static constexpr size_t SBS = get_page_size() - Sliced_heap::meta_data_size();
using Ds_slab = Synced_allocator<Tslab<Dataspace_component, SBS> >;
Rpc_entrypoint *_ds_ep;
Rpc_entrypoint *_ram_session_ep;
Range_allocator *_ram_alloc;
size_t _quota_limit;
size_t _payload; /* quota used for payload */
Allocator_guard _md_alloc; /* guarded meta-data allocator */
Ds_slab _ds_slab; /* meta-data allocator */
Ram_session_component *_ref_account; /* reference ram session */
addr_t _phys_start;
addr_t _phys_end;
enum { MAX_LABEL_LEN = 64 };
char _label[MAX_LABEL_LEN];
/**
* List of RAM sessions that use us as their reference account
*/
Ram_ref_account_members _ref_members;
Lock _ref_members_lock; /* protect '_ref_members' */
/**
* Register RAM session to use us as reference account
*/
void _register_ref_account_member(Ram_session_component *new_member);
/**
* Dissolve reference-account relationship of a member account
*/
void _remove_ref_account_member(Ram_session_component *member);
void _unsynchronized_remove_ref_account_member(Ram_session_component *member);
/**
* Return portion of RAM quota that is currently in use
*/
size_t used_quota() { return _payload; }
/**
* Free dataspace
*/
void _free_ds(Dataspace_capability ds_cap);
/**
* Transfer quota to another RAM session
*/
void _transfer_quota(Ram_session_component *dst, size_t amount);
/********************************************
** Platform-implemented support functions **
********************************************/
/**
* Export RAM dataspace as shared memory block
*/
void _export_ram_ds(Dataspace_component *ds);
/**
* Revert export of RAM dataspace
*/
void _revoke_ram_ds(Dataspace_component *ds);
/**
* Zero-out content of dataspace
*/
void _clear_ds(Dataspace_component *ds);
public:
/**
* Constructor
*
* \param ds_ep server entry point to manage the
* dataspaces created by the Ram session
* \param ram_session_ep entry point that manages Ram sessions,
* used for looking up another ram session
* in transfer_quota()
* \param ram_alloc memory pool to manage
* \param md_alloc meta-data allocator
* \param md_ram_quota limit of meta-data backing store
* \param quota_limit initial quota limit
*
* The 'quota_limit' parameter is only used for the very
* first ram session in the system. All other ram session
* load their quota via 'transfer_quota'.
*/
Ram_session_component(Rpc_entrypoint *ds_ep,
Rpc_entrypoint *ram_session_ep,
Range_allocator *ram_alloc,
Allocator *md_alloc,
const char *args,
size_t quota_limit = 0);
/**
* Destructor
*/
~Ram_session_component();
/**
* Accessors
*/
Ram_session_component *ref_account() { return _ref_account; }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); }
/**
* Get physical address of the RAM that backs a dataspace
*
* \param ds targeted dataspace
*
* \throw Invalid_dataspace
*/
addr_t phys_addr(Ram_dataspace_capability ds);
/*****************************
** Ram_allocator interface **
*****************************/
Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability ds) const override;
/***************************
** RAM Session interface **
***************************/
void ref_account(Ram_session_capability);
void transfer_quota(Ram_session_capability, Ram_quota);
Ram_quota ram_quota() const override { return { _quota_limit}; }
Ram_quota used_ram() const override { return { _payload}; }
};
#endif /* _CORE__INCLUDE__RAM_SESSION_COMPONENT_H_ */

View File

@ -67,14 +67,15 @@ void Ram_session_component::_free_ds(Dataspace_capability ds_cap)
}
int Ram_session_component::_transfer_quota(Ram_session_component *dst, size_t amount)
void Ram_session_component::_transfer_quota(Ram_session_component *dst, size_t amount)
{
/* check if recipient is a valid Ram_session_component */
if (!dst) return -1;
if (!dst)
throw Invalid_session();
/* check for reference account relationship */
if ((ref_account() != dst) && (dst->ref_account() != this))
return -2;
throw Invalid_session();
/* decrease quota limit of this session - check against used quota */
if (_quota_limit < amount + _payload) {
@ -82,15 +83,13 @@ int Ram_session_component::_transfer_quota(Ram_session_component *dst, size_t am
"'", Cstring(_label), "' to '", Cstring(dst->_label), "' "
"have ", (_quota_limit - _payload)/1024, " KiB, "
"need ", amount/1024, " KiB");
return -3;
throw Out_of_ram();
}
_quota_limit -= amount;
/* increase quota_limit of recipient */
dst->_quota_limit += amount;
return 0;
}
@ -250,37 +249,37 @@ size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) co
}
int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
void Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
{
/* the reference account cannot be defined twice */
if (_ref_account) return -2;
if (_ref_account)
return;
if (this->cap() == ram_session_cap)
return;
auto lambda = [this] (Ram_session_component *ref) {
/* check if recipient is a valid Ram_session_component */
if (!ref) return -1;
/* deny the usage of the ram session as its own ref account */
/* XXX also check for cycles along the tree of ref accounts */
if (ref == this) return -3;
if (!ref)
throw Invalid_session();
_ref_account = ref;
_ref_account->_register_ref_account_member(this);
return 0;
};
return _ram_session_ep->apply(ram_session_cap, lambda);
_ram_session_ep->apply(ram_session_cap, lambda);
}
int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
Ram_quota amount)
void Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
Ram_quota amount)
{
auto lambda = [&] (Ram_session_component *dst) {
return _transfer_quota(dst, amount.value); };
_transfer_quota(dst, amount.value); };
if (this->cap() == ram_session_cap)
return 0;
return;
return _ram_session_ep->apply(ram_session_cap, lambda);
}
@ -322,7 +321,7 @@ Ram_session_component::~Ram_session_component()
if (!_ref_account) return;
/* transfer remaining quota to reference account */
_transfer_quota(_ref_account, _quota_limit);
try { _transfer_quota(_ref_account, _quota_limit); } catch (...) { }
/* remember our original reference account */
Ram_session_component *orig_ref_account = _ref_account;

View File

@ -134,8 +134,9 @@ struct Stack_area_ram_session : Ram_session
size_t dataspace_size(Ram_dataspace_capability) const override { return 0; }
int ref_account (Ram_session_capability) override { return 0; }
int transfer_quota (Ram_session_capability, Ram_quota) override { return 0; }
void ref_account (Ram_session_capability) override { }
void transfer_quota (Ram_session_capability, Ram_quota) override { }
Ram_quota ram_quota () const override { return { 0 }; }
Ram_quota used_ram () const override { return { 0 }; }
};

View File

@ -68,22 +68,17 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
NUM_ATTEMPTS);
}
int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
{
/*
* Should the transfer fail because we don't have enough quota, request
* the needed amount from the parent.
*/
enum { NUM_ATTEMPTS = 2 };
int ret = -1;
for (unsigned i = 0; i < NUM_ATTEMPTS; i++) {
ret = Ram_session_client::transfer_quota(ram_session, amount);
if (ret != -3) break;
_request_ram_from_parent(amount.value);
}
return ret;
retry<Out_of_ram>(
[&] () { Ram_session_client::transfer_quota(ram_session, amount); },
[&] () { _request_ram_from_parent(amount.value); },
NUM_ATTEMPTS);
}
};

View File

@ -59,8 +59,11 @@ namespace {
Ram_session_capability to)
: _ack(false), _quantum(quantum), _from(from), _to(to)
{
if (_from.valid() && _to.valid() &&
Ram_session_client(_from).transfer_quota(_to, quantum)) {
if (!_from.valid() || !_to.valid())
return;
try { Ram_session_client(_from).transfer_quota(_to, quantum); }
catch (...) {
warning("not enough quota for a donation of ", quantum, " bytes");
throw Quota_exceeded();
}

View File

@ -107,15 +107,14 @@ class Cli_monitor::Ram
*/
void withdraw_from(Genode::Ram_session_capability from, size_t amount)
{
Genode::Lock::Guard guard(_lock);
using namespace Genode;
int const ret =
Genode::Ram_session_client(from).transfer_quota(_ram_cap, Genode::Ram_quota{amount});
Lock::Guard guard(_lock);
if (ret != 0)
throw Transfer_quota_failed();
try { Ram_session_client(from).transfer_quota(_ram_cap, Ram_quota{amount}); }
catch (...) { throw Transfer_quota_failed(); }
Genode::Signal_transmitter(_resource_avail_sigh).submit();
Signal_transmitter(_resource_avail_sigh).submit();
}
/**
@ -130,10 +129,8 @@ class Cli_monitor::Ram
throw Transfer_quota_failed();
}
int const ret = _ram.transfer_quota(to, Genode::Ram_quota{amount});
if (ret != 0)
throw Transfer_quota_failed();
try { _ram.transfer_quota(to, Genode::Ram_quota{amount}); }
catch (...) { throw Transfer_quota_failed(); }
}
size_t avail() const { return _ram.avail_ram().value; }

View File

@ -32,30 +32,12 @@ class Genode::Ram_session_guard : public Genode::Ram_session
size_t _used = 0;
size_t _withdraw = 0;
/* XXX should be either a exception or a enum in rm_session */
enum { RM_SESSION_INSUFFICIENT_QUOTA = -3 };
public:
Ram_session_guard(Ram_session &session, Ram_session_capability cap,
size_t quota)
: _session(session), _session_cap(cap), _quota(quota) { }
/**
* Convenient transfer_quota method throwing a exception iif the
* quota is insufficient.
*/
template <typename T>
int transfer_quota(Ram_session_capability ram_session, size_t amount)
{
int const error = transfer_quota(ram_session, Ram_quota{amount});
if (error == RM_SESSION_INSUFFICIENT_QUOTA)
throw T();
return error;
}
/**
* Extend allocation limit
*/
@ -98,11 +80,11 @@ class Genode::Ram_session_guard : public Genode::Ram_session
if (amount > _used)
return -4;
int error = ram_session.transfer_quota(_session_cap, Ram_quota{amount});
if (!error)
try {
ram_session.transfer_quota(_session_cap, Ram_quota{amount});
_used -= amount;
return error;
return 0;
} catch (...) { return -1; }
}
/***************************
@ -136,21 +118,17 @@ class Genode::Ram_session_guard : public Genode::Ram_session
return _session.dataspace_size(ds);
}
int ref_account(Ram_session_capability ram_session) override {
return _session.ref_account(ram_session); }
void ref_account(Ram_session_capability ram_session) override {
_session.ref_account(ram_session); }
int transfer_quota(Ram_session_capability ram_session,
Ram_quota amount) override
void transfer_quota(Ram_session_capability ram_session,
Ram_quota amount) override
{
if (_used + amount.value <= _used || _used + amount.value > _quota)
return RM_SESSION_INSUFFICIENT_QUOTA;
throw Out_of_ram();
int const error = _session.transfer_quota(ram_session, amount);
if (!error)
_used += amount.value;
return error;
_session.transfer_quota(ram_session, amount);
_used += amount.value;
}
Ram_quota ram_quota() const override { return Ram_quota{_quota}; }

View File

@ -252,8 +252,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_ram.ref_account(_env_ram_cap);
enum { OVERHEAD = 4096 };
if (_env_ram.transfer_quota(_ram, Genode::Ram_quota{OVERHEAD}) != 0)
throw Genode::Root::Quota_exceeded();
try { _env_ram.transfer_quota(_ram, Genode::Ram_quota{OVERHEAD}); }
catch (...) { throw Genode::Root::Quota_exceeded(); }
}
bool const _ram_initialized = (_init_ram(), true);
@ -942,8 +942,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_try_init_device_pd();
/* transfer ram quota to session specific ram session */
if (_env_ram.transfer_quota<Out_of_metadata>(_ram, size))
throw Fatal();
try { _env_ram.transfer_quota(_ram, Genode::Ram_quota{size}); }
catch (...) { throw Fatal(); }
enum { UPGRADE_QUOTA = 4096 };
@ -971,7 +971,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
* It is therefore enough to increase the quota in
* UPGRADE_QUOTA steps.
*/
_env_ram.transfer_quota<Out_of_metadata>(_ram, UPGRADE_QUOTA);
try { _env_ram.transfer_quota(_ram, Genode::Ram_quota{UPGRADE_QUOTA}); }
catch (...) { throw Out_of_metadata(); }
});
if (!ram_cap.valid())
@ -984,12 +985,14 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
if (!_env_ram.withdraw(UPGRADE_QUOTA))
_rollback(size, ram_cap);
if (_env_ram.transfer_quota(_ram, Genode::Ram_quota{UPGRADE_QUOTA}))
throw Fatal();
using namespace Genode;
if (_ram.transfer_quota(_device_pd->ram_session_cap(),
Genode::Ram_quota{UPGRADE_QUOTA}))
throw Fatal();
try { _env_ram.transfer_quota(_ram, Ram_quota{UPGRADE_QUOTA}); }
catch (...) { throw Fatal(); }
try { _ram.transfer_quota(_device_pd->ram_session_cap(),
Ram_quota{UPGRADE_QUOTA}); }
catch (...) { throw Fatal(); }
});
}

View File

@ -238,11 +238,12 @@ void Init::Child::apply_ram_downgrade()
size_t const transfer = min(avail - preserved, decrease);
if (_child.ram().transfer_quota(ref_ram_cap(), Ram_quota{transfer}) == 0) {
try {
_child.ram().transfer_quota(ref_ram_cap(), Ram_quota{transfer});
_resources.assigned_ram_quota =
Ram_quota { _resources.assigned_ram_quota.value - transfer };
break;
}
} catch (...) { }
}
if (attempts == max_attempts)

View File

@ -196,7 +196,8 @@ void Init::Server::_handle_create_session_request(Xml_node request,
route.label, argbuf, Affinity());
/* transfer session quota */
if (_env.ram().transfer_quota(route.service.ram(), ram_quota)) {
try { _env.ram().transfer_quota(route.service.ram(), forward_ram_quota); }
catch (...) {
/*
* This should never happen unless our parent missed to
@ -241,7 +242,10 @@ void Init::Server::_handle_upgrade_session_request(Xml_node request,
session.phase = Session_state::UPGRADE_REQUESTED;
if (_env.ram().transfer_quota(session.service().ram(), ram_quota)) {
try {
_env.ram().transfer_quota(session.service().ram(), ram_quota);
}
catch (...) {
warning("unable to upgrade session quota (", ram_quota, " bytes) "
"of forwarded ", session.service().name(), " session");
return;

View File

@ -66,7 +66,7 @@ namespace Genode {
return Ram_session_client::dataspace_size(ds);
}
int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
{
Lock::Guard _consumed_lock_guard(_consumed_lock);
@ -74,15 +74,11 @@ namespace Genode {
warning("Quota exceeded! amount=", _amount, ", "
"size=", amount.value, ", "
"consumed=", _consumed);
return -1;
throw Out_of_ram();
}
int result = Ram_session_client::transfer_quota(ram_session, amount);
if (result == 0)
_consumed += amount.value;
return result;
Ram_session_client::transfer_quota(ram_session, amount);
_consumed += amount.value;
}
Ram_quota ram_quota() const override

View File

@ -199,11 +199,7 @@ void Component::construct(Genode::Env &env)
* requests, too.
*/
log("\n-- out-of-memory during transfer-quota --");
int ret = env.ram().transfer_quota(ram.cap(), Ram_quota{512*1024});
if (ret != 0) {
error("transfer quota failed (ret = ", ret, ")");
throw Error();
}
env.ram().transfer_quota(ram.cap(), Ram_quota{512*1024});
print_quota_stats(env.ram());
size_t const used_quota_after_transfer = env.ram().used_ram().value;

View File

@ -49,16 +49,16 @@ size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) co
}
int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
void Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
{
return _parent_ram_session.ref_account(ram_session_cap);
_parent_ram_session.ref_account(ram_session_cap);
}
int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
Ram_quota amount)
void Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
Ram_quota amount)
{
return _parent_ram_session.transfer_quota(ram_session_cap, amount);
_parent_ram_session.transfer_quota(ram_session_cap, amount);
}

View File

@ -59,8 +59,8 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability) const override;
int ref_account(Ram_session_capability) override;
int transfer_quota(Ram_session_capability, Ram_quota) override;
void ref_account(Ram_session_capability) override;
void transfer_quota(Ram_session_capability, Ram_quota) override;
Ram_quota ram_quota() const override;
Ram_quota used_ram() const override;
};

View File

@ -188,8 +188,8 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
return result;
}
int ref_account(Ram_session_capability) { return 0; }
int transfer_quota(Ram_session_capability, Ram_quota) { return 0; }
void ref_account(Ram_session_capability) override { }
void transfer_quota(Ram_session_capability, Ram_quota) override { }
Ram_quota ram_quota() const override { return _ram.ram_quota(); }
Ram_quota used_ram() const override { return Ram_quota{_used_ram_quota}; }
};