base: use 'Ram_quota' in 'Ram_session' args

This patch replaces the former use of size_t with the use of the
'Ram_quota' type to improve type safety (in particular to avoid
accidentally mixing up RAM quotas with cap quotas).

Issue #2398
This commit is contained in:
Norman Feske
2017-05-08 01:33:40 +02:00
committed by Christian Helmuth
parent ff68d77c7d
commit 58f44d39c5
71 changed files with 330 additions and 333 deletions

View File

@ -94,22 +94,22 @@ namespace Genode {
return RAM_SESSION_IMPL::ref_account(session); return RAM_SESSION_IMPL::ref_account(session);
} }
int transfer_quota(Ram_session_capability session, size_t size) int transfer_quota(Ram_session_capability session, Ram_quota size)
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::transfer_quota(session, size); return RAM_SESSION_IMPL::transfer_quota(session, size);
} }
size_t quota() Ram_quota ram_quota() const override
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::quota(); return RAM_SESSION_IMPL::ram_quota();
} }
size_t used() Ram_quota used_ram() const override
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::used(); return RAM_SESSION_IMPL::used_ram();
} }
}; };

View File

@ -91,11 +91,11 @@ struct Stack_area_ram_session : Genode::Ram_session
int ref_account(Genode::Ram_session_capability) override { return 0; } int ref_account(Genode::Ram_session_capability) override { return 0; }
int transfer_quota(Genode::Ram_session_capability, Genode::size_t) override { return 0; } int transfer_quota(Genode::Ram_session_capability, Genode::Ram_quota) override { return 0; }
Genode::size_t quota() override { return 0; } Genode::Ram_quota ram_quota() const override { return { 0 }; }
Genode::size_t used() override { return 0; } Genode::Ram_quota used_ram() const override { return { 0 }; }
}; };

View File

@ -132,12 +132,12 @@ struct Stack_area_ram_session : Ram_session
int ref_account(Ram_session_capability ram_session) override { return 0; } int ref_account(Ram_session_capability ram_session) override { return 0; }
int transfer_quota(Ram_session_capability ram_session, size_t amount) override { int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override {
return 0; } return 0; }
size_t quota() override { return 0; } Ram_quota ram_quota() const override { return { 0 }; }
size_t used() override { return 0; } Ram_quota used_ram() const override { return { 0 }; }
}; };

View File

@ -19,6 +19,7 @@
#include <base/service.h> #include <base/service.h>
#include <base/lock.h> #include <base/lock.h>
#include <base/local_connection.h> #include <base/local_connection.h>
#include <base/quota_guard.h>
#include <util/arg_string.h> #include <util/arg_string.h>
#include <ram_session/connection.h> #include <ram_session/connection.h>
#include <region_map/client.h> #include <region_map/client.h>
@ -141,6 +142,7 @@ struct Genode::Child_policy
virtual Ram_session &ref_ram() = 0; virtual Ram_session &ref_ram() = 0;
virtual Ram_session_capability ref_ram_cap() const = 0; virtual Ram_session_capability ref_ram_cap() const = 0;
/** /**
* Respond to the release of resources by the child * Respond to the release of resources by the child
* *
@ -570,6 +572,15 @@ class Genode::Child : protected Rpc_object<Parent>,
*/ */
void session_closed(Session_state &) override; void session_closed(Session_state &) override;
template <typename UNIT>
static UNIT _effective_quota(UNIT requested_quota, UNIT env_quota)
{
if (requested_quota.value < env_quota.value)
return UNIT { 0 };
return UNIT { requested_quota.value - env_quota.value };
}
public: public:
/** /**
@ -623,13 +634,13 @@ class Genode::Child : protected Rpc_object<Parent>,
void initiate_env_sessions(); void initiate_env_sessions();
/** /**
* RAM quota unconditionally consumed by the child's environment * Quota unconditionally consumed by the child's environment
*/ */
static size_t env_ram_quota() static Ram_quota env_ram_quota()
{ {
return Cpu_connection::RAM_QUOTA + Ram_connection::RAM_QUOTA + return { Cpu_connection::RAM_QUOTA + Ram_connection::RAM_QUOTA +
Pd_connection::RAM_QUOTA + Log_connection::RAM_QUOTA + Pd_connection::RAM_QUOTA + Log_connection::RAM_QUOTA +
2*Rom_connection::RAM_QUOTA; 2*Rom_connection::RAM_QUOTA };
} }
template <typename FN> template <typename FN>
@ -639,14 +650,11 @@ class Genode::Child : protected Rpc_object<Parent>,
} }
/** /**
* Deduce session costs from usable ram quota * Deduce env session costs from usable RAM quota
*/ */
static size_t effective_ram_quota(size_t const ram_quota) static Ram_quota effective_quota(Ram_quota quota)
{ {
if (ram_quota < env_ram_quota()) return _effective_quota(quota, env_ram_quota());
return 0;
return ram_quota - env_ram_quota();
} }
Ram_session_capability ram_session_cap() const { return _ram.cap(); } Ram_session_capability ram_session_cap() const { return _ram.cap(); }

View File

@ -54,7 +54,7 @@ class Genode::Connection_base : public Noncopyable
void upgrade_ram(size_t bytes) void upgrade_ram(size_t bytes)
{ {
String<64> const args("ram_quota=", bytes); String<64> const args("ram_quota=", Ram_quota{bytes});
_env.upgrade(_id_space_element.id(), args.string()); _env.upgrade(_id_space_element.id(), args.string());
} }
}; };

View File

@ -58,15 +58,15 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
/** /**
* Total of quota associated with this session * Total of quota associated with this session
*/ */
size_t _donated_ram_quota = 0; Ram_quota _donated_ram_quota { 0 };
Factory *_factory = nullptr; Factory *_factory = nullptr;
Reconstructible<Id_space<Parent::Client>::Element> _id_at_client; Reconstructible<Id_space<Parent::Client>::Element> _id_at_client;
Session_label const _label; Session::Label const _label;
Args _args; Args _args;
Affinity _affinity; Affinity _affinity;
public: public:
@ -87,7 +87,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
CLOSED }; CLOSED };
/** /**
* If set, the server reponds asynchronously to the session request. * If set, the server responds asynchronously to the session request.
* The client waits for a notification that is delivered as soon as * The client waits for a notification that is delivered as soon as
* the server delivers the session capability. * the server delivers the session capability.
*/ */
@ -106,7 +106,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
Session_capability cap; Session_capability cap;
size_t ram_upgrade = 0; Ram_quota ram_upgrade { 0 };
void print(Output &out) const; void print(Output &out) const;
@ -129,7 +129,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
Session_state(Service &service, Session_state(Service &service,
Id_space<Parent::Client> &client_id_space, Id_space<Parent::Client> &client_id_space,
Parent::Client::Id client_id, Parent::Client::Id client_id,
Session_label const &label, Session::Label const &label,
Args const &args, Args const &args,
Affinity const &affinity); Affinity const &affinity);
@ -147,13 +147,13 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
*/ */
void confirm_ram_upgrade() void confirm_ram_upgrade()
{ {
ram_upgrade = 0; ram_upgrade = Ram_quota { 0 };
} }
void increase_donated_quota(size_t upgrade) void increase_donated_quota(Ram_quota added_ram_quota)
{ {
_donated_ram_quota += upgrade; _donated_ram_quota.value += added_ram_quota.value;
ram_upgrade = upgrade; ram_upgrade = added_ram_quota;
} }
Parent::Client::Id id_at_client() const Parent::Client::Id id_at_client() const
@ -177,7 +177,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
void generate_client_side_info(Xml_generator &, Detail detail) const; void generate_client_side_info(Xml_generator &, Detail detail) const;
void generate_server_side_info(Xml_generator &, Detail detail) const; void generate_server_side_info(Xml_generator &, Detail detail) const;
size_t donated_ram_quota() const { return _donated_ram_quota; } Ram_quota donated_ram_quota() const { return _donated_ram_quota; }
bool alive() const bool alive() const
{ {
@ -201,12 +201,12 @@ class Genode::Session_state : public Parent::Client, public Parent::Server,
/** /**
* Return client-side label of the session request * Return client-side label of the session request
*/ */
Session_label client_label() const { return label_from_args(_args.string()); } Session::Label client_label() const { return label_from_args(_args.string()); }
/** /**
* Return label presented to the server along with the session request * Return label presented to the server along with the session request
*/ */
Session_label label() const { return _label; } Session::Label label() const { return _label; }
/** /**
* Assign owner * Assign owner

View File

@ -42,12 +42,12 @@ struct Genode::Ram_session_client : Rpc_client<Ram_session>
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); }
int transfer_quota(Ram_session_capability ram_session, size_t amount) override { int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override {
return call<Rpc_transfer_quota>(ram_session, amount); } return call<Rpc_transfer_ram_quota>(ram_session, amount); }
size_t quota() override { return call<Rpc_quota>(); } Ram_quota ram_quota() const override { return call<Rpc_ram_quota>(); }
size_t used() override { return call<Rpc_used>(); } Ram_quota used_ram() const override { return call<Rpc_used_ram>(); }
}; };
#endif /* _INCLUDE__RAM_SESSION__CLIENT_H_ */ #endif /* _INCLUDE__RAM_SESSION__CLIENT_H_ */

View File

@ -21,10 +21,6 @@
#include <session/session.h> #include <session/session.h>
namespace Genode { namespace Genode {
struct Ram_dataspace;
typedef Capability<Ram_dataspace> Ram_dataspace_capability;
struct Ram_session_client; struct Ram_session_client;
struct Ram_session; struct Ram_session;
} }
@ -70,26 +66,22 @@ struct Genode::Ram_session : Session, Ram_allocator
* Quota can only be transfered if the specified RAM session is * Quota can only be transfered if the specified RAM session is
* either the reference account for this session or vice versa. * either the reference account for this session or vice versa.
*/ */
virtual int transfer_quota(Ram_session_capability ram_session, size_t amount) = 0; virtual int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) = 0;
/** /**
* Return current quota limit * Return current quota limit
*/ */
virtual size_t quota() = 0; virtual Ram_quota ram_quota() const = 0;
/** /**
* Return used quota * Return used quota
*/ */
virtual size_t used() = 0; virtual Ram_quota used_ram() const = 0;
/** /**
* Return amount of available quota * Return amount of available quota
*/ */
size_t avail() Ram_quota avail_ram() const { return { ram_quota().value - used_ram().value }; }
{
size_t q = quota(), u = used();
return q > u ? q - u : 0;
}
/********************* /*********************
@ -101,12 +93,12 @@ struct Genode::Ram_session : Session, Ram_allocator
size_t, Cache_attribute); size_t, Cache_attribute);
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability); GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
GENODE_RPC(Rpc_ref_account, int, ref_account, Ram_session_capability); GENODE_RPC(Rpc_ref_account, int, ref_account, Ram_session_capability);
GENODE_RPC(Rpc_transfer_quota, int, transfer_quota, Ram_session_capability, size_t); GENODE_RPC(Rpc_transfer_ram_quota, int, transfer_quota, Ram_session_capability, Ram_quota);
GENODE_RPC(Rpc_quota, size_t, quota); GENODE_RPC(Rpc_ram_quota, Ram_quota, ram_quota);
GENODE_RPC(Rpc_used, size_t, used); GENODE_RPC(Rpc_used_ram, Ram_quota, used_ram);
GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free, Rpc_ref_account, GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free, Rpc_ref_account,
Rpc_transfer_quota, Rpc_quota, Rpc_used); Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram);
}; };
#endif /* _INCLUDE__RAM_SESSION__RAM_SESSION_H_ */ #endif /* _INCLUDE__RAM_SESSION__RAM_SESSION_H_ */

View File

@ -138,33 +138,29 @@ class Genode::Root_component : public Rpc_object<Typed_root<SESSION_TYPE> >,
* We need to decrease 'ram_quota' by * We need to decrease 'ram_quota' by
* the size of the session object. * the size of the session object.
*/ */
size_t ram_quota = Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0); Ram_quota const ram_quota = ram_quota_from_args(args.string());
size_t needed = sizeof(SESSION_TYPE) + md_alloc()->overhead(sizeof(SESSION_TYPE)); size_t needed = sizeof(SESSION_TYPE) + md_alloc()->overhead(sizeof(SESSION_TYPE));
if (needed > ram_quota) { if (needed > ram_quota.value) {
warning("insufficient ram quota " warning("insufficient ram quota "
"for ", SESSION_TYPE::service_name(), " session, " "for ", SESSION_TYPE::service_name(), " session, "
"provided=", ram_quota, ", required=", needed); "provided=", ram_quota, ", required=", needed);
throw Root::Quota_exceeded(); throw Root::Quota_exceeded();
} }
size_t const remaining_ram_quota = ram_quota - needed; Ram_quota const remaining_ram_quota { ram_quota.value - needed };
/* /*
* Deduce ram quota needed for allocating the session object from the * Deduce ram quota needed for allocating the session object from the
* donated ram quota. * donated ram quota.
*
* XXX the size of the 'adjusted_args' buffer should dependent
* on the message-buffer size and stack size.
*/ */
enum { MAX_ARGS_LEN = 256 }; enum { MAX_ARGS_LEN = 256 };
char adjusted_args[MAX_ARGS_LEN]; char adjusted_args[MAX_ARGS_LEN];
strncpy(adjusted_args, args.string(), sizeof(adjusted_args)); strncpy(adjusted_args, args.string(), sizeof(adjusted_args));
char ram_quota_buf[64];
snprintf(ram_quota_buf, sizeof(ram_quota_buf), "%lu",
remaining_ram_quota);
Arg_string::set_arg(adjusted_args, sizeof(adjusted_args), Arg_string::set_arg(adjusted_args, sizeof(adjusted_args),
"ram_quota", ram_quota_buf); "ram_quota", String<64>(remaining_ram_quota).string());
SESSION_TYPE *s = 0; SESSION_TYPE *s = 0;
try { s = _create_session(adjusted_args, affinity); } try { s = _create_session(adjusted_args, affinity); }

