From ff68d77c7d3b75786a8fc33234e04901b350afd1 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Sun, 7 May 2017 23:49:43 +0200 Subject: [PATCH] base: new 'Ram_allocator' interface The 'Ram_allocator' interface contains the subset of the RAM session interface that is needed to satisfy the needs of the 'Heap' and 'Sliced_heap'. Its small size makes it ideal for intercepting memory allocations as done by the new 'Constrained_ram_allocator' wrapper class, which is meant to replace the existing 'base/allocator_guard.h' and 'os/ram_session_guard.h'. Issue #2398 --- repos/base-linux/src/core/include/core_env.h | 8 +- .../src/core/include/dataspace_component.h | 2 +- repos/base-linux/src/core/stack_area.cc | 21 +-- repos/base-sel4/src/core/stack_area.cc | 22 ++-- repos/base/include/base/heap.h | 41 +++--- repos/base/include/base/ram_allocator.h | 124 ++++++++++++++++++ repos/base/include/ram_session/client.h | 13 +- repos/base/include/ram_session/ram_session.h | 38 +----- repos/base/lib/symbols/ld | 8 +- repos/base/src/core/include/core_env.h | 8 +- .../src/core/include/dataspace_component.h | 2 +- .../src/core/include/ram_session_component.h | 14 +- repos/base/src/core/ram_session_component.cc | 14 ++ repos/base/src/core/stack_area.cc | 19 +-- repos/base/src/lib/base/heap.cc | 18 +-- repos/base/src/lib/base/sliced_heap.cc | 12 +- repos/os/include/os/ram_session_guard.h | 5 + .../server/loader/ram_session_client_guard.h | 21 +-- .../app/gdb_monitor/ram_session_component.cc | 6 + .../app/gdb_monitor/ram_session_component.h | 13 +- repos/ports/src/noux/ram_session_component.h | 24 ++-- 21 files changed, 297 insertions(+), 136 deletions(-) create mode 100644 repos/base/include/base/ram_allocator.h diff --git a/repos/base-linux/src/core/include/core_env.h b/repos/base-linux/src/core/include/core_env.h index 5b7d05481..dcdaa1553 100644 --- a/repos/base-linux/src/core/include/core_env.h +++ b/repos/base-linux/src/core/include/core_env.h @@ -48,7 +48,7 @@ namespace Genode { { private: - Lock _lock; + Lock mutable _lock; public: @@ -82,6 +82,12 @@ namespace Genode { RAM_SESSION_IMPL::free(ds); } + size_t dataspace_size(Ram_dataspace_capability ds) const override + { + Lock::Guard lock_guard(_lock); + return RAM_SESSION_IMPL::dataspace_size(ds); + } + int ref_account(Ram_session_capability session) { Lock::Guard lock_guard(_lock); diff --git a/repos/base-linux/src/core/include/dataspace_component.h b/repos/base-linux/src/core/include/dataspace_component.h index 903b0b883..91fa8ad98 100644 --- a/repos/base-linux/src/core/include/dataspace_component.h +++ b/repos/base-linux/src/core/include/dataspace_component.h @@ -100,7 +100,7 @@ namespace Genode { /** * Check if dataspace is owned by a specified object */ - bool owner(Dataspace_owner * const o) const { return _owner == o; } + bool owner(Dataspace_owner const *o) const { return _owner == o; } /** * Detach dataspace from all rm sessions. diff --git a/repos/base-linux/src/core/stack_area.cc b/repos/base-linux/src/core/stack_area.cc index 39a6a916f..640895960 100644 --- a/repos/base-linux/src/core/stack_area.cc +++ b/repos/base-linux/src/core/stack_area.cc @@ -78,23 +78,24 @@ class Stack_area_region_map : public Genode::Region_map }; -class Stack_area_ram_session : public Genode::Ram_session +struct Stack_area_ram_session : Genode::Ram_session { - public: - Genode::Ram_dataspace_capability alloc(Genode::size_t size, - Genode::Cache_attribute) { - return Genode::Ram_dataspace_capability(); } + Genode::Ram_dataspace_capability alloc(Genode::size_t size, + Genode::Cache_attribute) override { + return Genode::Ram_dataspace_capability(); } - void free(Genode::Ram_dataspace_capability) { } + void free(Genode::Ram_dataspace_capability) override { } - int ref_account(Genode::Ram_session_capability) { return 0; } + Genode::size_t dataspace_size(Genode::Ram_dataspace_capability) const override { return 0; } - int transfer_quota(Genode::Ram_session_capability, Genode::size_t) { return 0; } + int ref_account(Genode::Ram_session_capability) override { return 0; } - Genode::size_t quota() { return 0; } + int transfer_quota(Genode::Ram_session_capability, Genode::size_t) override { return 0; } - Genode::size_t used() { return 0; } + Genode::size_t quota() override { return 0; } + + Genode::size_t used() override { return 0; } }; diff --git a/repos/base-sel4/src/core/stack_area.cc b/repos/base-sel4/src/core/stack_area.cc index cc554ab95..05418cf5d 100644 --- a/repos/base-sel4/src/core/stack_area.cc +++ b/repos/base-sel4/src/core/stack_area.cc @@ -120,24 +120,24 @@ class Stack_area_region_map : public Region_map }; -class Stack_area_ram_session : public Ram_session +struct Stack_area_ram_session : Ram_session { - public: + Ram_dataspace_capability alloc(size_t, Cache_attribute) override { + return reinterpret_cap_cast(Native_capability()); } - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) { - return reinterpret_cap_cast(Native_capability()); } + void free(Ram_dataspace_capability) override { + warning(__func__, " not implemented"); } - void free(Ram_dataspace_capability ds) { - warning(__func__, " not implemented"); } + size_t dataspace_size(Ram_dataspace_capability) const override { return 0; } - int ref_account(Ram_session_capability ram_session) { return 0; } + int ref_account(Ram_session_capability ram_session) override { return 0; } - int transfer_quota(Ram_session_capability ram_session, size_t amount) { - return 0; } + int transfer_quota(Ram_session_capability ram_session, size_t amount) override { + return 0; } - size_t quota() { return 0; } + size_t quota() override { return 0; } - size_t used() { return 0; } + size_t used() override { return 0; } }; diff --git a/repos/base/include/base/heap.h b/repos/base/include/base/heap.h index 1baef1e86..117460341 100644 --- a/repos/base/include/base/heap.h +++ b/repos/base/include/base/heap.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include @@ -32,7 +32,8 @@ namespace Genode { * Heap that uses dataspaces as backing store * * The heap class provides an allocator that uses a list of dataspaces of a RAM - * session as backing store. One dataspace may be used for holding multiple blocks. + * allocator as backing store. One dataspace may be used for holding multiple + * blocks. */ class Genode::Heap : public Allocator { @@ -56,18 +57,18 @@ class Genode::Heap : public Allocator */ struct Dataspace_pool : public List { - Ram_session *ram_session; /* RAM session for backing store */ - Region_map *region_map; + Ram_allocator *ram_alloc; /* backing store */ + Region_map *region_map; - Dataspace_pool(Ram_session *ram, Region_map *rm) - : ram_session(ram), region_map(rm) { } + Dataspace_pool(Ram_allocator *ram, Region_map *rm) + : ram_alloc(ram), region_map(rm) { } ~Dataspace_pool(); void remove_and_free(Dataspace &); - void reassign_resources(Ram_session *ram, Region_map *rm) { - ram_session = ram, region_map = rm; } + void reassign_resources(Ram_allocator *ram, Region_map *rm) { + ram_alloc = ram, region_map = rm; } }; Lock _lock; @@ -108,13 +109,13 @@ class Genode::Heap : public Allocator enum { UNLIMITED = ~0 }; - Heap(Ram_session *ram_session, - Region_map *region_map, - size_t quota_limit = UNLIMITED, - void *static_addr = 0, - size_t static_size = 0); + Heap(Ram_allocator *ram_allocator, + Region_map *region_map, + size_t quota_limit = UNLIMITED, + void *static_addr = 0, + size_t static_size = 0); - Heap(Ram_session &ram, Region_map &rm) : Heap(&ram, &rm) { } + Heap(Ram_allocator &ram, Region_map &rm) : Heap(&ram, &rm) { } ~Heap(); @@ -127,9 +128,9 @@ class Genode::Heap : public Allocator int quota_limit(size_t new_quota_limit); /** - * Re-assign RAM and RM sessions + * Re-assign RAM allocator and region map */ - void reassign_resources(Ram_session *ram, Region_map *rm) { + void reassign_resources(Ram_allocator *ram, Region_map *rm) { _ds_pool.reassign_resources(ram, rm); } @@ -164,7 +165,7 @@ class Genode::Sliced_heap : public Allocator { } }; - Ram_session &_ram_session; /* RAM session for backing store */ + Ram_allocator &_ram_alloc; /* RAM allocator for backing store */ Region_map &_region_map; /* region map of the address space */ size_t _consumed; /* number of allocated bytes */ List _blocks; /* list of allocated blocks */ @@ -183,13 +184,13 @@ class Genode::Sliced_heap : public Allocator * \deprecated Use the other constructor that takes reference * arguments */ - Sliced_heap(Ram_session *ram_session, Region_map *region_map) - : Sliced_heap(*ram_session, *region_map) { } + Sliced_heap(Ram_allocator *ram_alloc, Region_map *region_map) + : Sliced_heap(*ram_alloc, *region_map) { } /** * Constructor */ - Sliced_heap(Ram_session &ram_session, Region_map ®ion_map); + Sliced_heap(Ram_allocator &ram_alloc, Region_map ®ion_map); /** * Destructor diff --git a/repos/base/include/base/ram_allocator.h b/repos/base/include/base/ram_allocator.h new file mode 100644 index 000000000..32933b799 --- /dev/null +++ b/repos/base/include/base/ram_allocator.h @@ -0,0 +1,124 @@ +/* + * \brief Interface for allocating RAM dataspaces + * \author Norman Feske + * \date 2017-05-02 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__BASE__RAM_ALLOCATOR_H_ +#define _INCLUDE__BASE__RAM_ALLOCATOR_H_ + +#include +#include +#include +#include + +namespace Genode { + + struct Ram_dataspace : Dataspace { }; + + typedef Capability Ram_dataspace_capability; + + struct Ram_allocator; + + class Constrained_ram_allocator; +} + + +struct Genode::Ram_allocator +{ + class Alloc_failed : public Exception { }; + class Quota_exceeded : public Alloc_failed { }; + class Out_of_metadata : public Alloc_failed { }; + + + /** + * Allocate RAM dataspace + * + * \param size size of RAM dataspace + * \param cached selects cacheability attributes of the memory, + * uncached memory, i.e., for DMA buffers + * + * \throw Quota_exceeded + * \throw Out_of_metadata + * + * \return capability to new RAM dataspace + */ + virtual Ram_dataspace_capability alloc(size_t size, + Cache_attribute cached = CACHED) = 0; + + /** + * Free RAM dataspace + * + * \param ds dataspace capability as returned by alloc + */ + virtual void free(Ram_dataspace_capability ds) = 0; + + /** + * Return size of dataspace in bytes + */ + virtual size_t dataspace_size(Ram_dataspace_capability ds) const = 0; +}; + + +/** + * Quota-bounds-checking wrapper of the 'Ram_allocator' interface + */ +class Genode::Constrained_ram_allocator : public Ram_allocator +{ + private: + + Ram_allocator &_ram_alloc; + Ram_quota_guard &_ram_guard; + Cap_quota_guard &_cap_guard; + + public: + + Constrained_ram_allocator(Ram_allocator &ram_alloc, + Ram_quota_guard &ram_guard, + Cap_quota_guard &cap_guard) + : + _ram_alloc(ram_alloc), _ram_guard(ram_guard), _cap_guard(cap_guard) + { } + + Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override + { + size_t page_aligned_size = align_addr(size, 12); + + Ram_quota_guard::Reservation ram (_ram_guard, Ram_quota{page_aligned_size}); + Cap_quota_guard::Reservation caps(_cap_guard, Cap_quota{1}); + + /* + * \throw Out_of_caps, Out_of_ram + */ + Ram_dataspace_capability ds = _ram_alloc.alloc(page_aligned_size, cached); + + ram. acknowledge(); + caps.acknowledge(); + + return ds; + } + + void free(Ram_dataspace_capability ds) override + { + size_t const size = _ram_alloc.dataspace_size(ds); + + _ram_alloc.free(ds); + + _ram_guard.replenish(Ram_quota{size}); + _cap_guard.replenish(Cap_quota{1}); + } + + size_t dataspace_size(Ram_dataspace_capability ds) const override + { + return _ram_alloc.dataspace_size(ds); + } +}; + +#endif /* _INCLUDE__BASE__RAM_ALLOCATOR_H_ */ diff --git a/repos/base/include/ram_session/client.h b/repos/base/include/ram_session/client.h index ccb7f80ea..7cef5ef88 100644 --- a/repos/base/include/ram_session/client.h +++ b/repos/base/include/ram_session/client.h @@ -16,7 +16,7 @@ #include #include -#include +#include namespace Genode { struct Ram_session_client; } @@ -27,11 +27,18 @@ struct Genode::Ram_session_client : Rpc_client : Rpc_client(session) { } Ram_dataspace_capability alloc(size_t size, - Cache_attribute cached = CACHED) override { - return call(size, cached); } + Cache_attribute cached = CACHED) override + { + return call(size, cached); + } void free(Ram_dataspace_capability ds) override { call(ds); } + size_t dataspace_size(Ram_dataspace_capability ds) const override + { + return ds.valid() ? Dataspace_client(ds).size() : 0; + } + int ref_account(Ram_session_capability ram_session) override { return call(ram_session); } diff --git a/repos/base/include/ram_session/ram_session.h b/repos/base/include/ram_session/ram_session.h index fe21cbe20..498060141 100644 --- a/repos/base/include/ram_session/ram_session.h +++ b/repos/base/include/ram_session/ram_session.h @@ -15,9 +15,7 @@ #define _INCLUDE__RAM_SESSION__RAM_SESSION_H_ #include -#include -#include -#include +#include #include #include #include @@ -32,13 +30,10 @@ namespace Genode { } -struct Genode::Ram_dataspace : Dataspace { }; - - /** * RAM session interface */ -struct Genode::Ram_session : Session +struct Genode::Ram_session : Session, Ram_allocator { static const char *service_name() { return "RAM"; } @@ -47,40 +42,11 @@ struct Genode::Ram_session : Session typedef Ram_session_client Client; - /********************* - ** Exception types ** - *********************/ - - class Alloc_failed : public Exception { }; - class Quota_exceeded : public Alloc_failed { }; - class Out_of_metadata : public Alloc_failed { }; - /** * Destructor */ virtual ~Ram_session() { } - /** - * Allocate RAM dataspace - * - * \param size size of RAM dataspace - * \param cached selects cacheability attributes of the memory, - * uncached memory, i.e., for DMA buffers - * - * \throw Quota_exceeded - * \throw Out_of_metadata - * \return capability to new RAM dataspace - */ - virtual Ram_dataspace_capability alloc(size_t size, - Cache_attribute cached = CACHED) = 0; - - /** - * Free RAM dataspace - * - * \param ds dataspace capability as returned by alloc - */ - virtual void free(Ram_dataspace_capability ds) = 0; - /** * Define reference account for the RAM session * diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld index eb820dd2f..3cb2bf6b9 100644 --- a/repos/base/lib/symbols/ld +++ b/repos/base/lib/symbols/ld @@ -63,8 +63,8 @@ _ZN6Genode10Ipc_serverD1Ev T _ZN6Genode10Ipc_serverD2Ev T _ZN6Genode11Sliced_heap4freeEPvm T _ZN6Genode11Sliced_heap5allocEmPPv T -_ZN6Genode11Sliced_heapC1ERNS_11Ram_sessionERNS_10Region_mapE T -_ZN6Genode11Sliced_heapC2ERNS_11Ram_sessionERNS_10Region_mapE T +_ZN6Genode11Sliced_heapC1ERNS_13Ram_allocatorERNS_10Region_mapE T +_ZN6Genode11Sliced_heapC2ERNS_13Ram_allocatorERNS_10Region_mapE T _ZN6Genode11Sliced_heapD0Ev T _ZN6Genode11Sliced_heapD1Ev T _ZN6Genode11Sliced_heapD2Ev T @@ -199,8 +199,8 @@ _ZN6Genode14env_deprecatedEv T _ZN6Genode4Heap11quota_limitEm T _ZN6Genode4Heap4freeEPvm T _ZN6Genode4Heap5allocEmPPv T -_ZN6Genode4HeapC1EPNS_11Ram_sessionEPNS_10Region_mapEmPvm T -_ZN6Genode4HeapC2EPNS_11Ram_sessionEPNS_10Region_mapEmPvm T +_ZN6Genode4HeapC1EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T +_ZN6Genode4HeapC2EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T _ZN6Genode4HeapD0Ev T _ZN6Genode4HeapD1Ev T _ZN6Genode4HeapD2Ev T diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index f3c2f3470..d5862debd 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -51,7 +51,7 @@ namespace Genode { { private: - Lock _lock; + Lock mutable _lock; public: @@ -84,6 +84,12 @@ namespace Genode { RAM_SESSION_IMPL::free(ds); } + size_t dataspace_size(Ram_dataspace_capability ds) const override + { + Lock::Guard lock_guard(_lock); + return RAM_SESSION_IMPL::dataspace_size(ds); + } + int ref_account(Ram_session_capability session) { Lock::Guard lock_guard(_lock); diff --git a/repos/base/src/core/include/dataspace_component.h b/repos/base/src/core/include/dataspace_component.h index e3616b11d..cacad38b7 100644 --- a/repos/base/src/core/include/dataspace_component.h +++ b/repos/base/src/core/include/dataspace_component.h @@ -147,7 +147,7 @@ namespace Genode { /** * Check if dataspace is owned by a specific owner */ - bool owner(Dataspace_owner * const o) const { return _owner == o; } + bool owner(Dataspace_owner const *o) const { return _owner == o; } List *regions() { return &_regions; } diff --git a/repos/base/src/core/include/ram_session_component.h b/repos/base/src/core/include/ram_session_component.h index 9285ea77b..45a89983d 100644 --- a/repos/base/src/core/include/ram_session_component.h +++ b/repos/base/src/core/include/ram_session_component.h @@ -163,12 +163,22 @@ namespace Genode { */ 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 ** ***************************/ - Ram_dataspace_capability alloc(size_t, Cache_attribute); - void free(Ram_dataspace_capability); int ref_account(Ram_session_capability); int transfer_quota(Ram_session_capability, size_t); size_t quota() { return _quota_limit; } diff --git a/repos/base/src/core/ram_session_component.cc b/repos/base/src/core/ram_session_component.cc index 0cf4c6d57..516e1ca07 100644 --- a/repos/base/src/core/ram_session_component.cc +++ b/repos/base/src/core/ram_session_component.cc @@ -236,6 +236,20 @@ void Ram_session_component::free(Ram_dataspace_capability ds_cap) { _free_ds(ds_cap); } +size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) const +{ + if (this->cap() == ds_cap) + return 0; + + size_t result = 0; + _ds_ep->apply(ds_cap, [&] (Dataspace_component *c) { + if (c && c->owner(this)) + result = c->size(); }); + + return result; +} + + int Ram_session_component::ref_account(Ram_session_capability ram_session_cap) { /* the reference account cannot be defined twice */ diff --git a/repos/base/src/core/stack_area.cc b/repos/base/src/core/stack_area.cc index 562173b03..58705e2d0 100644 --- a/repos/base/src/core/stack_area.cc +++ b/repos/base/src/core/stack_area.cc @@ -125,18 +125,19 @@ class Stack_area_region_map : public Region_map }; -class Stack_area_ram_session : public Ram_session +struct Stack_area_ram_session : Ram_session { - public: + Ram_dataspace_capability alloc(size_t, Cache_attribute) override { + return reinterpret_cap_cast(Native_capability()); } - Ram_dataspace_capability alloc(size_t, Cache_attribute) override { - return reinterpret_cap_cast(Native_capability()); } + void free(Ram_dataspace_capability) override { } - void free (Ram_dataspace_capability) override { } - int ref_account (Ram_session_capability) override { return 0; } - int transfer_quota (Ram_session_capability, size_t) override { return 0; } - size_t quota () override { return 0; } - size_t used () override { return 0; } + 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, size_t) override { return 0; } + size_t quota () override { return 0; } + size_t used () override { return 0; } }; diff --git a/repos/base/src/lib/base/heap.cc b/repos/base/src/lib/base/heap.cc index 1fa900393..91e32be3b 100644 --- a/repos/base/src/lib/base/heap.cc +++ b/repos/base/src/lib/base/heap.cc @@ -58,7 +58,7 @@ void Heap::Dataspace_pool::remove_and_free(Dataspace &ds) ds.~Dataspace(); region_map->detach(ds_local_addr); - ram_session->free(ds_cap); + ram_alloc->free(ds_cap); } @@ -87,13 +87,13 @@ Heap::Dataspace *Heap::_allocate_dataspace(size_t size, bool enforce_separate_me /* make new ram dataspace available at our local address space */ try { - new_ds_cap = _ds_pool.ram_session->alloc(size); + new_ds_cap = _ds_pool.ram_alloc->alloc(size); ds_addr = _ds_pool.region_map->attach(new_ds_cap); } catch (Ram_session::Alloc_failed) { return 0; } catch (Region_map::Attach_failed) { warning("could not attach dataspace"); - _ds_pool.ram_session->free(new_ds_cap); + _ds_pool.ram_alloc->free(new_ds_cap); return 0; } @@ -258,14 +258,14 @@ void Heap::free(void *addr, size_t) } -Heap::Heap(Ram_session *ram_session, - Region_map *region_map, - size_t quota_limit, - void *static_addr, - size_t static_size) +Heap::Heap(Ram_allocator *ram_alloc, + Region_map *region_map, + size_t quota_limit, + void *static_addr, + size_t static_size) : _alloc(nullptr), - _ds_pool(ram_session, region_map), + _ds_pool(ram_alloc, region_map), _quota_limit(quota_limit), _quota_used(0), _chunk_size(MIN_CHUNK_SIZE) { diff --git a/repos/base/src/lib/base/sliced_heap.cc b/repos/base/src/lib/base/sliced_heap.cc index 8214ba046..dacb74ad4 100644 --- a/repos/base/src/lib/base/sliced_heap.cc +++ b/repos/base/src/lib/base/sliced_heap.cc @@ -18,9 +18,9 @@ using namespace Genode; -Sliced_heap::Sliced_heap(Ram_session &ram_session, Region_map ®ion_map) +Sliced_heap::Sliced_heap(Ram_allocator &ram_alloc, Region_map ®ion_map) : - _ram_session(ram_session), _region_map(region_map), _consumed(0) + _ram_alloc(ram_alloc), _region_map(region_map), _consumed(0) { } @@ -47,13 +47,13 @@ bool Sliced_heap::alloc(size_t size, void **out_addr) Block *block = nullptr; try { - ds_cap = _ram_session.alloc(size); + ds_cap = _ram_alloc.alloc(size); block = _region_map.attach(ds_cap); } catch (Region_map::Attach_failed) { error("could not attach dataspace to local address space"); - _ram_session.free(ds_cap); + _ram_alloc.free(ds_cap); return false; - } catch (Ram_session::Alloc_failed) { + } catch (Ram_allocator::Alloc_failed) { error("could not allocate dataspace with size ", size); return false; } @@ -101,7 +101,7 @@ void Sliced_heap::free(void *addr, size_t size) } _region_map.detach(local_addr); - _ram_session.free(ds_cap); + _ram_alloc.free(ds_cap); } diff --git a/repos/os/include/os/ram_session_guard.h b/repos/os/include/os/ram_session_guard.h index d8dba030a..134b7aab0 100644 --- a/repos/os/include/os/ram_session_guard.h +++ b/repos/os/include/os/ram_session_guard.h @@ -131,6 +131,11 @@ class Genode::Ram_session_guard : public Genode::Ram_session _used -= size; } + size_t dataspace_size(Ram_dataspace_capability ds) const override + { + return _session.dataspace_size(ds); + } + int ref_account(Ram_session_capability ram_session) override { return _session.ref_account(ram_session); } 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 e9ff8fd58..6d86581eb 100644 --- a/repos/os/src/server/loader/ram_session_client_guard.h +++ b/repos/os/src/server/loader/ram_session_client_guard.h @@ -25,16 +25,16 @@ namespace Genode { { private: - size_t _amount; /* total amount */ - size_t _consumed; /* already consumed bytes */ - Lock _consumed_lock; + size_t const _amount; /* total amount */ + size_t _consumed; /* already consumed bytes */ + Lock mutable _consumed_lock; public: Ram_session_client_guard(Ram_session_capability session, size_t amount) : Ram_session_client(session), _amount(amount), _consumed(0) { } - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) + Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override { Lock::Guard _consumed_lock_guard(_consumed_lock); @@ -52,7 +52,7 @@ namespace Genode { return cap; } - void free(Ram_dataspace_capability ds) + void free(Ram_dataspace_capability ds) override { Lock::Guard _consumed_lock_guard(_consumed_lock); @@ -61,7 +61,12 @@ namespace Genode { Ram_session_client::free(ds); } - int transfer_quota(Ram_session_capability ram_session, size_t amount) + size_t dataspace_size(Ram_dataspace_capability ds) const override + { + return Ram_session_client::dataspace_size(ds); + } + + int transfer_quota(Ram_session_capability ram_session, size_t amount) override { Lock::Guard _consumed_lock_guard(_consumed_lock); @@ -79,12 +84,12 @@ namespace Genode { return result; } - size_t quota() + size_t quota() override { return _amount; } - size_t used() + size_t used() override { Lock::Guard _consumed_lock_guard(_consumed_lock); return _consumed; 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 ccc7261ac..d2b298f20 100644 --- a/repos/ports/src/app/gdb_monitor/ram_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/ram_session_component.cc @@ -43,6 +43,12 @@ void Ram_session_component::free(Ram_dataspace_capability ds_cap) } +size_t Ram_session_component::dataspace_size(Ram_dataspace_capability ds_cap) const +{ + return _parent_ram_session.dataspace_size(ds_cap); +} + + int Ram_session_component::ref_account(Ram_session_capability ram_session_cap) { return _parent_ram_session.ref_account(ram_session_cap); 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 287750350..b61f892dc 100644 --- a/repos/ports/src/app/gdb_monitor/ram_session_component.h +++ b/repos/ports/src/app/gdb_monitor/ram_session_component.h @@ -56,12 +56,13 @@ class Gdb_monitor::Ram_session_component : public Rpc_object ** RAM Session interface ** ***************************/ - Ram_dataspace_capability alloc(size_t, Cache_attribute); - void free(Ram_dataspace_capability); - int ref_account(Ram_session_capability); - int transfer_quota(Ram_session_capability, size_t); - size_t quota(); - size_t used(); + 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, size_t) override; + size_t quota() override; + size_t used() override; }; #endif /* _RAM_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/noux/ram_session_component.h b/repos/ports/src/noux/ram_session_component.h index 6125f76d4..45688d4de 100644 --- a/repos/ports/src/noux/ram_session_component.h +++ b/repos/ports/src/noux/ram_session_component.h @@ -106,7 +106,7 @@ class Noux::Ram_session_component : public Rpc_object * * XXX not used yet */ - size_t _used_quota; + size_t _used_ram_quota = 0; Dataspace_registry &_registry; @@ -118,8 +118,7 @@ class Noux::Ram_session_component : public Rpc_object Ram_session_component(Ram_session &ram, Allocator &alloc, Rpc_entrypoint &ep, Dataspace_registry ®istry) : - _ram(ram), _alloc(alloc), _ep(ep), _used_quota(0), - _registry(registry) + _ram(ram), _alloc(alloc), _ep(ep), _registry(registry) { _ep.manage(this); } @@ -140,14 +139,14 @@ class Noux::Ram_session_component : public Rpc_object ** Ram_session interface ** ***************************/ - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) + Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override { Ram_dataspace_capability ds_cap = _ram.alloc(size, cached); Ram_dataspace_info *ds_info = new (_alloc) Ram_dataspace_info(ds_cap); - _used_quota += ds_info->size(); + _used_ram_quota += ds_info->size(); _registry.insert(ds_info); _list.insert(ds_info); @@ -155,7 +154,7 @@ class Noux::Ram_session_component : public Rpc_object return ds_cap; } - void free(Ram_dataspace_capability ds_cap) + void free(Ram_dataspace_capability ds_cap) override { Ram_dataspace_info *ds_info; @@ -172,7 +171,7 @@ class Noux::Ram_session_component : public Rpc_object ds_info->dissolve_users(); _list.remove(ds_info); - _used_quota -= ds_info->size(); + _used_ram_quota -= ds_info->size(); _ram.free(ds_cap); }; @@ -180,10 +179,19 @@ class Noux::Ram_session_component : public Rpc_object destroy(_alloc, ds_info); } + size_t dataspace_size(Ram_dataspace_capability ds_cap) const override + { + size_t result = 0; + _registry.apply(ds_cap, [&] (Ram_dataspace_info *rdi) { + if (rdi) + result = rdi->size(); }); + return result; + } + int ref_account(Ram_session_capability) { return 0; } int transfer_quota(Ram_session_capability, size_t) { return 0; } size_t quota() { return _ram.quota(); } - size_t used() { return _used_quota; } + size_t used() { return _used_ram_quota; } }; #endif /* _NOUX__RAM_SESSION_COMPONENT_H_ */