genode/repos/os/include/cli_monitor/ram.h

138 lines
2.9 KiB
C++

/*
* \brief RAM management
* \author Norman Feske
* \date 2013-10-14
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__CLI_MONITOR__RAM_H_
#define _INCLUDE__CLI_MONITOR__RAM_H_
/* Genode includes */
#include <ram_session/connection.h>
class Ram
{
private:
typedef Genode::size_t size_t;
Genode::Lock mutable _lock;
Genode::Ram_session &_ram = *Genode::env()->ram_session();
Genode::Ram_session_capability _ram_cap = Genode::env()->ram_session_cap();
Genode::Signal_context_capability _yield_sigh;
Genode::Signal_context_capability _resource_avail_sigh;
size_t _preserve;
void _validate_preservation()
{
if (_ram.avail() < _preserve)
Genode::Signal_transmitter(_yield_sigh).submit();
/* verify to answer outstanding resource requests too */
if (_ram.avail() > _preserve)
Genode::Signal_transmitter(_resource_avail_sigh).submit();
}
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) { }
};
Ram(size_t preserve,
Genode::Signal_context_capability yield_sigh,
Genode::Signal_context_capability resource_avail_sigh)
:
_yield_sigh(yield_sigh),
_resource_avail_sigh(resource_avail_sigh),
_preserve(preserve)
{ }
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);
return Status(_ram.quota(), _ram.used(), _ram.avail(), _preserve);
}
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)
{
Genode::Lock::Guard guard(_lock);
int const ret =
Genode::Ram_session_client(from).transfer_quota(_ram_cap, amount);
if (ret != 0)
throw Transfer_quota_failed();
Genode::Signal_transmitter(_resource_avail_sigh).submit();
}
/**
* \throw Transfer_quota_failed
*/
void transfer_to(Genode::Ram_session_capability to, size_t amount)
{
Genode::Lock::Guard guard(_lock);
if (_ram.avail() < (_preserve + amount)) {
Genode::Signal_transmitter(_yield_sigh).submit();
throw Transfer_quota_failed();
}
int const ret = _ram.transfer_quota(to, amount);
if (ret != 0)
throw Transfer_quota_failed();
}
/**
* Return singleton object
*/
static Ram &ram();
};
#endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */