2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief CPU (processing time) manager session interface
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \date 2006-06-27
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2006-2017 Genode Labs GmbH
|
2011-12-22 15:19:25 +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.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INCLUDE__CPU_SESSION__CPU_SESSION_H_
|
|
|
|
#define _INCLUDE__CPU_SESSION__CPU_SESSION_H_
|
|
|
|
|
2014-10-16 09:15:46 +00:00
|
|
|
#include <cpu_session/capability.h>
|
2016-05-10 16:05:38 +00:00
|
|
|
#include <cpu_thread/cpu_thread.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <base/stdint.h>
|
|
|
|
#include <base/rpc_args.h>
|
|
|
|
#include <session/session.h>
|
2016-05-10 16:05:38 +00:00
|
|
|
#include <dataspace/capability.h>
|
2016-04-20 19:12:57 +00:00
|
|
|
#include <pd_session/pd_session.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
namespace Genode {
|
|
|
|
|
|
|
|
struct Cpu_session;
|
|
|
|
struct Cpu_session_client;
|
2019-01-30 16:27:46 +00:00
|
|
|
|
|
|
|
typedef Capability<Cpu_thread> Thread_capability;
|
2016-11-06 13:26:34 +00:00
|
|
|
}
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
struct Genode::Cpu_session : Session
|
|
|
|
{
|
2017-05-24 12:41:19 +00:00
|
|
|
/**
|
|
|
|
* \noapi
|
|
|
|
*/
|
2016-11-06 13:26:34 +00:00
|
|
|
static const char *service_name() { return "CPU"; }
|
|
|
|
|
2017-05-07 20:03:25 +00:00
|
|
|
/*
|
|
|
|
* A CPU session consumes a dataspace capability for the session-object
|
|
|
|
* allocation, its session capability, the capability of the 'Native_cpu'
|
|
|
|
* RPC interface, and a capability for the trace-control dataspace.
|
|
|
|
*/
|
2020-05-05 12:27:29 +00:00
|
|
|
enum { CAP_QUOTA = 6 };
|
2017-05-07 20:03:25 +00:00
|
|
|
|
2016-11-06 13:26:34 +00:00
|
|
|
typedef Cpu_session_client Client;
|
|
|
|
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/*********************
|
|
|
|
** Exception types **
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
class Thread_creation_failed : public Exception { };
|
|
|
|
class Quota_exceeded : public Thread_creation_failed { };
|
|
|
|
|
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
enum { THREAD_NAME_LEN = 32 };
|
2015-03-04 20:12:14 +00:00
|
|
|
enum { PRIORITY_LIMIT = 1 << 16 };
|
|
|
|
enum { QUOTA_LIMIT_LOG2 = 15 };
|
|
|
|
enum { QUOTA_LIMIT = 1 << QUOTA_LIMIT_LOG2 };
|
|
|
|
enum { DEFAULT_PRIORITY = 0 };
|
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
/**
|
|
|
|
* Thread weight argument type for 'create_thread'
|
|
|
|
*/
|
|
|
|
struct Weight
|
|
|
|
{
|
|
|
|
enum { DEFAULT_WEIGHT = 10 };
|
|
|
|
size_t value = DEFAULT_WEIGHT;
|
|
|
|
Weight() { }
|
|
|
|
explicit Weight(size_t value) : value(value) { }
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef String<THREAD_NAME_LEN> Name;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2015-03-27 13:05:55 +00:00
|
|
|
/**
|
|
|
|
* Physical quota configuration
|
|
|
|
*/
|
|
|
|
struct Quota;
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
virtual ~Cpu_session() { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new thread
|
|
|
|
*
|
2016-04-20 19:12:57 +00:00
|
|
|
* \param pd protection domain where the thread will be executed
|
|
|
|
* \param name name for the thread
|
|
|
|
* \param affinity CPU affinity, referring to the session-local
|
|
|
|
* affinity space
|
2016-05-04 10:27:17 +00:00
|
|
|
* \param weight CPU quota that shall be granted to the thread
|
|
|
|
* \param utcb base of the UTCB that will be used by the thread
|
2016-04-20 19:12:57 +00:00
|
|
|
* \return capability representing the new thread
|
|
|
|
* \throw Thread_creation_failed
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
* \throw Out_of_ram
|
|
|
|
* \throw Out_of_caps
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2016-04-20 19:12:57 +00:00
|
|
|
virtual Thread_capability create_thread(Capability<Pd_session> pd,
|
|
|
|
Name const &name,
|
2016-05-04 10:27:17 +00:00
|
|
|
Affinity::Location affinity,
|
|
|
|
Weight weight,
|
2016-04-20 19:12:57 +00:00
|
|
|
addr_t utcb = 0) = 0;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Kill an existing thread
|
|
|
|
*
|
|
|
|
* \param thread capability of the thread to kill
|
|
|
|
*/
|
|
|
|
virtual void kill_thread(Thread_capability thread) = 0;
|
|
|
|
|
|
|
|
/**
|
2016-05-10 16:05:38 +00:00
|
|
|
* Register default signal handler for exceptions
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
2016-05-10 16:05:38 +00:00
|
|
|
* This handler is used for all threads that have no explicitly installed
|
|
|
|
* exception handler.
|
2015-03-04 20:12:14 +00:00
|
|
|
*
|
|
|
|
* On Linux, this exception is delivered when the process triggers
|
|
|
|
* a SIGCHLD. On other platforms, this exception is delivered on
|
|
|
|
* the occurrence of CPU exceptions such as division by zero.
|
|
|
|
*/
|
2016-05-10 16:05:38 +00:00
|
|
|
virtual void exception_sigh(Signal_context_capability) = 0;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return affinity space of CPU nodes available to the CPU session
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* The dimension of the affinity space as returned by this method
|
2015-03-04 20:12:14 +00:00
|
|
|
* represent the physical CPUs that are available.
|
|
|
|
*/
|
|
|
|
virtual Affinity::Space affinity_space() const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Translate generic priority value to kernel-specific priority levels
|
|
|
|
*
|
|
|
|
* \param pf_prio_limit maximum priority used for the kernel, must
|
|
|
|
* be power of 2
|
|
|
|
* \param prio generic priority value as used by the CPU
|
|
|
|
* session interface
|
|
|
|
* \param inverse order of platform priorities, if true
|
|
|
|
* 'pf_prio_limit' corresponds to the highest
|
|
|
|
* priority, otherwise it refers to the
|
|
|
|
* lowest priority.
|
|
|
|
* \return platform-specific priority value
|
|
|
|
*/
|
|
|
|
static unsigned scale_priority(unsigned pf_prio_limit, unsigned prio,
|
|
|
|
bool inverse = true)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Generic priority values are (0 is highest, 'PRIORITY_LIMIT'
|
|
|
|
* is lowest. On platforms where priority levels are defined
|
|
|
|
* the other way round, we have to invert the priority value.
|
|
|
|
*/
|
|
|
|
prio = inverse ? Cpu_session::PRIORITY_LIMIT - prio : prio;
|
|
|
|
|
|
|
|
/* scale value to platform priority range 0..pf_prio_limit */
|
|
|
|
return (prio*pf_prio_limit)/Cpu_session::PRIORITY_LIMIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Request trace control dataspace
|
|
|
|
*
|
|
|
|
* The trace-control dataspace is used to propagate tracing
|
|
|
|
* control information from core to the threads of a CPU session.
|
|
|
|
*
|
|
|
|
* The trace-control dataspace is accounted to the CPU session.
|
|
|
|
*/
|
|
|
|
virtual Dataspace_capability trace_control() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Define reference account for the CPU session
|
|
|
|
*
|
|
|
|
* \param cpu_session reference account
|
|
|
|
*
|
|
|
|
* \return 0 on success
|
|
|
|
*
|
|
|
|
* Each CPU session requires another CPU session as reference
|
|
|
|
* account to transfer quota to and from. The reference account can
|
|
|
|
* be defined only once.
|
|
|
|
*/
|
|
|
|
virtual int ref_account(Cpu_session_capability cpu_session) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Transfer quota to another CPU session
|
|
|
|
*
|
|
|
|
* \param cpu_session receiver of quota donation
|
2015-03-27 13:05:55 +00:00
|
|
|
* \param amount percentage of the session quota scaled up to
|
|
|
|
* the 'QUOTA_LIMIT' space
|
2015-03-04 20:12:14 +00:00
|
|
|
* \return 0 on success
|
|
|
|
*
|
|
|
|
* Quota can only be transfered if the specified CPU session is
|
|
|
|
* either the reference account for this session or vice versa.
|
|
|
|
*/
|
|
|
|
virtual int transfer_quota(Cpu_session_capability cpu_session,
|
|
|
|
size_t amount) = 0;
|
|
|
|
|
|
|
|
/**
|
2015-03-27 13:05:55 +00:00
|
|
|
* Return quota configuration of the session
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2015-03-27 13:05:55 +00:00
|
|
|
virtual Quota quota() = 0;
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-27 13:05:55 +00:00
|
|
|
* Scale up 'value' from its space with 'limit' to the 'QUOTA_LIMIT' space
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2015-03-27 13:05:55 +00:00
|
|
|
template<typename T = size_t>
|
|
|
|
static size_t quota_lim_upscale(size_t const value, size_t const limit) {
|
|
|
|
return ((T)value << Cpu_session::QUOTA_LIMIT_LOG2) / limit; }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
2015-03-27 13:05:55 +00:00
|
|
|
* Scale down 'value' from the 'QUOTA_LIMIT' space to a space with 'limit'
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
2015-03-27 13:05:55 +00:00
|
|
|
template<typename T = size_t>
|
|
|
|
static size_t quota_lim_downscale(size_t const value, size_t const limit) {
|
|
|
|
return ((T)value * limit) >> Cpu_session::QUOTA_LIMIT_LOG2; }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2016-03-30 13:34:37 +00:00
|
|
|
|
|
|
|
/*****************************************
|
|
|
|
** Access to kernel-specific interface **
|
|
|
|
*****************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Common base class of kernel-specific CPU interfaces
|
|
|
|
*/
|
2021-01-13 15:23:25 +00:00
|
|
|
struct Native_cpu;
|
2016-03-30 13:34:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return capability to kernel-specific CPU operations
|
|
|
|
*/
|
|
|
|
virtual Capability<Native_cpu> native_cpu() = 0;
|
|
|
|
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/*********************
|
|
|
|
** RPC declaration **
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
GENODE_RPC_THROW(Rpc_create_thread, Thread_capability, create_thread,
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 20:03:22 +00:00
|
|
|
GENODE_TYPE_LIST(Thread_creation_failed, Out_of_ram, Out_of_caps),
|
2016-05-04 10:27:17 +00:00
|
|
|
Capability<Pd_session>, Name const &, Affinity::Location,
|
|
|
|
Weight, addr_t);
|
2015-03-04 20:12:14 +00:00
|
|
|
GENODE_RPC(Rpc_kill_thread, void, kill_thread, Thread_capability);
|
2016-05-10 16:05:38 +00:00
|
|
|
GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability);
|
2015-03-04 20:12:14 +00:00
|
|
|
GENODE_RPC(Rpc_affinity_space, Affinity::Space, affinity_space);
|
|
|
|
GENODE_RPC(Rpc_trace_control, Dataspace_capability, trace_control);
|
|
|
|
GENODE_RPC(Rpc_ref_account, int, ref_account, Cpu_session_capability);
|
|
|
|
GENODE_RPC(Rpc_transfer_quota, int, transfer_quota, Cpu_session_capability, size_t);
|
2015-03-27 13:05:55 +00:00
|
|
|
GENODE_RPC(Rpc_quota, Quota, quota);
|
2016-03-30 13:34:37 +00:00
|
|
|
GENODE_RPC(Rpc_native_cpu, Capability<Native_cpu>, native_cpu);
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2016-05-11 15:23:51 +00:00
|
|
|
GENODE_RPC_INTERFACE(Rpc_create_thread, Rpc_kill_thread, Rpc_exception_sigh,
|
|
|
|
Rpc_affinity_space, Rpc_trace_control, Rpc_ref_account,
|
|
|
|
Rpc_transfer_quota, Rpc_quota, Rpc_native_cpu);
|
2015-03-27 13:05:55 +00:00
|
|
|
};
|
|
|
|
|
2016-05-10 16:05:38 +00:00
|
|
|
|
2015-03-27 13:05:55 +00:00
|
|
|
struct Genode::Cpu_session::Quota
|
|
|
|
{
|
|
|
|
size_t super_period_us;
|
|
|
|
size_t us;
|
2015-03-04 20:12:14 +00:00
|
|
|
};
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
#endif /* _INCLUDE__CPU_SESSION__CPU_SESSION_H_ */
|