View File

@ -96,22 +96,22 @@ namespace Genode {
return RAM_SESSION_IMPL::ref_account(session); return RAM_SESSION_IMPL::ref_account(session);
} }
int transfer_quota(Ram_session_capability session, size_t size) int transfer_quota(Ram_session_capability session, Ram_quota size)
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::transfer_quota(session, size); return RAM_SESSION_IMPL::transfer_quota(session, size);
} }
size_t quota() Ram_quota ram_quota() const override
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::quota(); return RAM_SESSION_IMPL::ram_quota();
} }
size_t used() Ram_quota used_ram() const override
{ {
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
return RAM_SESSION_IMPL::used(); return RAM_SESSION_IMPL::used_ram();
} }
}; };

View File

@ -180,9 +180,9 @@ namespace Genode {
***************************/ ***************************/
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, Ram_quota);
size_t quota() { return _quota_limit; } Ram_quota ram_quota() const override { return { _quota_limit}; }
size_t used() { return _payload; } Ram_quota used_ram() const override { return { _payload}; }
}; };
} }

View File

@ -131,7 +131,7 @@ class Core_child : public Child_policy
Capability<Cpu_session> _core_cpu_cap; Capability<Cpu_session> _core_cpu_cap;
Cpu_session &_core_cpu; Cpu_session &_core_cpu;
size_t const _ram_quota; Ram_quota const _ram_quota;
Child _child; Child _child;
@ -141,14 +141,14 @@ class Core_child : public Child_policy
* Constructor * Constructor
*/ */
Core_child(Registry<Service> &services, Ram_session &core_ram, Core_child(Registry<Service> &services, Ram_session &core_ram,
Capability<Ram_session> core_ram_cap, size_t ram_quota, Capability<Ram_session> core_ram_cap, Ram_quota ram_quota,
Cpu_session &core_cpu, Capability<Cpu_session> core_cpu_cap) Cpu_session &core_cpu, Capability<Cpu_session> core_cpu_cap)
: :
_entrypoint(nullptr, STACK_SIZE, "init_child", false), _entrypoint(nullptr, STACK_SIZE, "init_child", false),
_services(services), _services(services),
_core_ram_cap(core_ram_cap), _core_ram(core_ram), _core_ram_cap(core_ram_cap), _core_ram(core_ram),
_core_cpu_cap(core_cpu_cap), _core_cpu(core_cpu), _core_cpu_cap(core_cpu_cap), _core_cpu(core_cpu),
_ram_quota(Child::effective_ram_quota(ram_quota)), _ram_quota(Child::effective_quota(ram_quota)),
_child(*env_deprecated()->rm_session(), _entrypoint, *this) _child(*env_deprecated()->rm_session(), _entrypoint, *this)
{ {
_entrypoint.activate(); _entrypoint.activate();
@ -294,20 +294,23 @@ int main()
"label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT); "label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT);
Cpu_session_capability core_cpu_cap = core_env()->entrypoint()->manage(&core_cpu); Cpu_session_capability core_cpu_cap = core_env()->entrypoint()->manage(&core_cpu);
/* /* calculate RAM to be assigned to init */
* Transfer all left memory to init, but leave some memory left for core size_t const platform_ram_limit = platform()->ram_alloc()->avail();
* size_t const preserved_ram_quota = 224*1024;
* NOTE: exception objects thrown in core components are currently
* allocated on core's heap and not accounted by the component's meta data
* allocator
*/
Genode::size_t const ram_quota = platform()->ram_alloc()->avail() - 224*1024; if (platform_ram_limit < preserved_ram_quota) {
log("", ram_quota / (1024*1024), " MiB RAM assigned to init"); error("platform RAM limit lower than preservation for core");
return -1;
}
size_t const avail_ram_quota = platform_ram_limit - preserved_ram_quota;
log("", avail_ram_quota / (1024*1024), " MiB RAM "
"assigned to init");
static Reconstructible<Core_child> static Reconstructible<Core_child>
init(services, *env_deprecated()->ram_session(), env_deprecated()->ram_session_cap(), init(services, *env_deprecated()->ram_session(), env_deprecated()->ram_session_cap(),
ram_quota, core_cpu, core_cpu_cap); Ram_quota{avail_ram_quota}, core_cpu, core_cpu_cap);
platform()->wait_for_exit(); platform()->wait_for_exit();

View File

@ -274,10 +274,10 @@ int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap, int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
size_t amount) Ram_quota amount)
{ {
auto lambda = [&] (Ram_session_component *dst) { auto lambda = [&] (Ram_session_component *dst) {
return _transfer_quota(dst, amount); }; return _transfer_quota(dst, amount.value); };
if (this->cap() == ram_session_cap) if (this->cap() == ram_session_cap)
return 0; return 0;

View File

@ -134,10 +134,10 @@ struct Stack_area_ram_session : Ram_session
size_t dataspace_size(Ram_dataspace_capability) const override { return 0; } size_t dataspace_size(Ram_dataspace_capability) const override { return 0; }
int ref_account (Ram_session_capability) override { return 0; } int ref_account (Ram_session_capability) override { return 0; }
int transfer_quota (Ram_session_capability, size_t) override { return 0; } int transfer_quota (Ram_session_capability, Ram_quota) override { return 0; }
size_t quota () override { return 0; } Ram_quota ram_quota () const override { return { 0 }; }
size_t used () override { return 0; } Ram_quota used_ram () const override { return { 0 }; }
}; };

View File

@ -16,7 +16,7 @@
/* Genode includes */ /* Genode includes */
#include <util/retry.h> #include <util/retry.h>
#include <ram_session/client.h> #include <ram_session/connection.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/upgradeable_client.h> #include <base/internal/upgradeable_client.h>
@ -26,6 +26,11 @@ namespace Genode { class Expanding_ram_session_client; }
struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_session_client> struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_session_client>
{ {
void _request_ram_from_parent(size_t amount)
{
Parent &parent = *env_deprecated()->parent();
parent.resource_request(String<128>("ram_quota=", amount).string());
}
Expanding_ram_session_client(Ram_session_capability cap, Parent::Client::Id id) Expanding_ram_session_client(Ram_session_capability cap, Parent::Client::Id id)
: Upgradeable_client<Genode::Ram_session_client>(cap, id) { } : Upgradeable_client<Genode::Ram_session_client>(cap, id) { }
@ -47,8 +52,6 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
[&] () { upgrade_ram(8*1024); }); [&] () { upgrade_ram(8*1024); });
}, },
[&] () { [&] () {
char buf[128];
/* /*
* The RAM service withdraws the meta data for the allocator * The RAM service withdraws the meta data for the allocator
* from the RAM quota. In the worst case, a new slab block * from the RAM quota. In the worst case, a new slab block
@ -59,16 +62,18 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
* Because the worst case almost never happens, we request * Because the worst case almost never happens, we request
* a bit too much quota for the most time. * a bit too much quota for the most time.
*/ */
enum { ALLOC_OVERHEAD = 4096U }; enum { OVERHEAD = 4096UL };
Genode::snprintf(buf, sizeof(buf), "ram_quota=%lu", _request_ram_from_parent(size + OVERHEAD);
size + ALLOC_OVERHEAD);
env_deprecated()->parent()->resource_request(buf);
}, },
NUM_ATTEMPTS); NUM_ATTEMPTS);
} }
int transfer_quota(Ram_session_capability ram_session, size_t amount) override int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
{ {
/*
* Should the transfer fail because we don't have enough quota, request
* the needed amount from the parent.
*/
enum { NUM_ATTEMPTS = 2 }; enum { NUM_ATTEMPTS = 2 };
int ret = -1; int ret = -1;
for (unsigned i = 0; i < NUM_ATTEMPTS; i++) { for (unsigned i = 0; i < NUM_ATTEMPTS; i++) {
@ -76,15 +81,7 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client<Genode::Ram_ses
ret = Ram_session_client::transfer_quota(ram_session, amount); ret = Ram_session_client::transfer_quota(ram_session, amount);
if (ret != -3) break; if (ret != -3) break;
/* _request_ram_from_parent(amount.value);
* The transfer failed because we don't have enough quota. Request
* the needed amount from the parent.
*
* XXX Let transfer_quota throw 'Ram_session::Quota_exceeded'
*/
char buf[128];
Genode::snprintf(buf, sizeof(buf), "ram_quota=%lu", amount);
env_deprecated()->parent()->resource_request(buf);
} }
return ret; return ret;
} }

View File

@ -117,9 +117,9 @@ class Genode::Platform_env : public Env_deprecated,
void release() { void release() {
log("used before freeing emergency=", _resources.ram.used()); log("used before freeing emergency=", _resources.ram.used_ram());
_resources.ram.free(_emergency_ram_ds); _resources.ram.free(_emergency_ram_ds);
log("used after freeing emergency=", _resources.ram.used()); log("used after freeing emergency=", _resources.ram.used_ram());
} }

View File

