mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
b2b5d1b2d2
The child handling as done by CLI monitor is worth reusing. Hence, this patch moves the corresponding headers to 'os/include/cli_monitor/'.
138 lines
2.9 KiB
C++
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_ */
|