genode/repos/base/src/base/env/platform_env.h

169 lines
4.8 KiB
C
Raw Normal View History

2011-12-22 16:19:25 +01:00
/*
* \brief Platform environment of Genode process
* \author Norman Feske
* \author Christian Helmuth
* \date 2006-07-28
*
* This file is a generic variant of the platform environment, which is
* suitable for platforms such as L4ka::Pistachio and L4/Fiasco. On other
* platforms, it may be replaced by a platform-specific version residing
* in the corresponding 'base-<platform>' repository.
*/
/*
2013-01-10 21:44:47 +01:00
* Copyright (C) 2006-2013 Genode Labs GmbH
2011-12-22 16:19:25 +01:00
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _PLATFORM_ENV_H_
#define _PLATFORM_ENV_H_
2011-12-22 16:19:25 +01:00
/* Genode includes */
#include <base/printf.h>
2011-12-22 16:19:25 +01:00
#include <base/env.h>
#include <base/heap.h>
2011-12-22 16:19:25 +01:00
/* local includes */
#include <platform_env_common.h>
2011-12-22 16:19:25 +01:00
namespace Genode {
struct Expanding_cpu_session_client;
class Platform_env;
}
2011-12-22 16:19:25 +01:00
struct Genode::Expanding_cpu_session_client : Upgradeable_client<Genode::Cpu_session_client>
{
Expanding_cpu_session_client(Genode::Cpu_session_capability cap)
:
/*
* We need to upcast the capability because on some platforms (i.e.,
* NOVA), 'Cpu_session_client' refers to a platform-specific session
* interface ('Nova_cpu_session').
*/
Upgradeable_client<Genode::Cpu_session_client>
(static_cap_cast<Genode::Cpu_session_client::Rpc_interface>(cap))
{ }
thread API & CPU session: accounting of CPU quota In the init configuration one can configure the donation of CPU time via 'resource' tags that have the attribute 'name' set to "CPU" and the attribute 'quantum' set to the percentage of CPU quota that init shall donate. The pattern is the same as when donating RAM quota. ! <start name="test"> ! <resource name="CPU" quantum="75"/> ! </start> This would cause init to try donating 75% of its CPU quota to the child "test". Init and core do not preserve CPU quota for their own requirements by default as it is done with RAM quota. The CPU quota that a process owns can be applied through the thread constructor. The constructor has been enhanced by an argument that indicates the percentage of the programs CPU quota that shall be granted to the new thread. So 'Thread(33, "test")' would cause the backing CPU session to try to grant 33% of the programs CPU quota to the thread "test". By now, the CPU quota of a thread can't be altered after construction. Constructing a thread with CPU quota 0 doesn't mean the thread gets never scheduled but that the thread has no guaranty to receive CPU time. Such threads have to live with excess CPU time. Threads that already existed in the official repositories of Genode were adapted in the way that they receive a quota of 0. This commit also provides a run test 'cpu_quota' in base-hw (the only kernel that applies the CPU-quota scheme currently). The test basically runs three threads with different physical CPU quota. The threads simply count for 30 seconds each and the test then checks wether the counter values relate to the CPU-quota distribution. fix #1275
2014-10-16 11:15:46 +02:00
Thread_capability
create_thread(size_t quota, Name const &name, addr_t utcb)
{
return retry<Cpu_session::Out_of_metadata>(
thread API & CPU session: accounting of CPU quota In the init configuration one can configure the donation of CPU time via 'resource' tags that have the attribute 'name' set to "CPU" and the attribute 'quantum' set to the percentage of CPU quota that init shall donate. The pattern is the same as when donating RAM quota. ! <start name="test"> ! <resource name="CPU" quantum="75"/> ! </start> This would cause init to try donating 75% of its CPU quota to the child "test". Init and core do not preserve CPU quota for their own requirements by default as it is done with RAM quota. The CPU quota that a process owns can be applied through the thread constructor. The constructor has been enhanced by an argument that indicates the percentage of the programs CPU quota that shall be granted to the new thread. So 'Thread(33, "test")' would cause the backing CPU session to try to grant 33% of the programs CPU quota to the thread "test". By now, the CPU quota of a thread can't be altered after construction. Constructing a thread with CPU quota 0 doesn't mean the thread gets never scheduled but that the thread has no guaranty to receive CPU time. Such threads have to live with excess CPU time. Threads that already existed in the official repositories of Genode were adapted in the way that they receive a quota of 0. This commit also provides a run test 'cpu_quota' in base-hw (the only kernel that applies the CPU-quota scheme currently). The test basically runs three threads with different physical CPU quota. The threads simply count for 30 seconds each and the test then checks wether the counter values relate to the CPU-quota distribution. fix #1275
2014-10-16 11:15:46 +02:00
[&] () {
return Cpu_session_client::create_thread(quota, name, utcb); },
[&] () { upgrade_ram(8*1024); });
}
};
2011-12-22 16:19:25 +01:00
class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve
{
private:
2011-12-22 16:19:25 +01:00
Expanding_parent_client _parent_client;
2011-12-22 16:19:25 +01:00
struct Resources
{
template <typename T>
Capability<T> request(Parent &parent, char const *service)
{
return static_cap_cast<T>(parent.session(service, ""));
}
Expanding_ram_session_client ram;
Expanding_cpu_session_client cpu;
Expanding_rm_session_client rm;
Pd_session_client pd;
Resources(Parent &parent)
:
ram(request<Ram_session>(parent, "Env::ram_session")),
cpu(request<Cpu_session>(parent, "Env::cpu_session")),
rm (request<Rm_session> (parent, "Env::rm_session")),
pd (request<Pd_session> (parent, "Env::pd_session"))
{ }
};
Resources _resources;
Heap _heap;
char _initial_heap_chunk[sizeof(addr_t) * 4096];
/*
* Emergency RAM reserve
*
* See the comment of '_fallback_sig_cap()' in 'env/env.cc'.
*/
constexpr static size_t _emergency_ram_size() { return 8*1024; }
Ram_dataspace_capability _emergency_ram_ds;
public:
/**
* Standard constructor
*/
Platform_env()
:
_parent_client(Genode::parent_cap(), *this),
_resources(_parent_client),
_heap(&_resources.ram, &_resources.rm, Heap::UNLIMITED,
_initial_heap_chunk, sizeof(_initial_heap_chunk)),
_emergency_ram_ds(_resources.ram.alloc(_emergency_ram_size()))
{ }
2011-12-22 16:19:25 +01:00
/**
* Reload parent capability and reinitialize environment resources
*
* This function is solely used for implementing fork semantics.
* After forking a process, the new child process is executed
* within a copy of the address space of the forking process.
* Thereby, the new process inherits the original 'env' object of
* the forking process, which is meaningless in the context of the
* new process. By calling this function, the new process is able
* to reinitialize its 'env' with meaningful capabilities obtained
* via its updated parent capability.
*/
void reinit(Native_capability::Dst, long);
/**
* Reinitialize main-thread object
*
* \param context_area_rm new RM session of the context area
*
* This function is solely used for implementing fork semantics
* as provided by the Noux environment.
*/
void reinit_main_thread(Rm_session_capability &);
2011-12-22 16:19:25 +01:00
/*************************************
** Emergency_ram_reserve interface **
*************************************/
void release() {
PDBG("used before freeing emergency=%zu", _resources.ram.used());
_resources.ram.free(_emergency_ram_ds);
PDBG("used after freeing emergency=%zu", _resources.ram.used());
}
/*******************
** Env interface **
*******************/
2011-12-22 16:19:25 +01:00
Parent *parent() { return &_parent_client; }
Ram_session *ram_session() { return &_resources.ram; }
Ram_session_capability ram_session_cap() { return _resources.ram; }
Cpu_session *cpu_session() { return &_resources.cpu; }
Cpu_session_capability cpu_session_cap() { return _resources.cpu; }
Rm_session *rm_session() { return &_resources.rm; }
Pd_session *pd_session() { return &_resources.pd; }
Allocator *heap() { return &_heap; }
};
2011-12-22 16:19:25 +01:00
#endif /* _PLATFORM_ENV_H_ */