genode/repos/base-hw/src/core/include/platform_thread.h

204 lines
4.9 KiB
C
Raw Normal View History

/*
* \brief Userland interface for the management of kernel thread-objects
* \author Martin Stein
* \author Stefan Kalkowski
* \date 2012-02-02
*/
/*
2013-01-10 21:44:47 +01:00
* Copyright (C) 2012-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 _CORE__INCLUDE__PLATFORM_THREAD_H_
#define _CORE__INCLUDE__PLATFORM_THREAD_H_
/* Genode includes */
#include <ram_session/ram_session.h>
#include <base/native_types.h>
#include <base/thread.h>
/* core includes */
#include <address_space.h>
#include <object.h>
#include <kernel/core_interface.h>
#include <kernel/thread.h>
#include <kernel/log.h>
namespace Genode {
class Pager_object;
class Thread_state;
class Rm_client;
class Platform_thread;
class Platform_pd;
/**
* Userland interface for the management of kernel thread-objects
*/
class Platform_thread : public Kernel_object<Kernel::Thread>
{
enum { LABEL_MAX_LEN = 32 };
Platform_pd * _pd;
Weak_ptr<Address_space> _address_space;
Pager_object * _pager;
Native_utcb * _utcb_core_addr; /* UTCB addr in core */
Native_utcb * _utcb_pd_addr; /* UTCB addr in pd */
Ram_dataspace_capability _utcb; /* UTCB dataspace */
char _label[LABEL_MAX_LEN];
/*
* Wether this thread is the main thread of a program.
* This should be used only after 'join_pd' was called
* or if this is a core thread. For core threads its save
* also without 'join_pd' because '_main_thread' is initialized
* with 0 wich is always true as cores main thread has no
* 'Platform_thread'.
*/
bool _main_thread;
Affinity::Location _location;
/**
* Common construction part
*/
void _init();
2012-10-09 15:41:40 +02:00
/*
* Check if this thread will attach its UTCB by itself
*/
bool _attaches_utcb_by_itself();
unsigned _priority(unsigned virt_prio)
{
return Cpu_session::scale_priority(Kernel::Cpu_priority::MAX,
virt_prio);
}
public:
/**
* Constructor for core threads
*
* \param label debugging label
* \param utcb virtual address of UTCB within core
*/
Platform_thread(const char * const label, Native_utcb * utcb);
/**
* Constructor for threads outside of core
*
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
* \param quota CPU quota that shall be granted to the thread
* \param label debugging label
* \param virt_prio unscaled processor-scheduling priority
* \param utcb core local pointer to userland stack
*/
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
Platform_thread(size_t const quota, const char * const label,
unsigned const virt_prio, addr_t const utcb);
2012-10-09 15:41:40 +02:00
/**
* Destructor
*/
~Platform_thread();
/**
* Join a protection domain
*
* \param pd platform pd object pointer
* \param main_thread wether thread is the first in protection domain
* \param address_space corresponding Genode address space
*
* \retval 0 succeeded
* \retval -1 failed
*/
int join_pd(Platform_pd * const pd, bool const main_thread,
Weak_ptr<Address_space> address_space);
/**
* Run this thread
*
* \param ip initial instruction pointer
* \param sp initial stack pointer
*/
int start(void * const ip, void * const sp);
/**
* Pause this thread
*/
void pause() { Kernel::pause_thread(kernel_object()); }
/**
* Resume this thread
*/
void resume() { Kernel::resume_thread(kernel_object()); }
/**
* Cancel currently blocking operation
*/
void cancel_blocking() { resume(); }
/**
* Set CPU quota of the thread to 'quota'
*/
void quota(size_t const quota);
/**
* Get raw thread state
*/
Thread_state state();
/**
* Override raw thread state
*/
void state(Thread_state s);
/**
* Return unique identification of this thread as faulter
*/
2015-02-06 17:23:41 +01:00
unsigned long pager_object_badge() { return (unsigned long)this; }
/**
* Set the executing CPU for this thread
*
* \param location targeted location in affinity space
*/
void affinity(Affinity::Location const & location);
/**
* Get the executing CPU for this thread
*/
Affinity::Location affinity() const;
/**
* Return the address space to which the thread is bound
*/
Weak_ptr<Address_space>& address_space();
/**
* Return execution time consumed by the thread
*/
unsigned long long execution_time() const { return 0; }
/***************
** Accessors **
***************/
char const * label() const { return _label; };
void pager(Pager_object * const pager);
Pager_object * pager();
Platform_pd * pd() const { return _pd; }
Ram_dataspace_capability utcb() const { return _utcb; }
};
}
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */