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
This commit is contained in:
Norman Feske 2017-05-07 23:49:43 +02:00 committed by Christian Helmuth
parent 5a468919bb
commit ff68d77c7d
21 changed files with 297 additions and 136 deletions

View File

@ -48,7 +48,7 @@ namespace Genode {
{ {
private: private:
Lock _lock; Lock mutable _lock;
public: public:
@ -82,6 +82,12 @@ namespace Genode {
RAM_SESSION_IMPL::free(ds); 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) int ref_account(Ram_session_capability session)
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);

View File

@ -100,7 +100,7 @@ namespace Genode {
/** /**
* Check if dataspace is owned by a specified object * 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. * Detach dataspace from all rm sessions.

View File

@ -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::Ram_dataspace_capability alloc(Genode::size_t size,
Genode::Cache_attribute) { Genode::Cache_attribute) override {
return Genode::Ram_dataspace_capability(); } 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; }
}; };

View File

@ -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<Ram_dataspace>(Native_capability()); }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) { void free(Ram_dataspace_capability) override {
return reinterpret_cap_cast<Ram_dataspace>(Native_capability()); } warning(__func__, " not implemented"); }
void free(Ram_dataspace_capability ds) { size_t dataspace_size(Ram_dataspace_capability) const override { return 0; }
warning(__func__, " not implemented"); }
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) { int transfer_quota(Ram_session_capability ram_session, size_t amount) override {
return 0; } return 0; }
size_t quota() { return 0; } size_t quota() override { return 0; }
size_t used() { return 0; } size_t used() override { return 0; }
}; };

View File

@ -16,7 +16,7 @@
#include <util/list.h> #include <util/list.h>
#include <util/reconstructible.h> #include <util/reconstructible.h>
#include <ram_session/ram_session.h> #include <base/ram_allocator.h>
#include <region_map/region_map.h> #include <region_map/region_map.h>
#include <base/allocator_avl.h> #include <base/allocator_avl.h>
#include <base/lock.h> #include <base/lock.h>
@ -32,7 +32,8 @@ namespace Genode {
* Heap that uses dataspaces as backing store * Heap that uses dataspaces as backing store
* *
* The heap class provides an allocator that uses a list of dataspaces of a RAM * 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 class Genode::Heap : public Allocator
{ {
@ -56,18 +57,18 @@ class Genode::Heap : public Allocator
*/ */
struct Dataspace_pool : public List<Dataspace> struct Dataspace_pool : public List<Dataspace>
{ {
Ram_session *ram_session; /* RAM session for backing store */ Ram_allocator *ram_alloc; /* backing store */
Region_map *region_map; Region_map *region_map;
Dataspace_pool(Ram_session *ram, Region_map *rm) Dataspace_pool(Ram_allocator *ram, Region_map *rm)
: ram_session(ram), region_map(rm) { } : ram_alloc(ram), region_map(rm) { }
~Dataspace_pool(); ~Dataspace_pool();
void remove_and_free(Dataspace &); void remove_and_free(Dataspace &);
void reassign_resources(Ram_session *ram, Region_map *rm) { void reassign_resources(Ram_allocator *ram, Region_map *rm) {
ram_session = ram, region_map = rm; } ram_alloc = ram, region_map = rm; }
}; };
Lock _lock; Lock _lock;
@ -108,13 +109,13 @@ class Genode::Heap : public Allocator
enum { UNLIMITED = ~0 }; enum { UNLIMITED = ~0 };
Heap(Ram_session *ram_session, Heap(Ram_allocator *ram_allocator,
Region_map *region_map, Region_map *region_map,
size_t quota_limit = UNLIMITED, size_t quota_limit = UNLIMITED,
void *static_addr = 0, void *static_addr = 0,
size_t static_size = 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(); ~Heap();
@ -127,9 +128,9 @@ class Genode::Heap : public Allocator
int quota_limit(size_t new_quota_limit); 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); } _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 */ Region_map &_region_map; /* region map of the address space */
size_t _consumed; /* number of allocated bytes */ size_t _consumed; /* number of allocated bytes */
List<Block> _blocks; /* list of allocated blocks */ List<Block> _blocks; /* list of allocated blocks */
@ -183,13 +184,13 @@ class Genode::Sliced_heap : public Allocator
* \deprecated Use the other constructor that takes reference * \deprecated Use the other constructor that takes reference
* arguments * arguments
*/ */
Sliced_heap(Ram_session *ram_session, Region_map *region_map) Sliced_heap(Ram_allocator *ram_alloc, Region_map *region_map)
: Sliced_heap(*ram_session, *region_map) { } : Sliced_heap(*ram_alloc, *region_map) { }
/** /**
* Constructor * Constructor
*/ */
Sliced_heap(Ram_session &ram_session, Region_map &region_map); Sliced_heap(Ram_allocator &ram_alloc, Region_map &region_map);
/** /**
* Destructor * Destructor

View File

@ -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 <base/capability.h>
#include <base/quota_guard.h>
#include <base/cache.h>
#include <dataspace/dataspace.h>
namespace Genode {
struct Ram_dataspace : Dataspace { };
typedef Capability<Ram_dataspace> 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_ */

View File

@ -16,7 +16,7 @@
#include <ram_session/capability.h> #include <ram_session/capability.h>
#include <ram_session/ram_session.h> #include <ram_session/ram_session.h>
#include <base/rpc_client.h> #include <dataspace/client.h>
namespace Genode { struct Ram_session_client; } namespace Genode { struct Ram_session_client; }
@ -27,11 +27,18 @@ struct Genode::Ram_session_client : Rpc_client<Ram_session>
: Rpc_client<Ram_session>(session) { } : Rpc_client<Ram_session>(session) { }
Ram_dataspace_capability alloc(size_t size, Ram_dataspace_capability alloc(size_t size,
Cache_attribute cached = CACHED) override { Cache_attribute cached = CACHED) override
return call<Rpc_alloc>(size, cached); } {
return call<Rpc_alloc>(size, cached);
}
void free(Ram_dataspace_capability ds) override { call<Rpc_free>(ds); } void free(Ram_dataspace_capability ds) override { call<Rpc_free>(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 { int ref_account(Ram_session_capability ram_session) override {
return call<Rpc_ref_account>(ram_session); } return call<Rpc_ref_account>(ram_session); }

View File

@ -15,9 +15,7 @@
#define _INCLUDE__RAM_SESSION__RAM_SESSION_H_ #define _INCLUDE__RAM_SESSION__RAM_SESSION_H_
#include <base/stdint.h> #include <base/stdint.h>
#include <base/capability.h> #include <base/ram_allocator.h>
#include <base/exception.h>
#include <base/cache.h>
#include <dataspace/capability.h> #include <dataspace/capability.h>
#include <ram_session/capability.h> #include <ram_session/capability.h>
#include <session/session.h> #include <session/session.h>
@ -32,13 +30,10 @@ namespace Genode {
} }
struct Genode::Ram_dataspace : Dataspace { };
/** /**
* RAM session interface * RAM session interface
*/ */
struct Genode::Ram_session : Session struct Genode::Ram_session : Session, Ram_allocator
{ {
static const char *service_name() { return "RAM"; } static const char *service_name() { return "RAM"; }
@ -47,40 +42,11 @@ struct Genode::Ram_session : Session
typedef Ram_session_client Client; 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 * Destructor
*/ */
virtual ~Ram_session() { } 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 * Define reference account for the RAM session
* *

View File

@ -63,8 +63,8 @@ _ZN6Genode10Ipc_serverD1Ev T
_ZN6Genode10Ipc_serverD2Ev T _ZN6Genode10Ipc_serverD2Ev T
_ZN6Genode11Sliced_heap4freeEPvm T _ZN6Genode11Sliced_heap4freeEPvm T
_ZN6Genode11Sliced_heap5allocEmPPv T _ZN6Genode11Sliced_heap5allocEmPPv T
_ZN6Genode11Sliced_heapC1ERNS_11Ram_sessionERNS_10Region_mapE T _ZN6Genode11Sliced_heapC1ERNS_13Ram_allocatorERNS_10Region_mapE T
_ZN6Genode11Sliced_heapC2ERNS_11Ram_sessionERNS_10Region_mapE T _ZN6Genode11Sliced_heapC2ERNS_13Ram_allocatorERNS_10Region_mapE T
_ZN6Genode11Sliced_heapD0Ev T _ZN6Genode11Sliced_heapD0Ev T
_ZN6Genode11Sliced_heapD1Ev T _ZN6Genode11Sliced_heapD1Ev T
_ZN6Genode11Sliced_heapD2Ev T _ZN6Genode11Sliced_heapD2Ev T
@ -199,8 +199,8 @@ _ZN6Genode14env_deprecatedEv T
_ZN6Genode4Heap11quota_limitEm T _ZN6Genode4Heap11quota_limitEm T
_ZN6Genode4Heap4freeEPvm T _ZN6Genode4Heap4freeEPvm T
_ZN6Genode4Heap5allocEmPPv T _ZN6Genode4Heap5allocEmPPv T
_ZN6Genode4HeapC1EPNS_11Ram_sessionEPNS_10Region_mapEmPvm T _ZN6Genode4HeapC1EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T
_ZN6Genode4HeapC2EPNS_11Ram_sessionEPNS_10Region_mapEmPvm T _ZN6Genode4HeapC2EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T
_ZN6Genode4HeapD0Ev T _ZN6Genode4HeapD0Ev T
_ZN6Genode4HeapD1Ev T _ZN6Genode4HeapD1Ev T
_ZN6Genode4HeapD2Ev T _ZN6Genode4HeapD2Ev T

View File

@ -51,7 +51,7 @@ namespace Genode {
{ {
private: private:
Lock _lock; Lock mutable _lock;
public: public:
@ -84,6 +84,12 @@ namespace Genode {
RAM_SESSION_IMPL::free(ds); 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) int ref_account(Ram_session_capability session)
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);

View File

@ -147,7 +147,7 @@ namespace Genode {
/** /**
* Check if dataspace is owned by a specific owner * 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<Rm_region> *regions() { return &_regions; } List<Rm_region> *regions() { return &_regions; }

View File

@ -163,12 +163,22 @@ namespace Genode {
*/ */
addr_t phys_addr(Ram_dataspace_capability ds); 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 Session interface **
***************************/ ***************************/
Ram_dataspace_capability alloc(size_t, Cache_attribute);
void free(Ram_dataspace_capability);
int ref_account(Ram_session_capability); int ref_account(Ram_session_capability);
int transfer_quota(Ram_session_capability, size_t); int transfer_quota(Ram_session_capability, size_t);
size_t quota() { return _quota_limit; } size_t quota() { return _quota_limit; }

View File

@ -236,6 +236,20 @@ void Ram_session_component::free(Ram_dataspace_capability ds_cap) {
_free_ds(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) int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
{ {
/* the reference account cannot be defined twice */ /* the reference account cannot be defined twice */

View File

@ -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<Ram_dataspace>(Native_capability()); }
Ram_dataspace_capability alloc(size_t, Cache_attribute) override { void free(Ram_dataspace_capability) override { }
return reinterpret_cap_cast<Ram_dataspace>(Native_capability()); }
void free (Ram_dataspace_capability) override { } 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; } int ref_account (Ram_session_capability) override { return 0; }
size_t quota () override { return 0; } int transfer_quota (Ram_session_capability, size_t) override { return 0; }
size_t used () override { return 0; } size_t quota () override { return 0; }
size_t used () override { return 0; }
}; };

View File

@ -58,7 +58,7 @@ void Heap::Dataspace_pool::remove_and_free(Dataspace &ds)
ds.~Dataspace(); ds.~Dataspace();
region_map->detach(ds_local_addr); 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 */ /* make new ram dataspace available at our local address space */
try { 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); ds_addr = _ds_pool.region_map->attach(new_ds_cap);
} catch (Ram_session::Alloc_failed) { } catch (Ram_session::Alloc_failed) {
return 0; return 0;
} catch (Region_map::Attach_failed) { } catch (Region_map::Attach_failed) {
warning("could not attach dataspace"); warning("could not attach dataspace");
_ds_pool.ram_session->free(new_ds_cap); _ds_pool.ram_alloc->free(new_ds_cap);
return 0; return 0;
} }
@ -258,14 +258,14 @@ void Heap::free(void *addr, size_t)
} }
Heap::Heap(Ram_session *ram_session, Heap::Heap(Ram_allocator *ram_alloc,
Region_map *region_map, Region_map *region_map,
size_t quota_limit, size_t quota_limit,
void *static_addr, void *static_addr,
size_t static_size) size_t static_size)
: :
_alloc(nullptr), _alloc(nullptr),
_ds_pool(ram_session, region_map), _ds_pool(ram_alloc, region_map),
_quota_limit(quota_limit), _quota_used(0), _quota_limit(quota_limit), _quota_used(0),
_chunk_size(MIN_CHUNK_SIZE) _chunk_size(MIN_CHUNK_SIZE)
{ {

View File

@ -18,9 +18,9 @@
using namespace Genode; using namespace Genode;
Sliced_heap::Sliced_heap(Ram_session &ram_session, Region_map &region_map) Sliced_heap::Sliced_heap(Ram_allocator &ram_alloc, Region_map &region_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; Block *block = nullptr;
try { try {
ds_cap = _ram_session.alloc(size); ds_cap = _ram_alloc.alloc(size);
block = _region_map.attach(ds_cap); block = _region_map.attach(ds_cap);
} catch (Region_map::Attach_failed) { } catch (Region_map::Attach_failed) {
error("could not attach dataspace to local address space"); error("could not attach dataspace to local address space");
_ram_session.free(ds_cap); _ram_alloc.free(ds_cap);
return false; return false;
} catch (Ram_session::Alloc_failed) { } catch (Ram_allocator::Alloc_failed) {
error("could not allocate dataspace with size ", size); error("could not allocate dataspace with size ", size);
return false; return false;
} }
@ -101,7 +101,7 @@ void Sliced_heap::free(void *addr, size_t size)
} }
_region_map.detach(local_addr); _region_map.detach(local_addr);
_ram_session.free(ds_cap); _ram_alloc.free(ds_cap);
} }

View File

@ -131,6 +131,11 @@ class Genode::Ram_session_guard : public Genode::Ram_session
_used -= size; _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 { int ref_account(Ram_session_capability ram_session) override {
return _session.ref_account(ram_session); } return _session.ref_account(ram_session); }

View File

@ -25,16 +25,16 @@ namespace Genode {
{ {
private: private:
size_t _amount; /* total amount */ size_t const _amount; /* total amount */
size_t _consumed; /* already consumed bytes */ size_t _consumed; /* already consumed bytes */
Lock _consumed_lock; Lock mutable _consumed_lock;
public: public:
Ram_session_client_guard(Ram_session_capability session, size_t amount) Ram_session_client_guard(Ram_session_capability session, size_t amount)
: Ram_session_client(session), _amount(amount), _consumed(0) { } : 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); Lock::Guard _consumed_lock_guard(_consumed_lock);
@ -52,7 +52,7 @@ namespace Genode {
return cap; return cap;
} }
void free(Ram_dataspace_capability ds) void free(Ram_dataspace_capability ds) override
{ {
Lock::Guard _consumed_lock_guard(_consumed_lock); Lock::Guard _consumed_lock_guard(_consumed_lock);
@ -61,7 +61,12 @@ namespace Genode {
Ram_session_client::free(ds); 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); Lock::Guard _consumed_lock_guard(_consumed_lock);
@ -79,12 +84,12 @@ namespace Genode {
return result; return result;
} }
size_t quota() size_t quota() override
{ {
return _amount; return _amount;
} }
size_t used() size_t used() override
{ {
Lock::Guard _consumed_lock_guard(_consumed_lock); Lock::Guard _consumed_lock_guard(_consumed_lock);
return _consumed; return _consumed;

View File

@ -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) int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
{ {
return _parent_ram_session.ref_account(ram_session_cap); return _parent_ram_session.ref_account(ram_session_cap);

View File

@ -56,12 +56,13 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
** RAM Session interface ** ** RAM Session interface **
***************************/ ***************************/
Ram_dataspace_capability alloc(size_t, Cache_attribute); Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
void free(Ram_dataspace_capability); void free(Ram_dataspace_capability) override;
int ref_account(Ram_session_capability); size_t dataspace_size(Ram_dataspace_capability) const override;
int transfer_quota(Ram_session_capability, size_t); int ref_account(Ram_session_capability) override;
size_t quota(); int transfer_quota(Ram_session_capability, size_t) override;
size_t used(); size_t quota() override;
size_t used() override;
}; };
#endif /* _RAM_SESSION_COMPONENT_H_ */ #endif /* _RAM_SESSION_COMPONENT_H_ */

View File

@ -106,7 +106,7 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
* *
* XXX not used yet * XXX not used yet
*/ */
size_t _used_quota; size_t _used_ram_quota = 0;
Dataspace_registry &_registry; Dataspace_registry &_registry;
@ -118,8 +118,7 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
Ram_session_component(Ram_session &ram, Allocator &alloc, Ram_session_component(Ram_session &ram, Allocator &alloc,
Rpc_entrypoint &ep, Dataspace_registry &registry) Rpc_entrypoint &ep, Dataspace_registry &registry)
: :
_ram(ram), _alloc(alloc), _ep(ep), _used_quota(0), _ram(ram), _alloc(alloc), _ep(ep), _registry(registry)
_registry(registry)
{ {
_ep.manage(this); _ep.manage(this);
} }
@ -140,14 +139,14 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
** Ram_session interface ** ** 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_dataspace_capability ds_cap =
_ram.alloc(size, cached); _ram.alloc(size, cached);
Ram_dataspace_info *ds_info = new (_alloc) Ram_dataspace_info(ds_cap); 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); _registry.insert(ds_info);
_list.insert(ds_info); _list.insert(ds_info);
@ -155,7 +154,7 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
return ds_cap; return ds_cap;
} }
void free(Ram_dataspace_capability ds_cap) void free(Ram_dataspace_capability ds_cap) override
{ {
Ram_dataspace_info *ds_info; Ram_dataspace_info *ds_info;
@ -172,7 +171,7 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
ds_info->dissolve_users(); ds_info->dissolve_users();
_list.remove(ds_info); _list.remove(ds_info);
_used_quota -= ds_info->size(); _used_ram_quota -= ds_info->size();
_ram.free(ds_cap); _ram.free(ds_cap);
}; };
@ -180,10 +179,19 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
destroy(_alloc, ds_info); 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 ref_account(Ram_session_capability) { return 0; }
int transfer_quota(Ram_session_capability, size_t) { return 0; } int transfer_quota(Ram_session_capability, size_t) { return 0; }
size_t quota() { return _ram.quota(); } 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_ */ #endif /* _NOUX__RAM_SESSION_COMPONENT_H_ */