2013-10-05 17:07:34 +00:00
|
|
|
/*
|
|
|
|
* \brief RAM management
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2013-10-14
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2013-2017 Genode Labs GmbH
|
2013-10-05 17:07:34 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 12:23:52 +00:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2013-10-05 17:07:34 +00:00
|
|
|
*/
|
|
|
|
|
2014-10-02 12:47:08 +00:00
|
|
|
#ifndef _INCLUDE__CLI_MONITOR__RAM_H_
|
|
|
|
#define _INCLUDE__CLI_MONITOR__RAM_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <ram_session/connection.h>
|
2013-10-05 17:07:34 +00:00
|
|
|
|
2017-01-03 11:52:42 +00:00
|
|
|
namespace Cli_monitor { class Ram; }
|
|
|
|
|
|
|
|
|
|
|
|
class Cli_monitor::Ram
|
2013-10-05 17:07:34 +00:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2014-10-02 12:47:08 +00:00
|
|
|
typedef Genode::size_t size_t;
|
|
|
|
|
2017-01-03 11:52:42 +00:00
|
|
|
Genode::Ram_session &_ram;
|
|
|
|
Genode::Ram_session_capability _ram_cap;
|
|
|
|
|
2013-10-05 17:07:34 +00:00
|
|
|
Genode::Lock mutable _lock;
|
|
|
|
Genode::Signal_context_capability _yield_sigh;
|
|
|
|
Genode::Signal_context_capability _resource_avail_sigh;
|
|
|
|
|
|
|
|
size_t _preserve;
|
|
|
|
|
|
|
|
void _validate_preservation()
|
|
|
|
{
|
2017-05-07 23:33:40 +00:00
|
|
|
if (_ram.avail_ram().value < _preserve)
|
2013-10-05 17:07:34 +00:00
|
|
|
Genode::Signal_transmitter(_yield_sigh).submit();
|
2013-10-18 12:31:49 +00:00
|
|
|
|
|
|
|
/* verify to answer outstanding resource requests too */
|
2017-05-07 23:33:40 +00:00
|
|
|
if (_ram.avail_ram().value > _preserve)
|
2013-10-18 12:31:49 +00:00
|
|
|
Genode::Signal_transmitter(_resource_avail_sigh).submit();
|
2013-10-05 17:07:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
struct Status
|
|
|
|
{
|
|
|
|
size_t quota, used, avail, preserve;
|
|
|
|
Status(size_t quota, size_t used, size_t avail, size_t preserve)
|
|
|
|
: quota(quota), used(used), avail(avail), preserve(preserve) { }
|
|
|
|
};
|
|
|
|
|
2017-01-03 11:52:42 +00:00
|
|
|
Ram(Genode::Ram_session &ram,
|
|
|
|
Genode::Ram_session_capability ram_cap,
|
|
|
|
size_t preserve,
|
2013-10-05 17:07:34 +00:00
|
|
|
Genode::Signal_context_capability yield_sigh,
|
|
|
|
Genode::Signal_context_capability resource_avail_sigh)
|
|
|
|
:
|
2017-01-03 11:52:42 +00:00
|
|
|
_ram(ram), _ram_cap(ram_cap),
|
2013-10-17 09:42:04 +00:00
|
|
|
_yield_sigh(yield_sigh),
|
|
|
|
_resource_avail_sigh(resource_avail_sigh),
|
|
|
|
_preserve(preserve)
|
2013-10-05 17:07:34 +00:00
|
|
|
{ }
|
|
|
|
|
|
|
|
size_t preserve() const
|
|
|
|
{
|
|
|
|
Genode::Lock::Guard guard(_lock);
|
|
|
|
|
|
|
|
return _preserve;
|
|
|
|
}
|
|
|
|
|
|
|
|
void preserve(size_t preserve)
|
|
|
|
{
|
|
|
|
Genode::Lock::Guard guard(_lock);
|
|
|
|
|
|
|
|
_preserve = preserve;
|
|
|
|
|
|
|
|
_validate_preservation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Status status() const
|
|
|
|
{
|
|
|
|
Genode::Lock::Guard guard(_lock);
|
|
|
|
|
2017-05-07 23:33:40 +00:00
|
|
|
return Status(_ram.ram_quota().value, _ram.used_ram().value,
|
|
|
|
_ram.avail_ram().value, _preserve);
|
2013-10-05 17:07:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void validate_preservation()
|
|
|
|
{
|
|
|
|
Genode::Lock::Guard guard(_lock);
|
|
|
|
|
|
|
|
_validate_preservation();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Exception type
|
|
|
|
*/
|
|
|
|
class Transfer_quota_failed { };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \throw Transfer_quota_failed
|
|
|
|
*/
|
|
|
|
void withdraw_from(Genode::Ram_session_capability from, size_t amount)
|
|
|
|
{
|
2017-05-08 10:33:56 +00:00
|
|
|
using namespace Genode;
|
2013-10-05 17:07:34 +00:00
|
|
|
|
2017-05-08 10:33:56 +00:00
|
|
|
Lock::Guard guard(_lock);
|
2013-10-05 17:07:34 +00:00
|
|
|
|
2017-05-08 10:33:56 +00:00
|
|
|
try { Ram_session_client(from).transfer_quota(_ram_cap, Ram_quota{amount}); }
|
|
|
|
catch (...) { throw Transfer_quota_failed(); }
|
2013-10-05 17:07:34 +00:00
|
|
|
|
2017-05-08 10:33:56 +00:00
|
|
|
Signal_transmitter(_resource_avail_sigh).submit();
|
2013-10-05 17:07:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \throw Transfer_quota_failed
|
|
|
|
*/
|
|
|
|
void transfer_to(Genode::Ram_session_capability to, size_t amount)
|
|
|
|
{
|
|
|
|
Genode::Lock::Guard guard(_lock);
|
|
|
|
|
2017-05-07 23:33:40 +00:00
|
|
|
if (_ram.avail_ram().value < (_preserve + amount)) {
|
2013-10-18 12:37:22 +00:00
|
|
|
Genode::Signal_transmitter(_yield_sigh).submit();
|
|
|
|
throw Transfer_quota_failed();
|
|
|
|
}
|
|
|
|
|
2017-05-08 10:33:56 +00:00
|
|
|
try { _ram.transfer_quota(to, Genode::Ram_quota{amount}); }
|
|
|
|
catch (...) { throw Transfer_quota_failed(); }
|
2013-10-05 17:07:34 +00:00
|
|
|
}
|
|
|
|
|
2017-05-07 23:33:40 +00:00
|
|
|
size_t avail() const { return _ram.avail_ram().value; }
|
2013-10-05 17:07:34 +00:00
|
|
|
};
|
|
|
|
|
2014-10-02 12:47:08 +00:00
|
|
|
#endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */
|