@ -37,7 +37,7 @@ namespace {
class Transfer { class Transfer {
bool _ack; bool _ack;
size_t _quantum; Ram_quota _quantum;
Ram_session_capability _from; Ram_session_capability _from;
Ram_session_capability _to; Ram_session_capability _to;
@ -54,7 +54,7 @@ namespace {
* *
* \throw Quota_exceeded * \throw Quota_exceeded
*/ */
Transfer(size_t quantum, Transfer(Ram_quota quantum,
Ram_session_capability from, Ram_session_capability from,
Ram_session_capability to) Ram_session_capability to)
: _ack(false), _quantum(quantum), _from(from), _to(to) : _ack(false), _quantum(quantum), _from(from), _to(to)
@ -240,28 +240,27 @@ Session_capability Child::session(Parent::Client::Id id,
/* filter session affinity */ /* filter session affinity */
Affinity const filtered_affinity = _policy.filter_session_affinity(affinity); Affinity const filtered_affinity = _policy.filter_session_affinity(affinity);
size_t const ram_quota = Arg_string::find_arg(argbuf, "ram_quota").ulong_value(0); Ram_quota const ram_quota = ram_quota_from_args(argbuf);
/* portion of quota to keep for ourself to maintain the session meta data */ /* portion of quota to keep for ourself to maintain the session meta data */
size_t const keep_ram_quota = _session_factory.session_costs(); size_t const keep_ram_quota = _session_factory.session_costs();
if (ram_quota < keep_ram_quota) if (ram_quota.value < keep_ram_quota)
throw Parent::Quota_exceeded(); throw Parent::Quota_exceeded();
/* ram quota to be forwarded to the server */ /* ram quota to be forwarded to the server */
size_t const forward_ram_quota = ram_quota - keep_ram_quota; Ram_quota const forward_ram_quota { ram_quota.value - keep_ram_quota };
/* adjust the session information as presented to the server */ /* adjust the session information as presented to the server */
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", forward_ram_quota.value);
forward_ram_quota);
/* may throw a 'Parent::Service_denied' exception */ /* may throw a 'Parent::Service_denied' exception */
Child_policy::Route route = _resolve_session_request(_policy, name.string(), argbuf); Child_policy::Route route = _resolve_session_request(_policy, name.string(), argbuf);
Service &service = route.service; Service &service = route.service;
Session_state &session = Session_state &session =
create_session(_policy.name(), service, route.label, _session_factory, create_session(_policy.name(), service, route.label,
_id_space, id, argbuf, filtered_affinity); _session_factory, _id_space, id, argbuf, filtered_affinity);
_policy.session_state_changed(); _policy.session_state_changed();
@ -380,8 +379,8 @@ Parent::Upgrade_result Child::upgrade(Client::Id id, Parent::Upgrade_args const
return; return;
} }
size_t const ram_quota = Ram_quota const ram_quota {
Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0); Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0) };
try { try {
/* transfer quota from client to ourself */ /* transfer quota from client to ourself */
@ -431,8 +430,8 @@ void Child::_revert_quota_and_destroy(Session_state &session)
* quota that we preserved for locally storing the session meta data * quota that we preserved for locally storing the session meta data
* ('session_costs'). * ('session_costs').
*/ */
Transfer donation_to_client(session.donated_ram_quota() + Transfer donation_to_client(Ram_quota{session.donated_ram_quota().value +
_session_factory.session_costs(), _session_factory.session_costs()},
_policy.ref_ram_cap(), ram_session_cap()); _policy.ref_ram_cap(), ram_session_cap());
/* finish transaction */ /* finish transaction */
donation_from_service.acknowledge(); donation_from_service.acknowledge();

View File

@ -133,23 +133,24 @@ namespace {
/* extract session quota as specified by the 'Connection' */ /* extract session quota as specified by the 'Connection' */
char argbuf[Parent::Session_args::MAX_SIZE]; char argbuf[Parent::Session_args::MAX_SIZE];
strncpy(argbuf, args.string(), sizeof(argbuf)); strncpy(argbuf, args.string(), sizeof(argbuf));
size_t ram_quota = Arg_string::find_arg(argbuf, "ram_quota").ulong_value(0); Ram_quota ram_quota = ram_quota_from_args(argbuf);
return retry<Parent::Quota_exceeded>([&] () { return retry<Parent::Quota_exceeded>(
[&] () {
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota",
String<32>(Number_of_bytes(ram_quota)).string()); String<32>(ram_quota).string());
Session_capability cap = Session_capability cap =
_parent.session(id, name, Parent::Session_args(argbuf), affinity); _parent.session(id, name, Parent::Session_args(argbuf), affinity);
if (cap.valid()) if (cap.valid())
return cap; return cap;
_block_for_session(); _block_for_session();
return _parent.session_cap(id); return _parent.session_cap(id);
}, },
[&] () { [&] () {
/* /*
* If our RAM session has less quota available than the * If our RAM session has less quota available than the
* session quota, the session-quota transfer failed. In * session quota, the session-quota transfer failed. In
@ -159,18 +160,14 @@ namespace {
* Otherwise, the session-quota transfer succeeded but * Otherwise, the session-quota transfer succeeded but
* the request was denied by the server. * the request was denied by the server.
*/ */
if (ram_quota > ram().avail()) { if (ram_quota.value > ram().avail_ram().value) {
Parent::Resource_args args(String<64>("ram_quota=", ram_quota));
/* issue resource request */ _parent.resource_request(args);
char buf[128];
snprintf(buf, sizeof(buf), "ram_quota=%lu", ram_quota);
_parent.resource_request(Parent::Resource_args(buf));
} else { } else {
ram_quota += 4096; ram_quota = Ram_quota { ram_quota.value + 4096 };
} }
},
}, NUM_ATTEMPTS); NUM_ATTEMPTS);
warning("giving up to increase session quota for ", name.string(), " session " warning("giving up to increase session quota for ", name.string(), " session "
"after ", (int)NUM_ATTEMPTS, " attempts"); "after ", (int)NUM_ATTEMPTS, " attempts");

View File

@ -195,13 +195,11 @@ void Root_proxy::_handle_session_request(Xml_node request)
_id_space.apply<Session>(id, [&] (Session &session) { _id_space.apply<Session>(id, [&] (Session &session) {
size_t ram_quota = request.attribute_value("ram_quota", 0UL); Ram_quota const ram_quota { request.attribute_value("ram_quota", 0UL) };
char buf[64]; String<80> const args("ram_quota=", ram_quota);
snprintf(buf, sizeof(buf), "ram_quota=%ld", ram_quota);
// XXX handle Root::Invalid_args Root_client(session.service.root).upgrade(session.cap, args.string());
Root_client(session.service.root).upgrade(session.cap, buf);
_env.parent().session_response(id, Parent::SESSION_OK); _env.parent().session_response(id, Parent::SESSION_OK);
}); });

View File

@ -76,7 +76,7 @@ void Session_state::generate_session_request(Xml_generator &xml) const
xml.node("upgrade", [&] () { xml.node("upgrade", [&] () {
xml.attribute("id", id_at_server->id().value); xml.attribute("id", id_at_server->id().value);
xml.attribute("ram_quota", ram_upgrade); xml.attribute("ram_quota", ram_upgrade.value);
}); });
break; break;
@ -101,7 +101,7 @@ void Session_state::generate_client_side_info(Xml_generator &xml, Detail detail)
xml.attribute("service", _service.name()); xml.attribute("service", _service.name());
xml.attribute("label", _label); xml.attribute("label", _label);
xml.attribute("state", String<32>(Formatted_phase(phase))); xml.attribute("state", String<32>(Formatted_phase(phase)));
xml.attribute("ram", String<32>(Number_of_bytes(_donated_ram_quota))); xml.attribute("ram", String<32>(_donated_ram_quota));
if (detail.args == Detail::ARGS) if (detail.args == Detail::ARGS)
xml.node("args", [&] () { xml.append_sanitized(_args.string()); }); xml.node("args", [&] () { xml.append_sanitized(_args.string()); });
@ -160,7 +160,7 @@ Session_state::Session_state(Service &service,
Affinity const &affinity) Affinity const &affinity)
: :
_service(service), _service(service),
_donated_ram_quota(Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0)), _donated_ram_quota(ram_quota_from_args(args.string())),
_id_at_client(*this, client_id_space, client_id), _id_at_client(*this, client_id_space, client_id),
_label(label), _args(args), _affinity(affinity) _label(label), _args(args), _affinity(affinity)
{ } { }

View File

@ -29,7 +29,7 @@ void Component::construct(Genode::Env &env)
log("allocate dataspace from one RAM session"); log("allocate dataspace from one RAM session");
ram_1.ref_account(env.ram_session_cap()); ram_1.ref_account(env.ram_session_cap());
env.ram().transfer_quota(ram_1.cap(), 8*1024); env.ram().transfer_quota(ram_1.cap(), Ram_quota{8*1024});
Ram_dataspace_capability ds = ram_1.alloc(sizeof(unsigned)); Ram_dataspace_capability ds = ram_1.alloc(sizeof(unsigned));
log("attempt to free dataspace from foreign RAM session"); log("attempt to free dataspace from foreign RAM session");
@ -41,11 +41,11 @@ void Component::construct(Genode::Env &env)
log("attach operation succeeded"); log("attach operation succeeded");
log("free dataspace from legitimate RAM session"); log("free dataspace from legitimate RAM session");
size_t const quota_before_free = ram_1.avail(); Ram_quota const quota_before_free { ram_1.avail_ram() };
ram_1.free(ds); ram_1.free(ds);
size_t const quota_after_free = ram_1.avail(); Ram_quota const quota_after_free { ram_1.avail_ram() };
if (quota_after_free > quota_before_free) if (quota_after_free.value > quota_before_free.value)
log("test succeeded"); log("test succeeded");
else else
error("test failed"); error("test failed");

View File

@ -106,7 +106,7 @@ class Test_child_policy : public Child_policy
{ {
enum { CHILD_QUOTA = 1*1024*1024 }; enum { CHILD_QUOTA = 1*1024*1024 };
session.ref_account(_env.ram_session_cap()); session.ref_account(_env.ram_session_cap());
_env.ram().transfer_quota(cap, CHILD_QUOTA); _env.ram().transfer_quota(cap, Ram_quota{CHILD_QUOTA});
} }
void init(Pd_session &session, Pd_session_capability cap) override void init(Pd_session &session, Pd_session_capability cap) override

View File

