mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
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:
parent
5a468919bb
commit
ff68d77c7d
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
return reinterpret_cap_cast<Ram_dataspace>(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; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include <util/list.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <base/ram_allocator.h>
|
||||
#include <region_map/region_map.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/lock.h>
|
||||
@ -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<Dataspace>
|
||||
{
|
||||
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<Block> _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
|
||||
|
124
repos/base/include/base/ram_allocator.h
Normal file
124
repos/base/include/base/ram_allocator.h
Normal 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_ */
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include <ram_session/capability.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <base/rpc_client.h>
|
||||
#include <dataspace/client.h>
|
||||
|
||||
namespace Genode { struct Ram_session_client; }
|
||||
|
||||
@ -27,11 +27,18 @@ struct Genode::Ram_session_client : Rpc_client<Ram_session>
|
||||
: Rpc_client<Ram_session>(session) { }
|
||||
|
||||
Ram_dataspace_capability alloc(size_t size,
|
||||
Cache_attribute cached = CACHED) override {
|
||||
return call<Rpc_alloc>(size, cached); }
|
||||
Cache_attribute cached = CACHED) override
|
||||
{
|
||||
return call<Rpc_alloc>(size, cached);
|
||||
}
|
||||
|
||||
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 {
|
||||
return call<Rpc_ref_account>(ram_session); }
|
||||
|
||||
|
@ -15,9 +15,7 @@
|
||||
#define _INCLUDE__RAM_SESSION__RAM_SESSION_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <base/capability.h>
|
||||
#include <base/exception.h>
|
||||
#include <base/cache.h>
|
||||
#include <base/ram_allocator.h>
|
||||
#include <dataspace/capability.h>
|
||||
#include <ram_session/capability.h>
|
||||
#include <session/session.h>
|
||||
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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<Rm_region> *regions() { return &_regions; }
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
return reinterpret_cap_cast<Ram_dataspace>(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; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -56,12 +56,13 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
|
||||
** 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_ */
|
||||
|
@ -106,7 +106,7 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
|
||||
*
|
||||
* 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>
|
||||
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>
|
||||
** 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<Ram_session>
|
||||
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<Ram_session>
|
||||
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<Ram_session>
|
||||
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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user