genode/repos/base-hw/src/core/kernel/thread.h

401 lines
9.6 KiB
C
Raw Normal View History

/*
* \brief Kernel backend for execution contexts in userland
* \author Martin Stein
* \date 2012-11-30
*/
/*
* Copyright (C) 2012-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__KERNEL__THREAD_H_
#define _CORE__KERNEL__THREAD_H_
#include <base/signal.h>
#include <util/reconstructible.h>
/* core includes */
2017-10-06 12:02:36 +02:00
#include <cpu.h>
#include <kernel/cpu_context.h>
#include <kernel/inter_processor_work.h>
#include <kernel/signal_receiver.h>
#include <kernel/ipc_node.h>
#include <kernel/object.h>
namespace Kernel
{
struct Thread_fault;
class Thread;
class Core_thread;
}
struct Kernel::Thread_fault
{
enum Type { WRITE, EXEC, PAGE_MISSING, UNKNOWN };
addr_t ip = 0;
addr_t addr = 0;
Type type = UNKNOWN;
void print(Genode::Output &out) const;
};
/**
* Kernel back-end for userland execution-contexts
*/
class Kernel::Thread
:
public Kernel::Object, public Cpu_job,
public Ipc_node, public Signal_context_killer, public Signal_handler,
private Timeout
{
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
private:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
/**
* An update of page-table entries that requires architecture-wise
* maintainance operations, e.g., a TLB invalidation needs
* cross-cpu synchronization
*/
struct Pd_update : Inter_processor_work
{
Thread & caller; /* the caller gets blocked until all finished */
Pd & pd; /* the corresponding pd */
unsigned cnt; /* count of cpus left */
Pd_update(Thread & caller, Pd & pd, unsigned cnt);
/************************************
** Inter_processor_work interface **
************************************/
void execute() override;
};
/**
* The destruction of a thread still active on another cpu
* needs cross-cpu synchronization
*/
struct Destroy : Inter_processor_work
{
Thread & caller; /* the caller gets blocked till the end */
Thread & thread_to_destroy; /* thread to be destroyed */
Destroy(Thread & caller, Thread & to_destroy);
/************************************
** Inter_processor_work interface **
************************************/
void execute() override;
};
friend void Pd_update::execute();
friend void Destroy::execute();
2017-10-06 12:02:36 +02:00
protected:
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
enum { START_VERBOSE = 0 };
enum State
{
ACTIVE = 1,
AWAITS_START = 2,
AWAITS_IPC = 3,
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
AWAITS_RESTART = 4,
AWAITS_SIGNAL = 5,
AWAITS_SIGNAL_CONTEXT_KILL = 6,
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
DEAD = 7,
};
Signal_context * _pager = nullptr;
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Thread_fault _fault { };
State _state;
Signal_receiver * _signal_receiver;
char const * const _label;
capid_t _timeout_sigid = 0;
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
bool _paused = false;
bool _cancel_next_await_signal = false;
bool const _core = false;
Genode::Constructible<Pd_update> _pd_update {};
Genode::Constructible<Destroy> _destroy {};
/**
* Notice that another thread yielded the CPU to this thread
*/
void _receive_yielded_cpu();
2013-09-12 00:48:27 +02:00
/**
* Attach or detach the handler of a thread-triggered event
*
* \param event_id kernel name of the thread event
* \param signal_context_id kernel name signal context or 0 to detach
*
* \retval 0 succeeded
* \retval -1 failed
*/
int _route_event(unsigned const event_id,
Signal_context * const signal_context_id);
/**
* Switch from an inactive state to the active state
*/
void _become_active();
/**
* Switch from the active state to the inactive state 's'
*/
void _become_inactive(State const s);
/**
* Activate our CPU-share and those of our helpers
*/
void _activate_used_shares();
/**
* Deactivate our CPU-share and those of our helpers
*/
void _deactivate_used_shares();
/**
* Suspend unrecoverably from execution
*/
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
void _die();
/**
* Handle an exception thrown by the memory management unit
*/
void _mmu_exception();
/**
* Handle kernel-call request of the thread
*/
void _call();
/**
* Return amount of timer ticks that 'quota' is worth
*/
size_t _core_to_kernel_quota(size_t const quota) const;
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
void _cancel_blocking();
bool _restart();
/*********************************************************
** Kernel-call back-ends, see kernel-interface headers **
*********************************************************/
void _call_new_thread();
void _call_new_core_thread();
void _call_thread_quota();
void _call_start_thread();
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
void _call_stop_thread();
void _call_pause_thread();
void _call_resume_thread();
hw: clean up scheduling-readiness syscalls This cleans up the syscalls that are mainly used to control the scheduling readiness of a thread. The different use cases and requirements were somehow mixed together in the previous interface. The new syscall set is: 1) pause_thread and resume_thread They don't affect the state of the thread (IPC, signalling, etc.) but merely decide wether the thread is allowed for scheduling or not, the so-called pause state. The pause state is orthogonal to the thread state and masks it when it comes to scheduling. In contrast to the stopped state, which is described in "stop_thread and restart_thread", the thread state and the UTCB content of a thread may change while in the paused state. However, the register state of a thread doesn't change while paused. The "pause" and "resume" syscalls are both core-restricted and may target any thread. They are used as back end for the CPU session calls "pause" and "resume". The "pause/resume" feature is made for applications like the GDB monitor that transparently want to stop and continue the execution of a thread no matter what state the thread is in. 2) stop_thread and restart_thread The stop syscall can only be used on a thread in the non-blocking ("active") thread state. The thread then switches to the "stopped" thread state in wich it explicitely waits for a restart. The restart syscall can only be used on a thread in the "stopped" or the "active" thread state. The thread then switches back to the "active" thread state and the syscall returns whether the thread was stopped. Both syscalls are not core-restricted. "Stop" always targets the calling thread while "restart" may target any thread in the same PD as the caller. Thread state and UTCB content of a thread don't change while in the stopped state. The "stop/restart" feature is used when an active thread wants to wait for an event that is not known to the kernel. Actually the syscalls are used when waiting for locks and on thread exit. 3) cancel_thread_blocking Does cleanly cancel a cancelable blocking thread state (IPC, signalling, stopped). The thread whose blocking was cancelled goes back to the "active" thread state. It may receive a syscall return value that reflects the cancellation. This syscall doesn't affect the pause state of the thread which means that it may still not get scheduled. The syscall is core-restricted and may target any thread. 4) yield_thread Does its best that a thread is scheduled as few as possible in the current scheduling super-period without touching the thread or pause state. In the next superperiod, however, the thread is scheduled "normal" again. The syscall is not core-restricted and always targets the caller. Fixes #2104
2016-09-15 17:23:06 +02:00
void _call_cancel_thread_blocking();
void _call_restart_thread();
void _call_yield_thread();
void _call_delete_thread();
void _call_await_request_msg();
void _call_send_request_msg();
void _call_send_reply_msg();
void _call_update_pd();
void _call_update_data_region();
void _call_update_instr_region();
void _call_print_char();
void _call_await_signal();
void _call_cancel_next_await_signal();
void _call_submit_signal();
void _call_ack_signal();
void _call_kill_signal_context();
void _call_new_vm();
void _call_delete_vm();
void _call_run_vm();
void _call_pause_vm();
void _call_pager();
void _call_new_irq();
void _call_ack_irq();
void _call_new_obj();
void _call_delete_obj();
void _call_ack_cap();
void _call_delete_cap();
void _call_timeout();
void _call_timeout_age_us();
void _call_timeout_max_us();
template <typename T, typename... ARGS>
void _call_new(ARGS &&... args)
{
using Object = Core_object<T>;
void * dst = (void *)user_arg_1();
Object * o = Genode::construct_at<Object>(dst, args...);
user_arg_0(o->core_capid());
}
template <typename T>
void _call_delete()
{
using Object = Core_object<T>;
reinterpret_cast<Object*>(user_arg_1())->~Object();
}
/***************************
** Signal_context_killer **
***************************/
void _signal_context_kill_pending() override;
void _signal_context_kill_failed() override;
void _signal_context_kill_done() override;
/********************
** Signal_handler **
********************/
void _await_signal(Signal_receiver * const receiver) override;
void _receive_signal(void * const base, size_t const size) override;
/**************
** Ipc_node **
**************/
void _send_request_succeeded() override;
void _send_request_failed() override;
void _await_request_succeeded() override;
void _await_request_failed() override;
public:
2017-10-06 12:02:36 +02:00
Genode::Align_at<Genode::Cpu::Context> regs;
/**
* Constructor
*
* \param priority scheduling priority
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-time quota
* \param label debugging label
* \param core whether it is a core thread or not
*/
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(unsigned const priority, unsigned const quota,
char const * const label, bool core = false);
/**
* Constructor for core/kernel thread
*
* \param label debugging label
*/
Thread(char const * const label)
: Thread(Cpu_priority::MIN, 0, label, true) { }
2017-10-06 12:02:36 +02:00
/**************************
** Support for syscalls **
**************************/
void user_arg_0(Kernel::Call_arg const arg);
void user_arg_1(Kernel::Call_arg const arg);
void user_arg_2(Kernel::Call_arg const arg);
void user_arg_3(Kernel::Call_arg const arg);
void user_arg_4(Kernel::Call_arg const arg);
Kernel::Call_arg user_arg_0() const;
Kernel::Call_arg user_arg_1() const;
Kernel::Call_arg user_arg_2() const;
Kernel::Call_arg user_arg_3() const;
Kernel::Call_arg user_arg_4() const;
/**
* Syscall to create a thread
*
* \param p memory donation for the new kernel thread object
* \param priority scheduling priority of the new thread
* \param quota CPU quota of the new thread
* \param label debugging label of the new thread
*
* \retval capability id of the new kernel object
*/
static capid_t syscall_create(void * const p, unsigned const priority,
size_t const quota,
char const * const label)
{
return call(call_id_new_thread(), (Call_arg)p, (Call_arg)priority,
(Call_arg)quota, (Call_arg)label);
}
/**
* Syscall to create a core thread
*
* \param p memory donation for the new kernel thread object
* \param label debugging label of the new thread
*
* \retval capability id of the new kernel object
*/
static capid_t syscall_create(void * const p, char const * const label)
{
return call(call_id_new_core_thread(), (Call_arg)p,
(Call_arg)label);
}
/**
* Syscall to destroy a thread
*
* \param thread pointer to thread kernel object
*/
static void syscall_destroy(Thread * thread) {
call(call_id_delete_thread(), (Call_arg)thread); }
void print(Genode::Output &out) const;
/*************
** Cpu_job **
*************/
void exception(Cpu & cpu) override;
void proceed(Cpu & cpu) override;
Cpu_job * helping_sink() override;
/*************
** Timeout **
*************/
void timeout_triggered() override;
/***************
** Accessors **
***************/
char const * label() const { return _label; }
Thread_fault fault() const { return _fault; }
};
/**
* The first core thread in the system bootstrapped by the Kernel
*/
2017-10-06 12:02:36 +02:00
struct Kernel::Core_thread : Core_object<Kernel::Thread>
{
2017-10-06 12:02:36 +02:00
Core_thread();
2017-10-06 12:02:36 +02:00
static Thread & singleton();
};
#endif /* _CORE__KERNEL__THREAD_H_ */