@ -162,7 +162,7 @@ int rumpuser_getparam(const char *name, void *buf, size_t buflen)
if (!Genode::strcmp(name, "RUMP_MEMLIMIT")) { if (!Genode::strcmp(name, "RUMP_MEMLIMIT")) {
/* leave 2 MB for the Genode */ /* leave 2 MB for the Genode */
size_t rump_ram = Rump::env().env().ram().avail(); size_t rump_ram = Rump::env().env().ram().avail_ram().value;
if (rump_ram <= RESERVE_MEM) { if (rump_ram <= RESERVE_MEM) {
Genode::error("insufficient quota left: ", Genode::error("insufficient quota left: ",

View File

@ -58,7 +58,8 @@ class Launchpad_child : public Genode::Child_policy,
Genode::Ram_session_capability _ref_ram_cap; Genode::Ram_session_capability _ref_ram_cap;
Genode::Ram_session_client _ref_ram { _ref_ram_cap }; Genode::Ram_session_client _ref_ram { _ref_ram_cap };
Genode::size_t const _ram_quota;
Genode::Ram_quota const _ram_quota;
Parent_services &_parent_services; Parent_services &_parent_services;
Child_services &_child_services; Child_services &_child_services;
@ -96,14 +97,15 @@ class Launchpad_child : public Genode::Child_policy,
Genode::Allocator &alloc, Genode::Allocator &alloc,
Genode::Session_label const &label, Genode::Session_label const &label,
Binary_name const &elf_name, Binary_name const &elf_name,
Genode::size_t ram_quota, Genode::Ram_quota ram_quota,
Parent_services &parent_services, Parent_services &parent_services,
Child_services &child_services, Child_services &child_services,
Genode::Dataspace_capability config_ds) Genode::Dataspace_capability config_ds)
: :
_name(label), _elf_name(elf_name), _name(label), _elf_name(elf_name),
_env(env), _alloc(alloc), _env(env), _alloc(alloc),
_ref_ram_cap(env.ram_session_cap()), _ram_quota(ram_quota), _ref_ram_cap(env.ram_session_cap()),
_ram_quota(Genode::Child::effective_quota(ram_quota)),
_parent_services(parent_services), _parent_services(parent_services),
_child_services(child_services), _child_services(child_services),
_session_requester(env.ep().rpc_ep(), _env.ram(), _env.rm()), _session_requester(env.ep().rpc_ep(), _env.ram(), _env.rm()),
@ -231,6 +233,8 @@ class Launchpad
public: public:
typedef Genode::Ram_quota Ram_quota;
Launchpad(Genode::Env &env, unsigned long initial_quota); Launchpad(Genode::Env &env, unsigned long initial_quota);
unsigned long initial_quota() { return _initial_quota; } unsigned long initial_quota() { return _initial_quota; }
@ -262,7 +266,7 @@ class Launchpad
Genode::Allocator &) { } Genode::Allocator &) { }
Launchpad_child *start_child(Launchpad_child::Name const &binary_name, Launchpad_child *start_child(Launchpad_child::Name const &binary_name,
unsigned long quota, Ram_quota quota,
Genode::Dataspace_capability config_ds); Genode::Dataspace_capability config_ds);
/** /**

View File

@ -20,7 +20,8 @@ using namespace Scout;
void Launcher::launch() void Launcher::launch()
{ {
_launchpad->start_child(prg_name(), quota(), _launchpad->start_child(prg_name(),
Launchpad::Ram_quota{quota()},
_config ? _config->config_ds() _config ? _config->config_ds()
: Genode::Dataspace_capability()); : Genode::Dataspace_capability());
} }

View File

@ -63,7 +63,7 @@ class Avail_quota_update : public Scout::Tick
*/ */
int on_tick() int on_tick()
{ {
size_t new_avail = _ram.avail(); size_t new_avail = _ram.avail_ram().value;
/* update launchpad window if needed */ /* update launchpad window if needed */
if (new_avail != _avail) if (new_avail != _avail)
@ -108,7 +108,7 @@ struct Main : Scout::Event_handler
Launchpad_window<Pixel_rgb565> Launchpad_window<Pixel_rgb565>
_launchpad { _env, _graphics_backend, _initial_position, _initial_size, _launchpad { _env, _graphics_backend, _initial_position, _initial_size,
_max_size, _env.ram().avail() }; _max_size, _env.ram().avail_ram().value };
void _process_config() void _process_config()
{ {

View File

@ -98,7 +98,7 @@ Dataspace_capability Config_registry::config(char const *name)
void Launcher::init(Genode::Env &env, Allocator &alloc) void Launcher::init(Genode::Env &env, Allocator &alloc)
{ {
static Launchpad launchpad(env, env.ram().avail()); static Launchpad launchpad(env, env.ram().avail_ram().value);
_launchpad_ptr = &launchpad; _launchpad_ptr = &launchpad;
_alloc_ptr = &alloc; _alloc_ptr = &alloc;
_env_ptr = &env; _env_ptr = &env;
@ -114,6 +114,7 @@ void Launcher::launch()
throw Missing_launchpad_init_call(); throw Missing_launchpad_init_call();
} }
_launchpad_ptr->start_child(prg_name(), quota(), _launchpad_ptr->start_child(prg_name(),
Launchpad::Ram_quota{quota()},
config_registry.config(prg_name().string())); config_registry.config(prg_name().string()));
} }

View File

@ -143,7 +143,7 @@ void Launchpad::process_config(Genode::Xml_node config_node)
Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name, Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name,
unsigned long ram_quota, Ram_quota ram_quota,
Dataspace_capability config_ds) Dataspace_capability config_ds)
{ {
log("starting ", binary_name, " with quota ", ram_quota); log("starting ", binary_name, " with quota ", ram_quota);
@ -152,27 +152,27 @@ Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name
Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name); Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name);
log("using unique child name \"", unique_name, "\""); log("using unique child name \"", unique_name, "\"");
if (ram_quota > _env.ram().avail()) { if (ram_quota.value > _env.ram().avail_ram().value) {
error("child's ram quota is higher than our available quota, using available quota"); warning("child's ram quota is higher than our available quota, using available quota");
size_t const avail = _env.ram().avail(); size_t const avail = _env.ram().avail_ram().value;
size_t const preserved = 256*1024; size_t const preserved = 256*1024;
if (avail < preserved) { if (avail < preserved) {
error("giving up, our own quota is too low (", avail, ")"); error("giving up, our own quota is too low (", avail, ")");
return 0; return 0;
} }
ram_quota = avail - preserved; ram_quota = Ram_quota { avail - preserved };
} }
size_t metadata_size = 4096*16 + sizeof(Launchpad_child); size_t metadata_size = 4096*16 + sizeof(Launchpad_child);
if (metadata_size > ram_quota) { if (metadata_size > ram_quota.value) {
error("too low ram_quota to hold child metadata"); error("too low ram_quota to hold child metadata");
return 0; return 0;
} }
ram_quota -= metadata_size; ram_quota = Ram_quota { ram_quota.value - metadata_size };
try { try {
Launchpad_child *c = new (&_sliced_heap) Launchpad_child *c = new (&_sliced_heap)
@ -182,7 +182,7 @@ Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name
Lock::Guard lock_guard(_children_lock); Lock::Guard lock_guard(_children_lock);
_children.insert(c); _children.insert(c);
add_child(unique_name, ram_quota, *c, _heap); add_child(unique_name, ram_quota.value, *c, _heap);
return c; return c;
} catch (...) { } catch (...) {

View File

@ -43,8 +43,8 @@ class Report_rom_slave : public Genode::Noncopyable
protected: protected:
static Name _name() { return "report_rom"; } static Name _name() { return "report_rom"; }
static Genode::size_t _quota() { return 1024*1024; } static Genode::Ram_quota _quota() { return { 1024*1024 }; }
public: public:

View File

@ -73,8 +73,8 @@ class Launcher::Menu_view_slave
configure(config); configure(config);
} }
static Name _name() { return "menu_view"; } static Name _name() { return "menu_view"; }
static Genode::size_t _quota() { return 6*1024*1024; } static Genode::Ram_quota _quota() { return { 6*1024*1024 }; }
public: public:

View File

@ -45,8 +45,8 @@ class Launcher::Nit_fader_slave
protected: protected:
static Name _name() { return "nit_fader"; } static Name _name() { return "nit_fader"; }
static size_t _quota() { return 2*1024*1024; } static Genode::Ram_quota _quota() { return { 2*1024*1024 }; }
public: public:

View File

@ -52,7 +52,7 @@ extern "C" long sysconf(int name)
case _SC_PAGESIZE: return PAGESIZE; case _SC_PAGESIZE: return PAGESIZE;
case _SC_PHYS_PAGES: case _SC_PHYS_PAGES:
return _global_env->ram().quota() / PAGESIZE; return _global_env->ram().ram_quota().value / PAGESIZE;
default: default:
Genode::warning(__func__, "(", name, ") not implemented"); Genode::warning(__func__, "(", name, ") not implemented");
return Libc::Errno(EINVAL); return Libc::Errno(EINVAL);
@ -127,7 +127,7 @@ extern "C" int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
case HW_PHYSMEM: case HW_PHYSMEM:
case HW_USERMEM: case HW_USERMEM:
*(unsigned long*)oldp = _global_env->ram().quota(); *(unsigned long*)oldp = _global_env->ram().ram_quota().value;
*oldlenp = sizeof(unsigned long); *oldlenp = sizeof(unsigned long);
return 0; return 0;

View File

@ -63,7 +63,7 @@ static int l_quota(lua_State *lua)
return 0; return 0;
} }
lua_pushnumber(lua, Moon::env->ram.quota()); lua_pushnumber(lua, Moon::env->ram.ram_quota().value);
return 1; return 1;
} }

View File

