From 843dd179d7165853d77ecf175f330e5e4f51cbb4 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 8 May 2017 12:33:56 +0200 Subject: [PATCH] base: remove int return types from 'Ram_session' This patch replaces the existing C-style error codes with C++ exceptions. Fixes #895 --- repos/base-linux/src/core/include/core_env.h | 12 +- repos/base-linux/src/core/stack_area.cc | 5 +- repos/base-sel4/src/core/stack_area.cc | 5 +- repos/base/include/ram_session/client.h | 8 +- repos/base/include/ram_session/ram_session.h | 27 +- repos/base/src/core/include/core_env.h | 16 +- .../src/core/include/ram_session_component.h | 309 +++++++++--------- repos/base/src/core/ram_session_component.cc | 39 ++- repos/base/src/core/stack_area.cc | 5 +- .../internal/expanding_ram_session_client.h | 15 +- repos/base/src/lib/base/child.cc | 7 +- repos/os/include/cli_monitor/ram.h | 17 +- repos/os/include/os/ram_session_guard.h | 44 +-- .../platform/spec/x86/pci_session_component.h | 23 +- repos/os/src/init/child.cc | 5 +- repos/os/src/init/server.cc | 8 +- .../server/loader/ram_session_client_guard.h | 12 +- repos/os/src/test/resource_request/main.cc | 6 +- .../app/gdb_monitor/ram_session_component.cc | 10 +- .../app/gdb_monitor/ram_session_component.h | 4 +- repos/ports/src/noux/ram_session_component.h | 4 +- 21 files changed, 282 insertions(+), 299 deletions(-) diff --git a/repos/base-linux/src/core/include/core_env.h b/repos/base-linux/src/core/include/core_env.h index bcb41ac70..33648c066 100644 --- a/repos/base-linux/src/core/include/core_env.h +++ b/repos/base-linux/src/core/include/core_env.h @@ -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 diff --git a/repos/base-linux/src/core/stack_area.cc b/repos/base-linux/src/core/stack_area.cc index 3dc437720..a77cb13f5 100644 --- a/repos/base-linux/src/core/stack_area.cc +++ b/repos/base-linux/src/core/stack_area.cc @@ -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 }; } diff --git a/repos/base-sel4/src/core/stack_area.cc b/repos/base-sel4/src/core/stack_area.cc index f3c8d5771..4d7eeb651 100644 --- a/repos/base-sel4/src/core/stack_area.cc +++ b/repos/base-sel4/src/core/stack_area.cc @@ -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 }; } diff --git a/repos/base/include/ram_session/client.h b/repos/base/include/ram_session/client.h index 985aeb3ef..9e9bf61f6 100644 --- a/repos/base/include/ram_session/client.h +++ b/repos/base/include/ram_session/client.h @@ -39,11 +39,11 @@ struct Genode::Ram_session_client : Rpc_client return ds.valid() ? Dataspace_client(ds).size() : 0; } - int ref_account(Ram_session_capability ram_session) override { - return call(ram_session); } + void ref_account(Ram_session_capability ram_session) override { + call(ram_session); } - int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override { - return call(ram_session, amount); } + void transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override { + call(ram_session, amount); } Ram_quota ram_quota() const override { return call(); } diff --git a/repos/base/include/ram_session/ram_session.h b/repos/base/include/ram_session/ram_session.h index e86025e61..80d71780a 100644 --- a/repos/base/include/ram_session/ram_session.h +++ b/repos/base/include/ram_session/ram_session.h @@ -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); + GENODE_RPC_THROW(Rpc_transfer_ram_quota, void, transfer_quota, + GENODE_TYPE_LIST(Out_of_ram, Invalid_session, Undefined_ref_account), + Capability, Ram_quota); GENODE_RPC(Rpc_ram_quota, Ram_quota, ram_quota); GENODE_RPC(Rpc_used_ram, Ram_quota, used_ram); diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index b4980454d..848683163 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -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 diff --git a/repos/base/src/core/include/ram_session_component.h b/repos/base/src/core/include/ram_session_component.h index 1d2cd6fb7..e07b87eed 100644 --- a/repos/base/src/core/include/ram_session_component.h +++ b/repos/base/src/core/include/ram_session_component.h @@ -30,160 +30,161 @@ namespace Genode { class Ram_session_component; typedef List Ram_ref_account_members; - - class Ram_session_component : public Rpc_object, - 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 >; - - 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, + 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 >; + + 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_ */ diff --git a/repos/base/src/core/ram_session_component.cc b/repos/base/src/core/ram_session_component.cc index f553721b1..4fedddb44 100644 --- a/repos/base/src/core/ram_session_component.cc +++ b/repos/base/src/core/ram_session_component.cc @@ -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; diff --git a/repos/base/src/core/stack_area.cc b/repos/base/src/core/stack_area.cc index b8c718af9..6cbde0489 100644 --- a/repos/base/src/core/stack_area.cc +++ b/repos/base/src/core/stack_area.cc @@ -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 }; } }; diff --git a/repos/base/src/include/base/internal/expanding_ram_session_client.h b/repos/base/src/include/base/internal/expanding_ram_session_client.h index d8c79db9d..60b216f2c 100644 --- a/repos/base/src/include/base/internal/expanding_ram_session_client.h +++ b/repos/base/src/include/base/internal/expanding_ram_session_client.h @@ -68,22 +68,17 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client( + [&] () { Ram_session_client::transfer_quota(ram_session, amount); }, + [&] () { _request_ram_from_parent(amount.value); }, + NUM_ATTEMPTS); } }; diff --git a/repos/base/src/lib/base/child.cc b/repos/base/src/lib/base/child.cc index 1f2450b77..21393edce 100644 --- a/repos/base/src/lib/base/child.cc +++ b/repos/base/src/lib/base/child.cc @@ -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(); } diff --git a/repos/os/include/cli_monitor/ram.h b/repos/os/include/cli_monitor/ram.h index 0aa4bdcfd..8a18aa360 100644 --- a/repos/os/include/cli_monitor/ram.h +++ b/repos/os/include/cli_monitor/ram.h @@ -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; } diff --git a/repos/os/include/os/ram_session_guard.h b/repos/os/include/os/ram_session_guard.h index 10cf00bf4..7124bf817 100644 --- a/repos/os/include/os/ram_session_guard.h +++ b/repos/os/include/os/ram_session_guard.h @@ -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 - 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}; } diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index 3bd9c6a8a..1fabcb6f2 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -252,8 +252,8 @@ class Platform::Session_component : public Genode::Rpc_object _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 _try_init_device_pd(); /* transfer ram quota to session specific ram session */ - if (_env_ram.transfer_quota(_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 * It is therefore enough to increase the quota in * UPGRADE_QUOTA steps. */ - _env_ram.transfer_quota(_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 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(); } }); } diff --git a/repos/os/src/init/child.cc b/repos/os/src/init/child.cc index 0df1cce29..b585b6c01 100644 --- a/repos/os/src/init/child.cc +++ b/repos/os/src/init/child.cc @@ -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) diff --git a/repos/os/src/init/server.cc b/repos/os/src/init/server.cc index 6fc4524c8..6680ce387 100644 --- a/repos/os/src/init/server.cc +++ b/repos/os/src/init/server.cc @@ -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; diff --git a/repos/os/src/server/loader/ram_session_client_guard.h b/repos/os/src/server/loader/ram_session_client_guard.h index 9db1288b2..ea41b6344 100644 --- a/repos/os/src/server/loader/ram_session_client_guard.h +++ b/repos/os/src/server/loader/ram_session_client_guard.h @@ -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 diff --git a/repos/os/src/test/resource_request/main.cc b/repos/os/src/test/resource_request/main.cc index 780e2f158..7ebf56d35 100644 --- a/repos/os/src/test/resource_request/main.cc +++ b/repos/os/src/test/resource_request/main.cc @@ -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; diff --git a/repos/ports/src/app/gdb_monitor/ram_session_component.cc b/repos/ports/src/app/gdb_monitor/ram_session_component.cc index f6ad2bfa2..1a65b6c37 100644 --- a/repos/ports/src/app/gdb_monitor/ram_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/ram_session_component.cc @@ -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); } diff --git a/repos/ports/src/app/gdb_monitor/ram_session_component.h b/repos/ports/src/app/gdb_monitor/ram_session_component.h index 4700e3e11..152e5f2a6 100644 --- a/repos/ports/src/app/gdb_monitor/ram_session_component.h +++ b/repos/ports/src/app/gdb_monitor/ram_session_component.h @@ -59,8 +59,8 @@ class Gdb_monitor::Ram_session_component : public Rpc_object 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; }; diff --git a/repos/ports/src/noux/ram_session_component.h b/repos/ports/src/noux/ram_session_component.h index 778849bc7..0c03e7445 100644 --- a/repos/ports/src/noux/ram_session_component.h +++ b/repos/ports/src/noux/ram_session_component.h @@ -188,8 +188,8 @@ class Noux::Ram_session_component : public Rpc_object 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}; } };