mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
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:
parent
58f44d39c5
commit
843dd179d7
@ -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
|
||||
|
@ -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 }; }
|
||||
|
||||
|
@ -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 }; }
|
||||
|
||||
|
@ -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>(); }
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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 }; }
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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}; }
|
||||
|
@ -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(); }
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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}; }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user