@ -190,7 +190,7 @@ class Cli_monitor::Child_base : public Genode::Child_policy
/* wake up child if resource request is in flight */ /* wake up child if resource request is in flight */
size_t const req = requested_ram_quota(); size_t const req = requested_ram_quota();
if (req && _child.ram().avail() >= req) { if (req && _child.ram().avail_ram().value >= req) {
_child.notify_resource_avail(); _child.notify_resource_avail();
/* clear request state */ /* clear request state */
@ -256,9 +256,9 @@ class Cli_monitor::Child_base : public Genode::Child_policy
{ {
return Ram_status(_ram_quota, return Ram_status(_ram_quota,
_ram_limit, _ram_limit,
_ram_quota - _child.ram().quota(), _ram_quota - _child.ram().ram_quota().value,
_child.ram().used(), _child.ram().used_ram().value,
_child.ram().avail(), _child.ram().avail_ram().value,
requested_ram_quota()); requested_ram_quota());
} }
@ -281,7 +281,7 @@ class Cli_monitor::Child_base : public Genode::Child_policy
void init(Genode::Ram_session &session, Genode::Ram_session_capability cap) override void init(Genode::Ram_session &session, Genode::Ram_session_capability cap) override
{ {
session.ref_account(_ref_ram_cap); session.ref_account(_ref_ram_cap);
_ref_ram.transfer_quota(cap, _ram_quota); _ref_ram.transfer_quota(cap, Genode::Ram_quota{_ram_quota});
} }
Genode::Service &resolve_session_request(Genode::Service::Name const &name, Genode::Service &resolve_session_request(Genode::Service::Name const &name,
@ -309,8 +309,8 @@ class Cli_monitor::Child_base : public Genode::Child_policy
if (_withdraw_on_yield_response) { if (_withdraw_on_yield_response) {
enum { RESERVE = 4*1024*1024 }; enum { RESERVE = 4*1024*1024 };
size_t amount = _child.ram().avail() < RESERVE size_t amount = _child.ram().avail_ram().value < RESERVE
? 0 : _child.ram().avail() - RESERVE; ? 0 : _child.ram().avail_ram().value - RESERVE;
/* try to immediately withdraw freed-up resources */ /* try to immediately withdraw freed-up resources */
try { withdraw_ram_quota(amount); } try { withdraw_ram_quota(amount); }

View File

@ -37,11 +37,11 @@ class Cli_monitor::Ram
void _validate_preservation() void _validate_preservation()
{ {
if (_ram.avail() < _preserve) if (_ram.avail_ram().value < _preserve)
Genode::Signal_transmitter(_yield_sigh).submit(); Genode::Signal_transmitter(_yield_sigh).submit();
/* verify to answer outstanding resource requests too */ /* verify to answer outstanding resource requests too */
if (_ram.avail() > _preserve) if (_ram.avail_ram().value > _preserve)
Genode::Signal_transmitter(_resource_avail_sigh).submit(); Genode::Signal_transmitter(_resource_avail_sigh).submit();
} }
@ -86,7 +86,8 @@ class Cli_monitor::Ram
{ {
Genode::Lock::Guard guard(_lock); Genode::Lock::Guard guard(_lock);
return Status(_ram.quota(), _ram.used(), _ram.avail(), _preserve); return Status(_ram.ram_quota().value, _ram.used_ram().value,
_ram.avail_ram().value, _preserve);
} }
void validate_preservation() void validate_preservation()
@ -109,7 +110,7 @@ class Cli_monitor::Ram
Genode::Lock::Guard guard(_lock); Genode::Lock::Guard guard(_lock);
int const ret = int const ret =
Genode::Ram_session_client(from).transfer_quota(_ram_cap, amount); Genode::Ram_session_client(from).transfer_quota(_ram_cap, Genode::Ram_quota{amount});
if (ret != 0) if (ret != 0)
throw Transfer_quota_failed(); throw Transfer_quota_failed();
@ -124,18 +125,18 @@ class Cli_monitor::Ram
{ {
Genode::Lock::Guard guard(_lock); Genode::Lock::Guard guard(_lock);
if (_ram.avail() < (_preserve + amount)) { if (_ram.avail_ram().value < (_preserve + amount)) {
Genode::Signal_transmitter(_yield_sigh).submit(); Genode::Signal_transmitter(_yield_sigh).submit();
throw Transfer_quota_failed(); throw Transfer_quota_failed();
} }
int const ret = _ram.transfer_quota(to, amount); int const ret = _ram.transfer_quota(to, Genode::Ram_quota{amount});
if (ret != 0) if (ret != 0)
throw Transfer_quota_failed(); throw Transfer_quota_failed();
} }
size_t avail() const { return _ram.avail(); } size_t avail() const { return _ram.avail_ram().value; }
}; };
#endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */ #endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */

View File

@ -34,7 +34,7 @@ struct Loader::Session_client : Genode::Rpc_client<Session>
void commit_rom_module(Name const &name) override { void commit_rom_module(Name const &name) override {
call<Rpc_commit_rom_module>(name); } call<Rpc_commit_rom_module>(name); }
void ram_quota(size_t quantum) override { void ram_quota(Ram_quota quantum) override {
call<Rpc_ram_quota>(quantum); } call<Rpc_ram_quota>(quantum); }
void constrain_geometry(Area size) override { void constrain_geometry(Area size) override {

View File

@ -26,10 +26,11 @@ struct Loader::Connection : Genode::Connection<Session>, Session_client
/** /**
* Constructor * Constructor
*/ */
Connection(Genode::Env &env, size_t ram_quota) Connection(Genode::Env &env, Ram_quota ram_quota)
: :
Genode::Connection<Session>(env, session(env.parent(), Genode::Connection<Session>(env, session(env.parent(),
"ram_quota=%ld", ram_quota)), "ram_quota=%ld",
ram_quota.value)),
Session_client(cap()) Session_client(cap())
{ } { }

View File

@ -31,6 +31,7 @@ namespace Loader {
using Genode::Dataspace_capability; using Genode::Dataspace_capability;
using Genode::Signal_context_capability; using Genode::Signal_context_capability;
using Genode::Ram_quota;
struct Session; struct Session;
} }
@ -101,7 +102,7 @@ struct Loader::Session : Genode::Session
* If 'ram_quota' is not called prior calling 'start', all available * If 'ram_quota' is not called prior calling 'start', all available
* session resources will be assigned to the subsystem. * session resources will be assigned to the subsystem.
*/ */
virtual void ram_quota(size_t quantum) = 0; virtual void ram_quota(Ram_quota quantum) = 0;
/** /**
* Constrain size of the nitpicker buffer used by the subsystem * Constrain size of the nitpicker buffer used by the subsystem
@ -166,7 +167,7 @@ struct Loader::Session : Genode::Session
GENODE_RPC_THROW(Rpc_commit_rom_module, void, commit_rom_module, GENODE_RPC_THROW(Rpc_commit_rom_module, void, commit_rom_module,
GENODE_TYPE_LIST(Rom_module_does_not_exist), GENODE_TYPE_LIST(Rom_module_does_not_exist),
Name const &); Name const &);
GENODE_RPC(Rpc_ram_quota, void, ram_quota, size_t); GENODE_RPC(Rpc_ram_quota, void, ram_quota, Ram_quota);
GENODE_RPC(Rpc_constrain_geometry, void, constrain_geometry, Area); GENODE_RPC(Rpc_constrain_geometry, void, constrain_geometry, Area);
GENODE_RPC(Rpc_parent_view, void, parent_view, Nitpicker::View_capability); GENODE_RPC(Rpc_parent_view, void, parent_view, Nitpicker::View_capability);
GENODE_RPC(Rpc_view_ready_sigh, void, view_ready_sigh, Signal_context_capability); GENODE_RPC(Rpc_view_ready_sigh, void, view_ready_sigh, Signal_context_capability);

View File

@ -48,7 +48,7 @@ class Genode::Ram_session_guard : public Genode::Ram_session
template <typename T> template <typename T>
int transfer_quota(Ram_session_capability ram_session, size_t amount) int transfer_quota(Ram_session_capability ram_session, size_t amount)
{ {
int const error = transfer_quota(ram_session, amount); int const error = transfer_quota(ram_session, Ram_quota{amount});
if (error == RM_SESSION_INSUFFICIENT_QUOTA) if (error == RM_SESSION_INSUFFICIENT_QUOTA)
throw T(); throw T();
@ -98,7 +98,7 @@ class Genode::Ram_session_guard : public Genode::Ram_session
if (amount > _used) if (amount > _used)
return -4; return -4;
int error = ram_session.transfer_quota(_session_cap, amount); int error = ram_session.transfer_quota(_session_cap, Ram_quota{amount});
if (!error) if (!error)
_used -= amount; _used -= amount;
@ -140,22 +140,21 @@ class Genode::Ram_session_guard : public Genode::Ram_session
return _session.ref_account(ram_session); } return _session.ref_account(ram_session); }
int transfer_quota(Ram_session_capability ram_session, int transfer_quota(Ram_session_capability ram_session,
size_t amount) override Ram_quota amount) override
{ {
if (_used + amount <= _used || _used + amount > _quota) if (_used + amount.value <= _used || _used + amount.value > _quota)
return RM_SESSION_INSUFFICIENT_QUOTA; return RM_SESSION_INSUFFICIENT_QUOTA;
int const error = _session.transfer_quota(ram_session, amount); int const error = _session.transfer_quota(ram_session, amount);
if (!error) if (!error)
_used += amount; _used += amount.value;
return error; return error;
} }
size_t quota() override { return _quota; } Ram_quota ram_quota() const override { return Ram_quota{_quota}; }
Ram_quota used_ram() const override { return Ram_quota{_used}; }
size_t used() override { return _used; }
}; };
#endif /* _INCLUDE__OS__RAM_SESSION_GUARD_H_ */ #endif /* _INCLUDE__OS__RAM_SESSION_GUARD_H_ */

View File

@ -56,7 +56,7 @@ class Genode::Slave::Policy : public Child_policy
Binary_name const _binary_name; Binary_name const _binary_name;
Ram_session_client _ram; Ram_session_client _ram;
Genode::Parent_service _binary_service; Genode::Parent_service _binary_service;
size_t _ram_quota; Ram_quota const _ram_quota;
Parent_services &_parent_services; Parent_services &_parent_services;
Rpc_entrypoint &_ep; Rpc_entrypoint &_ep;
Child_policy_dynamic_rom_file _config_policy; Child_policy_dynamic_rom_file _config_policy;
@ -83,7 +83,7 @@ class Genode::Slave::Policy : public Child_policy
Rpc_entrypoint &ep, Rpc_entrypoint &ep,
Region_map &rm, Region_map &rm,
Ram_session_capability ram_cap, Ram_session_capability ram_cap,
size_t ram_quota) Ram_quota ram_quota)
: :
_label(label), _binary_name(binary_name), _ram(ram_cap), _label(label), _binary_name(binary_name), _ram(ram_cap),
_binary_service(Rom_session::service_name()), _binary_service(Rom_session::service_name()),

View File

@ -95,7 +95,7 @@ struct Dummy::Log_service
size_t const ram_quota = size_t const ram_quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0); Arg_string::find_arg(args, "ram_quota").ulong_value(0);
if (_ram.avail() >= ram_quota) if (_ram.avail_ram().value >= ram_quota)
log("received session quota upgrade"); log("received session quota upgrade");
} }
}; };

View File

@ -34,7 +34,7 @@ class Platform::Device_pd_policy
Device_pd_policy(Genode::Rpc_entrypoint &slave_ep, Device_pd_policy(Genode::Rpc_entrypoint &slave_ep,
Genode::Region_map &local_rm, Genode::Region_map &local_rm,
Genode::Ram_session_capability ram_ref_cap, Genode::Ram_session_capability ram_ref_cap,
Genode::size_t ram_quota, Genode::Ram_quota ram_quota,
Genode::Session_label const &label) Genode::Session_label const &label)
: :
Genode::Slave::Policy(label, "device_pd", *this, slave_ep, local_rm, Genode::Slave::Policy(label, "device_pd", *this, slave_ep, local_rm,

View File

@ -59,7 +59,7 @@ struct Expanding_region_map_client : Genode::Region_map_client
[&] () { [&] () {
enum { UPGRADE_QUOTA = 4096 }; enum { UPGRADE_QUOTA = 4096 };
if (_env.ram().avail() < UPGRADE_QUOTA) if (_env.ram().avail_ram().value < UPGRADE_QUOTA)
throw; throw;
Genode::String<32> arg("ram_quota=", (unsigned)UPGRADE_QUOTA); Genode::String<32> arg("ram_quota=", (unsigned)UPGRADE_QUOTA);

View File

@ -252,7 +252,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_ram.ref_account(_env_ram_cap); _ram.ref_account(_env_ram_cap);
enum { OVERHEAD = 4096 }; enum { OVERHEAD = 4096 };
if (_env_ram.transfer_quota(_ram, OVERHEAD) != 0) if (_env_ram.transfer_quota(_ram, Genode::Ram_quota{OVERHEAD}) != 0)
throw Genode::Root::Quota_exceeded(); throw Genode::Root::Quota_exceeded();
} }
@ -322,7 +322,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Genode::Session_label const &label) Genode::Session_label const &label)
try : try :
_reservation(guard, RAM_QUOTA), _reservation(guard, RAM_QUOTA),
_policy(ep, local_rm, ref_ram, RAM_QUOTA, label), _policy(ep, local_rm, ref_ram, Genode::Ram_quota{RAM_QUOTA}, label),
_child(local_rm, ep, _policy), _child(local_rm, ep, _policy),
_connection(_policy, Genode::Slave::Args()) _connection(_policy, Genode::Slave::Args())
{ } { }
@ -984,10 +984,11 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
if (!_env_ram.withdraw(UPGRADE_QUOTA)) if (!_env_ram.withdraw(UPGRADE_QUOTA))
_rollback(size, ram_cap); _rollback(size, ram_cap);
if (_env_ram.transfer_quota(_ram, UPGRADE_QUOTA)) if (_env_ram.transfer_quota(_ram, Genode::Ram_quota{UPGRADE_QUOTA}))
throw Fatal(); throw Fatal();
if (_ram.transfer_quota(_device_pd->ram_session_cap(), UPGRADE_QUOTA)) if (_ram.transfer_quota(_device_pd->ram_session_cap(),
Genode::Ram_quota{UPGRADE_QUOTA}))
throw Fatal(); throw Fatal();
}); });
} }

View File

@ -198,9 +198,9 @@ void Init::Child::apply_ram_upgrade()
_resources.assigned_ram_quota = _resources.assigned_ram_quota =
Ram_quota { _resources.assigned_ram_quota.value + transfer }; Ram_quota { _resources.assigned_ram_quota.value + transfer };
_check_resource_constraints(_ram_limit_accessor.ram_limit()); _check_ram_constraints(_ram_limit_accessor.ram_limit());
ref_ram().transfer_quota(_child.ram_session_cap(), transfer); ref_ram().transfer_quota(_child.ram_session_cap(), Ram_quota{transfer});
/* wake up child that blocks on a resource request */ /* wake up child that blocks on a resource request */
if (_requested_resources.constructed()) { if (_requested_resources.constructed()) {
@ -231,14 +231,14 @@ void Init::Child::apply_ram_downgrade()
/* give up if the child's available RAM is exhausted */ /* give up if the child's available RAM is exhausted */
size_t const preserved = 16*1024; size_t const preserved = 16*1024;
size_t const avail = _child.ram().avail(); size_t const avail = _child.ram().avail_ram().value;
if (avail < preserved) if (avail < preserved)
break; break;
size_t const transfer = min(avail - preserved, decrease); size_t const transfer = min(avail - preserved, decrease);
if (_child.ram().transfer_quota(ref_ram_cap(), transfer) == 0) { if (_child.ram().transfer_quota(ref_ram_cap(), Ram_quota{transfer}) == 0) {
_resources.assigned_ram_quota = _resources.assigned_ram_quota =
Ram_quota { _resources.assigned_ram_quota.value - transfer }; Ram_quota { _resources.assigned_ram_quota.value - transfer };
break; break;
@ -335,7 +335,7 @@ void Init::Child::init(Ram_session &session, Ram_session_capability cap)
? _resources.effective_ram_quota().value - initial_session_costs ? _resources.effective_ram_quota().value - initial_session_costs
: 0; : 0;
if (transfer_ram) if (transfer_ram)
_env.ram().transfer_quota(cap, transfer_ram); _env.ram().transfer_quota(cap, Ram_quota{transfer_ram});
} }
@ -630,14 +630,14 @@ Init::Child::Child(Env &env,
_ram_limit_accessor(ram_limit_accessor), _ram_limit_accessor(ram_limit_accessor),
_name_registry(name_registry), _name_registry(name_registry),
_resources(_resources_from_start_node(start_node, prio_levels, affinity_space)), _resources(_resources_from_start_node(start_node, prio_levels, affinity_space)),
_resources_checked((_check_resource_constraints(ram_limit), true)), _resources_checked((_check_ram_constraints(ram_limit), true)),
_parent_services(parent_services), _parent_services(parent_services),
_child_services(child_services), _child_services(child_services),
_session_requester(_env.ep().rpc_ep(), _env.ram(), _env.rm()) _session_requester(_env.ep().rpc_ep(), _env.ram(), _env.rm())
{ {
if (_verbose.enabled()) { if (_verbose.enabled()) {
log("child \"", _unique_name, "\""); log("child \"", _unique_name, "\"");
log(" RAM quota: ", Number_of_bytes(_resources.effective_ram_quota().value)); log(" RAM quota: ", _resources.effective_ram_quota());
log(" ELF binary: ", _binary_name); log(" ELF binary: ", _binary_name);
log(" priority: ", _resources.priority); log(" priority: ", _resources.priority);
} }

View File

@ -130,7 +130,7 @@ class Init::Child : Child_policy, Child_service::Wakeup
Ram_quota effective_ram_quota() const Ram_quota effective_ram_quota() const
{ {
return Ram_quota { Genode::Child::effective_ram_quota(assigned_ram_quota.value) }; return Genode::Child::effective_quota(assigned_ram_quota);
} }
}; };
@ -167,7 +167,7 @@ class Init::Child : Child_policy, Child_service::Wakeup
Resources _resources; Resources _resources;
void _check_resource_constraints(Ram_quota ram_limit) void _check_ram_constraints(Ram_quota ram_limit)
{ {
if (_resources.effective_ram_quota().value == 0) if (_resources.effective_ram_quota().value == 0)
warning("no valid RAM RESOURCE for child \"", _unique_name, "\""); warning("no valid RAM RESOURCE for child \"", _unique_name, "\"");

View File

@ -59,7 +59,7 @@ struct Init::Main : State_reporter::Producer, Child::Default_route_accessor,
{ {
Ram_quota const preserved_ram = _preserved_ram_from_config(_config.xml()); Ram_quota const preserved_ram = _preserved_ram_from_config(_config.xml());
Ram_quota avail_ram { _env.ram().avail() }; Ram_quota avail_ram = _env.ram().avail_ram();
if (preserved_ram.value > avail_ram.value) { if (preserved_ram.value > avail_ram.value) {
error("RAM preservation exceeds available memory"); error("RAM preservation exceeds available memory");

View File

@ -180,15 +180,15 @@ void Init::Server::_handle_create_session_request(Xml_node request,
char argbuf[Parent::Session_args::MAX_SIZE]; char argbuf[Parent::Session_args::MAX_SIZE];
strncpy(argbuf, args.string(), sizeof(argbuf)); strncpy(argbuf, args.string(), sizeof(argbuf));
size_t const ram_quota = Arg_string::find_arg(argbuf, "ram_quota").ulong_value(0); Ram_quota const ram_quota = ram_quota_from_args(argbuf);
size_t const keep_quota = route.service.factory().session_costs(); size_t const keep_quota = route.service.factory().session_costs();
if (ram_quota < keep_quota) if (ram_quota.value < keep_quota)
throw Genode::Service::Quota_exceeded(); throw Genode::Service::Quota_exceeded();
size_t const forward_ram_quota = ram_quota - keep_quota; Ram_quota const forward_ram_quota { ram_quota.value - keep_quota };
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", forward_ram_quota); Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", forward_ram_quota.value);
Session_state &session = Session_state &session =
route.service.create_session(route.service.factory(), route.service.create_session(route.service.factory(),
@ -237,7 +237,7 @@ void Init::Server::_handle_upgrade_session_request(Xml_node request,
{ {
_client_id_space.apply<Session_state>(id, [&] (Session_state &session) { _client_id_space.apply<Session_state>(id, [&] (Session_state &session) {
size_t const ram_quota = request.attribute_value("ram_quota", 0UL); Ram_quota const ram_quota { request.attribute_value("ram_quota", 0UL) };
session.phase = Session_state::UPGRADE_REQUESTED; session.phase = Session_state::UPGRADE_REQUESTED;

View File

@ -136,16 +136,11 @@ namespace Init {
inline void generate_ram_info(Xml_generator &xml, Ram_session const &ram) inline void generate_ram_info(Xml_generator &xml, Ram_session const &ram)
{ {
/*
* The const cast is needed because the 'Ram_session' accessors are
* non-const methods.
*/
Ram_session &ram_nonconst = const_cast<Ram_session &>(ram);
typedef String<32> Value; typedef String<32> Value;
xml.attribute("quota", Value(Number_of_bytes(ram_nonconst.quota()))); xml.attribute("quota", Value(ram.ram_quota()));
xml.attribute("used", Value(Number_of_bytes(ram_nonconst.used()))); xml.attribute("used", Value(ram.used_ram()));
xml.attribute("avail", Value(Number_of_bytes(ram_nonconst.avail()))); xml.attribute("avail", Value(ram.avail_ram()));
} }
/** /**

View File

@ -45,7 +45,7 @@ class Loader::Child : public Child_policy
Session_label const _label; Session_label const _label;
Name const _binary_name; Name const _binary_name;
size_t const _ram_quota; Ram_quota const _ram_quota;
Parent_services &_parent_services; Parent_services &_parent_services;
@ -62,7 +62,7 @@ class Loader::Child : public Child_policy
Allocator &alloc, Allocator &alloc,
Name const &binary_name, Name const &binary_name,
Session_label const &label, Session_label const &label,
size_t ram_quota, Ram_quota ram_quota,
Parent_services &parent_services, Parent_services &parent_services,
Service &local_rom_service, Service &local_rom_service,
Service &local_cpu_service, Service &local_cpu_service,
@ -74,7 +74,7 @@ class Loader::Child : public Child_policy
_alloc(alloc), _alloc(alloc),
_label(label), _label(label),
_binary_name(binary_name), _binary_name(binary_name),
_ram_quota(Genode::Child::effective_ram_quota(ram_quota)), _ram_quota(Genode::Child::effective_quota(ram_quota)),
_parent_services(parent_services), _parent_services(parent_services),
_local_nitpicker_service(local_nitpicker_service), _local_nitpicker_service(local_nitpicker_service),
_local_rom_service(local_rom_service), _local_rom_service(local_rom_service),

View File

@ -204,7 +204,7 @@ class Loader::Session_component : public Rpc_object<Session>
Env &_env; Env &_env;
Session_label const _label; Session_label const _label;
Xml_node const _config; Xml_node const _config;
size_t const _ram_quota; Ram_quota const _ram_quota;
Ram_session_client_guard _local_ram { _env.ram_session_cap(), _ram_quota }; Ram_session_client_guard _local_ram { _env.ram_session_cap(), _ram_quota };
Heap _md_alloc { _local_ram, _env.rm() }; Heap _md_alloc { _local_ram, _env.rm() };
size_t _subsystem_ram_quota_limit = 0; size_t _subsystem_ram_quota_limit = 0;
@ -244,7 +244,7 @@ class Loader::Session_component : public Rpc_object<Session>
* Constructor * Constructor
*/ */
Session_component(Env &env, Session_label const &label, Session_component(Env &env, Session_label const &label,
Xml_node config, size_t quota) Xml_node config, Ram_quota quota)
: :
_env(env), _label(label), _config(config), _ram_quota(quota) _env(env), _label(label), _config(config), _ram_quota(quota)
{ {
@ -287,9 +287,9 @@ class Loader::Session_component : public Rpc_object<Session>
throw Rom_module_does_not_exist(); } throw Rom_module_does_not_exist(); }
} }
void ram_quota(size_t quantum) override void ram_quota(Ram_quota quantum) override
{ {
_subsystem_ram_quota_limit = quantum; _subsystem_ram_quota_limit = quantum.value;
} }
void constrain_geometry(Area size) override void constrain_geometry(Area size) override
@ -335,13 +335,14 @@ class Loader::Session_component : public Rpc_object<Session>
} }
size_t const ram_quota = (_subsystem_ram_quota_limit > 0) size_t const ram_quota = (_subsystem_ram_quota_limit > 0)
? min(_subsystem_ram_quota_limit, _ram_quota) ? min(_subsystem_ram_quota_limit, _ram_quota.value)
: _ram_quota; : _ram_quota.value;
try { try {
_child.construct(_env, _md_alloc, binary_name.string(), _child.construct(_env, _md_alloc, binary_name.string(),
prefixed_label(_label, Session_label(label.string())), prefixed_label(_label, Session_label(label.string())),
ram_quota, _parent_services, _rom_service, Ram_quota{ram_quota},
_parent_services, _rom_service,
_cpu_service, _pd_service, _nitpicker_service, _cpu_service, _pd_service, _nitpicker_service,
_fault_sigh); _fault_sigh);
} }
@ -372,8 +373,6 @@ class Loader::Root : public Root_component<Session_component>
Session_component *_create_session(const char *args) Session_component *_create_session(const char *args)
{ {
size_t quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
Xml_node session_config("<policy/>"); Xml_node session_config("<policy/>");
Session_label const label = label_from_args(args); Session_label const label = label_from_args(args);
@ -381,7 +380,8 @@ class Loader::Root : public Root_component<Session_component>
try { session_config = Session_policy(label, _config); } try { session_config = Session_policy(label, _config); }
catch (...) { } catch (...) { }
return new (md_alloc()) Session_component(_env, label, session_config, quota); return new (md_alloc()) Session_component(_env, label, session_config,
ram_quota_from_args(args));
} }
public: public:

View File

@ -31,8 +31,8 @@ namespace Genode {
public: public:
Ram_session_client_guard(Ram_session_capability session, size_t amount) Ram_session_client_guard(Ram_session_capability session, Ram_quota amount)
: Ram_session_client(session), _amount(amount), _consumed(0) { } : Ram_session_client(session), _amount(amount.value), _consumed(0) { }
Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) override
{ {
@ -66,33 +66,34 @@ namespace Genode {
return Ram_session_client::dataspace_size(ds); return Ram_session_client::dataspace_size(ds);
} }
int transfer_quota(Ram_session_capability ram_session, size_t amount) override int transfer_quota(Ram_session_capability ram_session, Ram_quota amount) override
{ {
Lock::Guard _consumed_lock_guard(_consumed_lock); Lock::Guard _consumed_lock_guard(_consumed_lock);
if ((_amount - _consumed) < amount) { if ((_amount - _consumed) < amount.value) {
PWRN("Quota exceeded! amount=%lu, size=%lu, consumed=%lu", warning("Quota exceeded! amount=", _amount, ", "
_amount, amount, _consumed); "size=", amount.value, ", "
"consumed=", _consumed);
return -1; return -1;
} }
int result = Ram_session_client::transfer_quota(ram_session, amount); int result = Ram_session_client::transfer_quota(ram_session, amount);
if (result == 0) if (result == 0)
_consumed += amount; _consumed += amount.value;
return result; return result;
} }
size_t quota() override Ram_quota ram_quota() const override
{ {
return _amount; return { _amount };
} }
size_t used() override Ram_quota used_ram() const override
{ {
Lock::Guard _consumed_lock_guard(_consumed_lock); Lock::Guard _consumed_lock_guard(_consumed_lock);
return _consumed; return { _consumed };
} }
}; };
} }

View File

@ -974,7 +974,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
if (::Session::texture()) { if (::Session::texture()) {
enum { PRESERVED_RAM = 128*1024 }; enum { PRESERVED_RAM = 128*1024 };
if (_env.ram().avail() > _buffer_size + PRESERVED_RAM) { if (_env.ram().avail_ram().value > _buffer_size + PRESERVED_RAM) {
src_texture = static_cast<Texture<PT> const *>(::Session::texture()); src_texture = static_cast<Texture<PT> const *>(::Session::texture());
} else { } else {
Genode::warning("not enough RAM to preserve buffer content during resize"); Genode::warning("not enough RAM to preserve buffer content during resize");

View File

@ -32,7 +32,7 @@ class Bomb_child : public Child_policy
Env &_env; Env &_env;
Binary_name const _binary_name; Binary_name const _binary_name;
Name const _label; Name const _label;
size_t const _ram_quota; Ram_quota const _ram_quota;
Registry<Registered<Parent_service> > &_parent_services; Registry<Registered<Parent_service> > &_parent_services;
@ -45,12 +45,12 @@ class Bomb_child : public Child_policy
Bomb_child(Env &env, Bomb_child(Env &env,
Name const &binary_name, Name const &binary_name,
Name const &label, Name const &label,
size_t ram_quota, Ram_quota const ram_quota,
Registry<Registered<Parent_service> > &parent_services, Registry<Registered<Parent_service> > &parent_services,
unsigned generation) unsigned generation)
: :
_env(env), _binary_name(binary_name), _label(label), _env(env), _binary_name(binary_name), _label(label),
_ram_quota(Child::effective_ram_quota(ram_quota)), _ram_quota(Child::effective_quota(ram_quota)),
_parent_services(parent_services) _parent_services(parent_services)
{ {
String<64> config("<config generations=\"", generation, "\"/>"); String<64> config("<config generations=\"", generation, "\"/>");
@ -158,7 +158,7 @@ struct Bomb
unsigned const generation = config.xml().attribute_value("generations", 1U); unsigned const generation = config.xml().attribute_value("generations", 1U);
unsigned const children = config.xml().attribute_value("children", 2U); unsigned const children = config.xml().attribute_value("children", 2U);
unsigned const sleeptime = config.xml().attribute_value("sleep", 2000U); unsigned const sleeptime = config.xml().attribute_value("sleep", 2000U);
unsigned long const demand = config.xml().attribute_value("demand", 1024UL * 1024); size_t const ram_demand = config.xml().attribute_value("demand", 1024UL * 1024);
Heap heap { env.ram(), env.rm() }; Heap heap { env.ram(), env.rm() };
@ -169,9 +169,10 @@ struct Bomb
void construct_children() void construct_children()
{ {
unsigned long avail = env.ram().avail(); unsigned long avail_ram = env.ram().avail_ram().value;
unsigned long amount = (avail - demand) / children; Ram_quota const ram_amount { (avail_ram - ram_demand) / children };
if (amount < (demand * children)) {
if (ram_amount.value < (ram_demand * children)) {
log("I'm a leaf node - generation ", generation, log("I'm a leaf node - generation ", generation,
" - not enough memory."); " - not enough memory.");
return; return;
@ -191,7 +192,8 @@ struct Bomb
unique_child_name(child_registry, unique_child_name(child_registry,
binary_name, binary_name,
generation - 1), generation - 1),
amount, parent_services, generation - 1); ram_amount,
parent_services, generation - 1);
} }
/* master if we have a timer connection */ /* master if we have a timer connection */
@ -241,7 +243,7 @@ struct Bomb
timer->sigh(signal_timeout); timer->sigh(signal_timeout);
log("rounds=", rounds, " generations=", generation, " children=", log("rounds=", rounds, " generations=", generation, " children=",
children, " sleep=", sleeptime, " demand=", demand/1024, "K"); children, " sleep=", sleeptime, " demand=", ram_demand/1024, "K");
} }
construct_children(); construct_children();

View File

@ -24,7 +24,7 @@ struct Main
Env &env; Env &env;
int counter { -1 }; int counter { -1 };
Loader::Connection loader { env, 8 * 1024 * 1024 }; Loader::Connection loader { env, Ram_quota{8*1024*1024} };
Timer::Connection timer { env }; Timer::Connection timer { env };
Signal_handler<Main> timer_handler { env.ep(), *this, &Main::handle_timer }; Signal_handler<Main> timer_handler { env.ep(), *this, &Main::handle_timer };

View File

@ -36,7 +36,7 @@ struct Test::Policy
Policy(Env &env, Name const &name) Policy(Env &env, Name const &name)
: :
Slave::Policy(name, name, *this, env.ep().rpc_ep(), env.rm(), Slave::Policy(name, name, *this, env.ep().rpc_ep(), env.rm(),
env.ram_session_cap(), 1024*1024) env.ram_session_cap(), Ram_quota{1024*1024})
{ } { }
}; };

View File

@ -70,7 +70,7 @@ class Test_child : public Genode::Child_policy
private: private:
Env &_env; Env &_env;
size_t const _ram_quota = 1024*1024; Ram_quota const _ram_quota { 1024*1024 };
Binary_name const _binary_name; Binary_name const _binary_name;
Signal_context_capability _sigh; Signal_context_capability _sigh;
Parent_service _cpu_service { _env, Cpu_session::service_name() }; Parent_service _cpu_service { _env, Cpu_session::service_name() };
@ -162,7 +162,7 @@ struct Faulting_loader_child_test
void start_iteration(Env &env, Signal_context_capability fault_sigh) void start_iteration(Env &env, Signal_context_capability fault_sigh)
{ {
loader.construct(env, 1024*1024); loader.construct(env, Ram_quota{1024*1024});
/* register fault handler at loader session */ /* register fault handler at loader session */
loader->fault_sigh(fault_sigh); loader->fault_sigh(fault_sigh);
@ -207,7 +207,7 @@ struct Faulting_loader_grand_child_test
void start_iteration(Env &env, Signal_context_capability fault_sigh) void start_iteration(Env &env, Signal_context_capability fault_sigh)
{ {
loader.construct(env, 2*1024*1024); loader.construct(env, Ram_quota{2*1024*1024});
/* import config into loader session */ /* import config into loader session */
{ {

View File

@ -25,7 +25,7 @@ struct Test::Main
{ {
Env &_env; Env &_env;
Loader::Connection _loader { _env, 8*1024*1024 }; Loader::Connection _loader { _env, Ram_quota{8*1024*1024} };
Timer::Connection _timer { _env }; Timer::Connection _timer { _env };
Loader::Area _size; Loader::Area _size;

View File

@ -28,7 +28,7 @@ namespace Test {
static void print_quota_stats(Genode::Ram_session &ram) static void print_quota_stats(Genode::Ram_session &ram)
{ {
Genode::log("quota: avail=", ram.avail(), " used=", ram.used()); Genode::log("quota: avail=", ram.avail_ram().value, " used=", ram.used_ram().value);
} }
@ -139,7 +139,7 @@ void Component::construct(Genode::Env &env)
* Consume initial quota to let the test trigger the corner cases of * Consume initial quota to let the test trigger the corner cases of
* exceeded quota. * exceeded quota.
*/ */
size_t const avail_quota = env.ram().avail(); size_t const avail_quota = env.ram().avail_ram().value;
enum { KEEP_QUOTA = 64*1024 }; enum { KEEP_QUOTA = 64*1024 };
size_t const wasted_quota = (avail_quota >= KEEP_QUOTA) size_t const wasted_quota = (avail_quota >= KEEP_QUOTA)
? avail_quota - KEEP_QUOTA : 0; ? avail_quota - KEEP_QUOTA : 0;
@ -181,7 +181,7 @@ void Component::construct(Genode::Env &env)
dummy_handlers[i].destruct(); dummy_handlers[i].destruct();
} }
print_quota_stats(env.ram()); print_quota_stats(env.ram());
size_t const used_quota_after_draining_session = env.ram().used(); size_t const used_quota_after_draining_session = env.ram().used_ram().value;
/* /*
* When creating a new session, we try to donate RAM quota to the server. * When creating a new session, we try to donate RAM quota to the server.
@ -192,20 +192,20 @@ void Component::construct(Genode::Env &env)
static Ram_connection ram(env); static Ram_connection ram(env);
ram.ref_account(env.ram_session_cap()); ram.ref_account(env.ram_session_cap());
print_quota_stats(env.ram()); print_quota_stats(env.ram());
size_t const used_quota_after_session_request = env.ram().used(); size_t const used_quota_after_session_request = env.ram().used_ram().value;
/* /*
* Quota transfers from the component's RAM session may result in resource * Quota transfers from the component's RAM session may result in resource
* requests, too. * requests, too.
*/ */
log("\n-- out-of-memory during transfer-quota --"); log("\n-- out-of-memory during transfer-quota --");
int ret = env.ram().transfer_quota(ram.cap(), 512*1024); int ret = env.ram().transfer_quota(ram.cap(), Ram_quota{512*1024});
if (ret != 0) { if (ret != 0) {
error("transfer quota failed (ret = ", ret, ")"); error("transfer quota failed (ret = ", ret, ")");
throw Error(); throw Error();
} }
print_quota_stats(env.ram()); print_quota_stats(env.ram());
size_t const used_quota_after_transfer = env.ram().used(); size_t const used_quota_after_transfer = env.ram().used_ram().value;
/* /*
* Finally, resource requests could be caused by a regular allocation, * Finally, resource requests could be caused by a regular allocation,
@ -214,7 +214,7 @@ void Component::construct(Genode::Env &env)
log("\n-- out-of-memory during RAM allocation --"); log("\n-- out-of-memory during RAM allocation --");
env.ram().alloc(512*1024); env.ram().alloc(512*1024);
print_quota_stats(env.ram()); print_quota_stats(env.ram());
size_t const used_quota_after_alloc = env.ram().used(); size_t const used_quota_after_alloc = env.ram().used_ram().value;
/* /*
* Validate asserted effect of the individual steps on the used quota. * Validate asserted effect of the individual steps on the used quota.

View File

@ -98,7 +98,7 @@ void Test::Child::_handle_periodic_timeout()
{ {
size_t const chunk_size = 1024*1024; size_t const chunk_size = 1024*1024;
if (_env.ram().avail() < chunk_size) { if (_env.ram().avail_ram().value < chunk_size) {
if (_expand) { if (_expand) {
log("quota consumed, request additional resources"); log("quota consumed, request additional resources");
@ -197,8 +197,8 @@ class Test::Parent
void _print_status() void _print_status()
{ {
log("quota: ", _child.ram().quota() / 1024, " KiB " log("quota: ", _child.ram().ram_quota().value / 1024, " KiB "
"used: ", _child.ram().used() / 1024, " KiB"); "used: ", _child.ram().used_ram().value / 1024, " KiB");
} }
size_t _used_ram_prior_yield = 0; size_t _used_ram_prior_yield = 0;
@ -229,7 +229,7 @@ class Test::Parent
void _request_yield() void _request_yield()
{ {
/* remember quantum of resources used by the child */ /* remember quantum of resources used by the child */
_used_ram_prior_yield = _child.ram().used(); _used_ram_prior_yield = _child.ram().used_ram().value;
log("request yield (ram prior yield: ", _used_ram_prior_yield); log("request yield (ram prior yield: ", _used_ram_prior_yield);
@ -259,7 +259,7 @@ class Test::Parent
_print_status(); _print_status();
/* validate that the amount of yielded resources matches the request */ /* validate that the amount of yielded resources matches the request */
size_t const used_after_yield = _child.ram().used(); size_t const used_after_yield = _child.ram().used_ram().value;
if (used_after_yield + 5*1024*1024 > _used_ram_prior_yield) { if (used_after_yield + 5*1024*1024 > _used_ram_prior_yield) {
error("child has not yielded enough resources"); error("child has not yielded enough resources");
throw Insufficient_yield(); throw Insufficient_yield();
@ -296,7 +296,7 @@ class Test::Parent
: :
Slave::Policy(Label("child"), "test-resource_yield", Slave::Policy(Label("child"), "test-resource_yield",
*this, env.ep().rpc_ep(), env.rm(), *this, env.ep().rpc_ep(), env.rm(),
env.ram_session_cap(), SLAVE_QUOTA), env.ram_session_cap(), Ram_quota{SLAVE_QUOTA}),
_parent(parent) _parent(parent)
{ {
configure("<config child=\"yes\" />"); configure("<config child=\"yes\" />");

View File

@ -495,7 +495,7 @@ void Component::construct(Genode::Env &env)
/* populate the directory file system at / */ /* populate the directory file system at / */
vfs_root.num_dirent("/"); vfs_root.num_dirent("/");
size_t initial_consumption = env.ram().used(); size_t initial_consumption = env.ram().used_ram().value;
/************************** /**************************
** Generate directories ** ** Generate directories **
@ -517,7 +517,7 @@ void Component::construct(Genode::Env &env)
log("created ",count," empty directories, ", log("created ",count," empty directories, ",
(elapsed_ms*1000)/count,"μs/op , ", (elapsed_ms*1000)/count,"μs/op , ",
env.ram().used()/1024,"KB consumed"); env.ram().used_ram().value/1024,"KiB consumed");
} }
@ -541,7 +541,7 @@ void Component::construct(Genode::Env &env)
log("created ",count," empty files, ", log("created ",count," empty files, ",
(elapsed_ms*1000)/count,"μs/op, ", (elapsed_ms*1000)/count,"μs/op, ",
env.ram().used()/1024,"KB consumed"); env.ram().used_ram().value/1024,"KiB consumed");
} }
@ -551,7 +551,7 @@ void Component::construct(Genode::Env &env)
if (!config_xml.attribute_value("write", true)) { if (!config_xml.attribute_value("write", true)) {
elapsed_ms = timer.elapsed_ms(); elapsed_ms = timer.elapsed_ms();
log("total: ",elapsed_ms,"ms, ",env.ram().used()/1024,"K consumed"); log("total: ",elapsed_ms,"ms, ",env.ram().used_ram().value/1024,"K consumed");
return die(env, 0); return die(env, 0);
} }
{ {
@ -572,7 +572,7 @@ void Component::construct(Genode::Env &env)
log("wrote ",count," bytes ", log("wrote ",count," bytes ",
count/elapsed_ms,"kB/s, ", count/elapsed_ms,"kB/s, ",
env.ram().used()/1024,"KB consumed"); env.ram().used_ram().value/1024,"KiB consumed");
} }
@ -583,7 +583,7 @@ void Component::construct(Genode::Env &env)
if (!config_xml.attribute_value("read", true)) { if (!config_xml.attribute_value("read", true)) {
elapsed_ms = timer.elapsed_ms(); elapsed_ms = timer.elapsed_ms();
log("total: ",elapsed_ms,"ms, ",env.ram().used()/1024,"KB consumed"); log("total: ",elapsed_ms,"ms, ",env.ram().used_ram().value/1024,"KiB consumed");
return die(env, 0); return die(env, 0);
} }
{ {
@ -603,7 +603,7 @@ void Component::construct(Genode::Env &env)
log("read ",count," bytes, ", log("read ",count," bytes, ",
count/elapsed_ms,"kB/s, ", count/elapsed_ms,"kB/s, ",
env.ram().used()/1024,"KB consumed"); env.ram().used_ram().value/1024,"KiB consumed");
} }
@ -613,7 +613,7 @@ void Component::construct(Genode::Env &env)
if (!config_xml.attribute_value("unlink", true)) { if (!config_xml.attribute_value("unlink", true)) {
elapsed_ms = timer.elapsed_ms(); elapsed_ms = timer.elapsed_ms();
log("total: ",elapsed_ms,"ms, ",env.ram().used()/1024,"KB consumed"); log("total: ",elapsed_ms,"ms, ",env.ram().used_ram().value/1024,"KiB consumed");
return die(env, 0); return die(env, 0);
} }
@ -635,18 +635,18 @@ void Component::construct(Genode::Env &env)
vfs_root.sync("/"); vfs_root.sync("/");
log("unlinked ",count," files in ",elapsed_ms,"ms, ", log("unlinked ",count," files in ",elapsed_ms,"ms, ",
env.ram().used()/1024,"KB consumed"); env.ram().used_ram().value/1024,"KiB consumed");
} }
log("total: ",timer.elapsed_ms(),"ms, ", log("total: ",timer.elapsed_ms(),"ms, ",
env.ram().used()/1024,"KB consumed"); env.ram().used_ram().value/1024,"KiB consumed");
size_t outstanding = env.ram().used() - initial_consumption; size_t outstanding = env.ram().used_ram().value - initial_consumption;
if (outstanding) { if (outstanding) {
if (outstanding < 1024) if (outstanding < 1024)
error(outstanding, "B not freed after unlink and sync!"); error(outstanding, "B not freed after unlink and sync!");
else else
error(outstanding/1024,"KB not freed after unlink and sync!"); error(outstanding/1024,"KiB not freed after unlink and sync!");
} }
die(env, 0); die(env, 0);

View File

@ -59,7 +59,7 @@ class Gdb_monitor::App_child : public Child_policy
Region_map &_rm; Region_map &_rm;
size_t _ram_quota; Ram_quota _ram_quota;
Rpc_entrypoint _entrypoint; Rpc_entrypoint _entrypoint;
@ -111,7 +111,7 @@ class Gdb_monitor::App_child : public Child_policy
App_child(Env &env, App_child(Env &env,
Allocator &alloc, Allocator &alloc,
char const *unique_name, char const *unique_name,
size_t ram_quota, Ram_quota ram_quota,
Signal_receiver &signal_receiver, Signal_receiver &signal_receiver,
Xml_node target_node) Xml_node target_node)
: :

View File

@ -467,7 +467,7 @@ extern "C" int fork()
return -1; return -1;
} }
Number_of_bytes ram_quota = genode_env->ram().avail() - preserved_ram_quota; Number_of_bytes ram_quota = genode_env->ram().avail_ram().value - preserved_ram_quota;
/* start the application */ /* start the application */
@ -482,7 +482,7 @@ extern "C" int fork()
App_child *child = new (alloc) App_child(*genode_env, App_child *child = new (alloc) App_child(*genode_env,
alloc, alloc,
filename, filename,
ram_quota, Ram_quota{ram_quota},
signal_receiver, signal_receiver,
target_node); target_node);

View File

@ -56,20 +56,20 @@ int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap, int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap,
size_t amount) Ram_quota amount)
{ {
return _parent_ram_session.transfer_quota(ram_session_cap, amount); return _parent_ram_session.transfer_quota(ram_session_cap, amount);
} }
size_t Ram_session_component::quota() Ram_quota Ram_session_component::ram_quota() const
{ {
return _parent_ram_session.quota(); return _parent_ram_session.ram_quota();
} }
size_t Ram_session_component::used() Ram_quota Ram_session_component::used_ram() const
{ {
return _parent_ram_session.used(); return _parent_ram_session.used_ram();
} }

View File

@ -60,9 +60,9 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
void free(Ram_dataspace_capability) override; void free(Ram_dataspace_capability) override;
size_t dataspace_size(Ram_dataspace_capability) const override; size_t dataspace_size(Ram_dataspace_capability) const override;
int ref_account(Ram_session_capability) override; int ref_account(Ram_session_capability) override;
int transfer_quota(Ram_session_capability, size_t) override; int transfer_quota(Ram_session_capability, Ram_quota) override;
size_t quota() override; Ram_quota ram_quota() const override;
size_t used() override; Ram_quota used_ram() const override;
}; };
#endif /* _RAM_SESSION_COMPONENT_H_ */ #endif /* _RAM_SESSION_COMPONENT_H_ */

View File

@ -1403,7 +1403,7 @@ void Component::construct(Genode::Env &env)
Genode::log("--- Vancouver VMM starting ---"); Genode::log("--- Vancouver VMM starting ---");
/* request max available memory */ /* request max available memory */
vm_size = env.ram().avail(); vm_size = env.ram().avail_ram().value;
/* reserve some memory for the VMM */ /* reserve some memory for the VMM */
vm_size -= 8 * 1024 * 1024; vm_size -= 8 * 1024 * 1024;
/* calculate max memory for the VM */ /* calculate max memory for the VM */

View File

@ -341,7 +341,7 @@ extern "C" int getrlimit(int resource, struct rlimit *rlim)
#endif #endif
return 0; return 0;
case RLIMIT_RSS: case RLIMIT_RSS:
rlim->rlim_cur = rlim->rlim_max = Genode::env()->ram_session()->quota(); rlim->rlim_cur = rlim->rlim_max = Genode::env()->ram_session()->ram_quota().value;
return 0; return 0;
case RLIMIT_NPROC: case RLIMIT_NPROC:
case RLIMIT_NOFILE: case RLIMIT_NOFILE:

View File

@ -189,9 +189,9 @@ class Noux::Ram_session_component : public Rpc_object<Ram_session>
} }
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, Ram_quota) { return 0; }
size_t quota() { return _ram.quota(); } Ram_quota ram_quota() const override { return _ram.ram_quota(); }
size_t used() { return _used_ram_quota; } Ram_quota used_ram() const override { return Ram_quota{_used_ram_quota}; }
}; };
#endif /* _NOUX__RAM_SESSION_COMPONENT_H_ */ #endif /* _NOUX__RAM_SESSION_COMPONENT_H_ */

View File

@ -75,7 +75,7 @@ class Avl_ds : public Genode::Avl_node<Avl_ds>
genode_env().ram().free(_ds); genode_env().ram().free(_ds);
Genode::log("free up ", _size, " ", _mem_allocated, "/", Genode::log("free up ", _size, " ", _mem_allocated, "/",
_mem_unused, " hit=", hit, "/", hit_coarse, " avail=", _mem_unused, " hit=", hit, "/", hit_coarse, " avail=",
genode_env().ram().avail()); genode_env().ram().avail_ram());
} }
void unused() void unused()
@ -140,7 +140,7 @@ class Avl_ds : public Genode::Avl_node<Avl_ds>
while (_unused_ds.first() && cbx && while (_unused_ds.first() && cbx &&
(_mem_allocated + cb > MEMORY_MAX || (_mem_allocated + cb > MEMORY_MAX ||
_mem_unused + cb > MEMORY_CACHED || _mem_unused + cb > MEMORY_CACHED ||
genode_env().ram().avail() < cb * 2 genode_env().ram().avail_ram().value < cb * 2
) )
) )
{ {

View File

@ -379,7 +379,7 @@ HRESULT genode_check_memory_config(ComObjPtr<Machine> machine)
return rc; return rc;
/* Request max available memory */ /* Request max available memory */
size_t memory_genode = genode_env().ram().avail() >> 20; size_t memory_genode = genode_env().ram().avail_ram().value >> 20;
size_t memory_vmm = 28; size_t memory_vmm = 28;
if (memory_vbox + memory_vmm > memory_genode) { if (memory_vbox + memory_vmm > memory_genode) {

View File

@ -382,7 +382,7 @@ HRESULT genode_check_memory_config(ComObjPtr<Machine> machine)
return rc; return rc;
/* Request max available memory */ /* Request max available memory */
size_t memory_genode = genode_env().ram().avail() >> 20; size_t memory_genode = genode_env().ram().avail_ram().value >> 20;
size_t memory_vmm = 28; size_t memory_vmm = 28;
if (memory_vbox + memory_vmm > memory_genode) { if (memory_vbox + memory_vmm > memory_genode) {