mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
base-hw: no PD code / virt methods in Ipc_node
This is a simplication of the asyncronous-IPC module of the base-hw kernel. Besides structuring the code in a cleaner way, it prepares for the in-place translation of the module into Ada in the context of the Spunky project. * Get rid of virtual methods in Ipc_node. * Move all stuff related to protection domains, capabilities, and UTCBs to the Thread class. this code might later be moved to a dedicated module, but for now it's just fine to have it done by the thread module. Ref #3308
This commit is contained in:
parent
4b3c40f35b
commit
6a5aa18a7b
@ -19,74 +19,16 @@
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_pd.h>
|
||||
#include <kernel/ipc_node.h>
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/thread.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
static inline void free_obj_id_ref(Pd &pd, void *ptr)
|
||||
{
|
||||
pd.platform_pd().capability_slab().free(ptr, sizeof(Object_identity_reference));
|
||||
}
|
||||
|
||||
|
||||
void Ipc_node::copy_msg(Ipc_node &sender)
|
||||
{
|
||||
using namespace Genode;
|
||||
using Reference = Object_identity_reference;
|
||||
|
||||
/* copy payload and set destination capability id */
|
||||
*_utcb = *sender._utcb;
|
||||
_utcb->destination(sender._capid);
|
||||
|
||||
/* translate capabilities */
|
||||
for (unsigned i = 0; i < _rcv_caps; i++) {
|
||||
|
||||
capid_t id = sender._utcb->cap_get(i);
|
||||
|
||||
/* if there is no capability to send, just free the pre-allocation */
|
||||
if (i >= sender._utcb->cap_cnt()) {
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup the capability id within the caller's cap space */
|
||||
Reference *oir = (id == cap_id_invalid())
|
||||
? nullptr : sender.pd().cap_tree().find(id);
|
||||
|
||||
/* if the caller's capability is invalid, free the pre-allocation */
|
||||
if (!oir) {
|
||||
_utcb->cap_add(cap_id_invalid());
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup the capability id within the callee's cap space */
|
||||
Reference *dst_oir = oir->find(pd());
|
||||
|
||||
/* if it is not found, and the target is not core, create a reference */
|
||||
if (!dst_oir && (&pd() != &core_pd())) {
|
||||
dst_oir = oir->factory(_obj_id_ref_ptr[i], pd());
|
||||
if (!dst_oir)
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
} else /* otherwise free the pre-allocation */
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
|
||||
if (dst_oir) dst_oir->add_to_utcb();
|
||||
|
||||
/* add the translated capability id to the target buffer */
|
||||
_utcb->cap_add(dst_oir ? dst_oir->capid() : cap_id_invalid());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ipc_node::_receive_request(Ipc_node &caller)
|
||||
{
|
||||
copy_msg(caller);
|
||||
_thread.ipc_copy_msg(caller._thread);
|
||||
_caller = &caller;
|
||||
_state = INACTIVE;
|
||||
}
|
||||
@ -94,9 +36,9 @@ void Ipc_node::_receive_request(Ipc_node &caller)
|
||||
|
||||
void Ipc_node::_receive_reply(Ipc_node &callee)
|
||||
{
|
||||
copy_msg(callee);
|
||||
_thread.ipc_copy_msg(callee._thread);
|
||||
_state = INACTIVE;
|
||||
_send_request_succeeded();
|
||||
_thread.ipc_send_request_succeeded();
|
||||
}
|
||||
|
||||
|
||||
@ -105,7 +47,7 @@ void Ipc_node::_announce_request(Ipc_node &node)
|
||||
/* directly receive request if we've awaited it */
|
||||
if (_state == AWAIT_REQUEST) {
|
||||
_receive_request(node);
|
||||
_await_request_succeeded();
|
||||
_thread.ipc_await_request_succeeded();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -152,40 +94,24 @@ void Ipc_node::_outbuf_request_cancelled()
|
||||
|
||||
_callee = nullptr;
|
||||
_state = INACTIVE;
|
||||
_send_request_failed();
|
||||
_thread.ipc_send_request_failed();
|
||||
}
|
||||
|
||||
|
||||
bool Ipc_node::_helps_outbuf_dst() { return (_state == AWAIT_REPLY) && _help; }
|
||||
|
||||
|
||||
void Ipc_node::_init(Genode::Native_utcb &utcb, Ipc_node &starter)
|
||||
bool Ipc_node::can_send_request()
|
||||
{
|
||||
_utcb = &utcb;
|
||||
_rcv_caps = starter._utcb->cap_cnt();
|
||||
Genode::Allocator &slab = pd().platform_pd().capability_slab();
|
||||
for (unsigned i = 0; i < _rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
copy_msg(starter);
|
||||
return _state == INACTIVE;
|
||||
}
|
||||
|
||||
|
||||
void Ipc_node::send_request(Ipc_node &callee, capid_t capid, bool help,
|
||||
unsigned rcv_caps)
|
||||
void Ipc_node::send_request(Ipc_node &callee, bool help)
|
||||
{
|
||||
if (_state != INACTIVE) {
|
||||
Genode::raw("IPC send request: bad state");
|
||||
return;
|
||||
}
|
||||
Genode::Allocator &slab = pd().platform_pd().capability_slab();
|
||||
for (unsigned i = 0; i < rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
|
||||
_state = AWAIT_REPLY;
|
||||
_callee = &callee;
|
||||
_capid = capid;
|
||||
_help = false;
|
||||
_rcv_caps = rcv_caps;
|
||||
|
||||
/* announce request */
|
||||
_callee->_announce_request(*this);
|
||||
@ -198,18 +124,14 @@ Ipc_node * Ipc_node::helping_sink() {
|
||||
return _helps_outbuf_dst() ? _callee->helping_sink() : this; }
|
||||
|
||||
|
||||
bool Ipc_node::await_request(unsigned rcv_caps)
|
||||
bool Ipc_node::can_await_request()
|
||||
{
|
||||
if (_state != INACTIVE) {
|
||||
Genode::raw("IPC await request: bad state");
|
||||
return true;
|
||||
}
|
||||
Genode::Allocator &slab = pd().platform_pd().capability_slab();
|
||||
for (unsigned i = 0; i < rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
return _state == INACTIVE;
|
||||
}
|
||||
|
||||
_rcv_caps = rcv_caps;
|
||||
|
||||
bool Ipc_node::await_request()
|
||||
{
|
||||
/* if no request announced then wait */
|
||||
bool announced = false;
|
||||
_state = AWAIT_REQUEST;
|
||||
@ -239,11 +161,11 @@ void Ipc_node::cancel_waiting()
|
||||
case AWAIT_REPLY:
|
||||
_cancel_outbuf_request();
|
||||
_state = INACTIVE;
|
||||
_send_request_failed();
|
||||
_thread.ipc_send_request_failed();
|
||||
break;
|
||||
case AWAIT_REQUEST:
|
||||
_state = INACTIVE;
|
||||
_await_request_failed();
|
||||
_thread.ipc_await_request_failed();
|
||||
break;
|
||||
return;
|
||||
default: return;
|
||||
@ -251,6 +173,12 @@ void Ipc_node::cancel_waiting()
|
||||
}
|
||||
|
||||
|
||||
Ipc_node::Ipc_node(Thread &thread)
|
||||
:
|
||||
_thread(thread)
|
||||
{ }
|
||||
|
||||
|
||||
Ipc_node::~Ipc_node()
|
||||
{
|
||||
_cancel_request_queue();
|
||||
|
@ -15,18 +15,14 @@
|
||||
#ifndef _CORE__KERNEL__IPC_NODE_H_
|
||||
#define _CORE__KERNEL__IPC_NODE_H_
|
||||
|
||||
/* base-local includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/interface.h>
|
||||
#include <assertion.h>
|
||||
/* Genode includes */
|
||||
#include <util/fifo.h>
|
||||
|
||||
namespace Genode { class Msgbuf_base; };
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
class Pd;
|
||||
class Thread;
|
||||
|
||||
/**
|
||||
* Backend for end points of synchronous interprocess communication
|
||||
@ -47,27 +43,19 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||
AWAIT_REQUEST = 3,
|
||||
};
|
||||
|
||||
void _init(Genode::Native_utcb &utcb, Ipc_node &callee);
|
||||
|
||||
private:
|
||||
|
||||
friend class Core_thread;
|
||||
friend class Genode::Fifo<Ipc_node>;
|
||||
|
||||
State _state = INACTIVE;
|
||||
capid_t _capid = cap_id_invalid();
|
||||
Ipc_node * _caller = nullptr;
|
||||
Ipc_node * _callee = nullptr;
|
||||
bool _help = false;
|
||||
size_t _rcv_caps = 0; /* max capability num to receive */
|
||||
Genode::Native_utcb * _utcb = nullptr;
|
||||
Thread &_thread;
|
||||
State _state { INACTIVE };
|
||||
Ipc_node * _caller { nullptr };
|
||||
Ipc_node * _callee { nullptr };
|
||||
bool _help { false };
|
||||
Ipc_node_queue _request_queue { };
|
||||
|
||||
/* pre-allocation array for obkject identity references */
|
||||
void * _obj_id_ref_ptr[Genode::Msgbuf_base::MAX_CAPS_PER_MSG];
|
||||
|
||||
inline void copy_msg(Ipc_node &sender);
|
||||
|
||||
/**
|
||||
* Buffer next request from request queue in 'r' to handle it
|
||||
*/
|
||||
@ -114,40 +102,26 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||
bool _helps_outbuf_dst();
|
||||
|
||||
/**
|
||||
* IPC node returned from waiting due to reply receipt
|
||||
* Make the class noncopyable because it has pointer members
|
||||
*/
|
||||
virtual void _send_request_succeeded() = 0;
|
||||
Ipc_node(const Ipc_node&) = delete;
|
||||
|
||||
/**
|
||||
* IPC node returned from waiting due to reply cancellation
|
||||
* Make the class noncopyable because it has pointer members
|
||||
*/
|
||||
virtual void _send_request_failed() = 0;
|
||||
|
||||
/**
|
||||
* IPC node returned from waiting due to request receipt
|
||||
*/
|
||||
virtual void _await_request_succeeded() = 0;
|
||||
|
||||
/**
|
||||
* IPC node returned from waiting due to request cancellation
|
||||
*/
|
||||
virtual void _await_request_failed() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
Pd * _pd = nullptr; /* pointer to PD this IPC node is part of */
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Ipc_node * callee() { return _callee; }
|
||||
State state() { return _state; }
|
||||
const Ipc_node& operator=(const Ipc_node&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Ipc_node();
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Ipc_node();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Ipc_node(Thread &thread);
|
||||
|
||||
/**
|
||||
* Send a request and wait for the according reply
|
||||
@ -155,8 +129,8 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||
* \param callee targeted IPC node
|
||||
* \param help wether the request implies a helping relationship
|
||||
*/
|
||||
void send_request(Ipc_node &callee, capid_t capid, bool help,
|
||||
unsigned rcv_caps);
|
||||
bool can_send_request();
|
||||
void send_request(Ipc_node &callee, bool help);
|
||||
|
||||
/**
|
||||
* Return root destination of the helping-relation tree we are in
|
||||
@ -181,7 +155,8 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||
*
|
||||
* \return wether a request could be received already
|
||||
*/
|
||||
bool await_request(unsigned rcv_caps);
|
||||
bool can_await_request();
|
||||
bool await_request();
|
||||
|
||||
/**
|
||||
* Reply to last request if there's any
|
||||
@ -198,15 +173,9 @@ class Kernel::Ipc_node : private Ipc_node_queue::Element
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Pd &pd() const
|
||||
{
|
||||
if (_pd)
|
||||
return *_pd;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
|
||||
Genode::Native_utcb *utcb() { return _utcb; }
|
||||
Ipc_node * callee() { return _callee; }
|
||||
State state() { return _state; }
|
||||
Thread &thread() { return _thread; }
|
||||
};
|
||||
|
||||
#endif /* _CORE__KERNEL__IPC_NODE_H_ */
|
||||
|
@ -35,6 +35,72 @@ extern "C" void _core_start(void);
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
static inline void free_obj_id_ref(Pd &pd, void *ptr)
|
||||
{
|
||||
pd.platform_pd().capability_slab().free(ptr, sizeof(Object_identity_reference));
|
||||
}
|
||||
|
||||
|
||||
void Thread::_ipc_init(Genode::Native_utcb &utcb, Thread &starter)
|
||||
{
|
||||
_utcb = &utcb;
|
||||
_ipc_rcv_caps = starter._utcb->cap_cnt();
|
||||
Genode::Allocator &slab = pd().platform_pd().capability_slab();
|
||||
for (unsigned i = 0; i < _ipc_rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
ipc_copy_msg(starter);
|
||||
}
|
||||
|
||||
|
||||
void Thread::ipc_copy_msg(Thread &sender)
|
||||
{
|
||||
using namespace Genode;
|
||||
using Reference = Object_identity_reference;
|
||||
|
||||
/* copy payload and set destination capability id */
|
||||
*_utcb = *sender._utcb;
|
||||
_utcb->destination(sender._ipc_capid);
|
||||
|
||||
/* translate capabilities */
|
||||
for (unsigned i = 0; i < _ipc_rcv_caps; i++) {
|
||||
|
||||
capid_t id = sender._utcb->cap_get(i);
|
||||
|
||||
/* if there is no capability to send, just free the pre-allocation */
|
||||
if (i >= sender._utcb->cap_cnt()) {
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup the capability id within the caller's cap space */
|
||||
Reference *oir = (id == cap_id_invalid())
|
||||
? nullptr : sender.pd().cap_tree().find(id);
|
||||
|
||||
/* if the caller's capability is invalid, free the pre-allocation */
|
||||
if (!oir) {
|
||||
_utcb->cap_add(cap_id_invalid());
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* lookup the capability id within the callee's cap space */
|
||||
Reference *dst_oir = oir->find(pd());
|
||||
|
||||
/* if it is not found, and the target is not core, create a reference */
|
||||
if (!dst_oir && (&pd() != &core_pd())) {
|
||||
dst_oir = oir->factory(_obj_id_ref_ptr[i], pd());
|
||||
if (!dst_oir)
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
} else /* otherwise free the pre-allocation */
|
||||
free_obj_id_ref(pd(), _obj_id_ref_ptr[i]);
|
||||
|
||||
if (dst_oir) dst_oir->add_to_utcb();
|
||||
|
||||
/* add the translated capability id to the target buffer */
|
||||
_utcb->cap_add(dst_oir ? dst_oir->capid() : cap_id_invalid());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Thread::Tlb_invalidation::Tlb_invalidation(Thread & caller, Pd & pd,
|
||||
addr_t addr, size_t size,
|
||||
@ -114,7 +180,7 @@ void Thread::_receive_signal(void * const base, size_t const size)
|
||||
}
|
||||
|
||||
|
||||
void Thread::_send_request_succeeded()
|
||||
void Thread::ipc_send_request_succeeded()
|
||||
{
|
||||
assert(_state == AWAITS_IPC);
|
||||
user_arg_0(0);
|
||||
@ -123,7 +189,7 @@ void Thread::_send_request_succeeded()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_send_request_failed()
|
||||
void Thread::ipc_send_request_failed()
|
||||
{
|
||||
assert(_state == AWAITS_IPC);
|
||||
user_arg_0(-1);
|
||||
@ -132,7 +198,7 @@ void Thread::_send_request_failed()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_await_request_succeeded()
|
||||
void Thread::ipc_await_request_succeeded()
|
||||
{
|
||||
assert(_state == AWAITS_IPC);
|
||||
user_arg_0(0);
|
||||
@ -140,7 +206,7 @@ void Thread::_await_request_succeeded()
|
||||
}
|
||||
|
||||
|
||||
void Thread::_await_request_failed()
|
||||
void Thread::ipc_await_request_failed()
|
||||
{
|
||||
assert(_state == AWAITS_IPC);
|
||||
user_arg_0(-1);
|
||||
@ -151,15 +217,15 @@ void Thread::_await_request_failed()
|
||||
void Thread::_deactivate_used_shares()
|
||||
{
|
||||
Cpu_job::_deactivate_own_share();
|
||||
Ipc_node::for_each_helper([&] (Ipc_node &h) {
|
||||
static_cast<Thread &>(h)._deactivate_used_shares(); });
|
||||
_ipc_node.for_each_helper([&] (Ipc_node &ipc_node) {
|
||||
ipc_node.thread()._deactivate_used_shares(); });
|
||||
}
|
||||
|
||||
void Thread::_activate_used_shares()
|
||||
{
|
||||
Cpu_job::_activate_own_share();
|
||||
Ipc_node::for_each_helper([&] (Ipc_node &h) {
|
||||
static_cast<Thread &>(h)._activate_used_shares(); });
|
||||
_ipc_node.for_each_helper([&] (Ipc_node &ipc_node) {
|
||||
ipc_node.thread()._activate_used_shares(); });
|
||||
}
|
||||
|
||||
void Thread::_become_active()
|
||||
@ -180,7 +246,7 @@ void Thread::_die() { _become_inactive(DEAD); }
|
||||
|
||||
|
||||
Cpu_job * Thread::helping_sink() {
|
||||
return static_cast<Thread *>(Ipc_node::helping_sink()); }
|
||||
return &_ipc_node.helping_sink()->thread(); }
|
||||
|
||||
|
||||
size_t Thread::_core_to_kernel_quota(size_t const quota) const
|
||||
@ -212,7 +278,7 @@ void Thread::_call_start_thread()
|
||||
|
||||
/* join protection domain */
|
||||
thread._pd = (Pd *) user_arg_3();
|
||||
thread.Ipc_node::_init(*(Native_utcb *)user_arg_4(), *this);
|
||||
thread._ipc_init(*(Native_utcb *)user_arg_4(), *this);
|
||||
thread._become_active();
|
||||
}
|
||||
|
||||
@ -285,7 +351,7 @@ void Thread::_cancel_blocking()
|
||||
_become_active();
|
||||
return;
|
||||
case AWAITS_IPC:
|
||||
Ipc_node::cancel_waiting();
|
||||
_ipc_node.cancel_waiting();
|
||||
return;
|
||||
case AWAITS_SIGNAL:
|
||||
Signal_handler::cancel_waiting();
|
||||
@ -339,7 +405,18 @@ void Thread::_call_delete_thread()
|
||||
|
||||
void Thread::_call_await_request_msg()
|
||||
{
|
||||
if (Ipc_node::await_request(user_arg_1())) {
|
||||
if (!_ipc_node.can_await_request()) {
|
||||
Genode::raw("IPC await request: bad state");
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
unsigned const rcv_caps = user_arg_1();
|
||||
Genode::Allocator &slab = pd().platform_pd().capability_slab();
|
||||
for (unsigned i = 0; i < rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
|
||||
_ipc_rcv_caps = rcv_caps;
|
||||
if (_ipc_node.await_request()) {
|
||||
user_arg_0(0);
|
||||
return;
|
||||
}
|
||||
@ -390,8 +467,19 @@ void Thread::_call_send_request_msg()
|
||||
bool const help = Cpu_job::_helping_possible(*dst);
|
||||
oir = oir->find(dst->pd());
|
||||
|
||||
Ipc_node::send_request(*dst, oir ? oir->capid() : cap_id_invalid(),
|
||||
help, user_arg_2());
|
||||
if (!_ipc_node.can_send_request()) {
|
||||
Genode::raw("IPC send request: bad state");
|
||||
} else {
|
||||
unsigned const rcv_caps = user_arg_2();
|
||||
Genode::Allocator &slab = pd().platform_pd().capability_slab();
|
||||
for (unsigned i = 0; i < rcv_caps; i++)
|
||||
_obj_id_ref_ptr[i] = slab.alloc(sizeof(Object_identity_reference));
|
||||
|
||||
_ipc_capid = oir ? oir->capid() : cap_id_invalid();
|
||||
_ipc_rcv_caps = rcv_caps;
|
||||
_ipc_node.send_request(dst->_ipc_node, help);
|
||||
}
|
||||
|
||||
_state = AWAITS_IPC;
|
||||
if (!help || !dst->own_share_active()) { _deactivate_used_shares(); }
|
||||
}
|
||||
@ -399,7 +487,7 @@ void Thread::_call_send_request_msg()
|
||||
|
||||
void Thread::_call_send_reply_msg()
|
||||
{
|
||||
Ipc_node::send_reply();
|
||||
_ipc_node.send_reply();
|
||||
bool const await_request_msg = user_arg_2();
|
||||
if (await_request_msg) { _call_await_request_msg(); }
|
||||
else { user_arg_0(0); }
|
||||
@ -730,7 +818,7 @@ void Thread::_mmu_exception()
|
||||
Thread::Thread(unsigned const priority, unsigned const quota,
|
||||
char const * const label, bool core)
|
||||
:
|
||||
Cpu_job(priority, quota), _state(AWAITS_START),
|
||||
Cpu_job(priority, quota), _ipc_node(*this), _state(AWAITS_START),
|
||||
_signal_receiver(0), _label(label), _core(core), regs(core) { }
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
#ifndef _CORE__KERNEL__THREAD_H_
|
||||
#define _CORE__KERNEL__THREAD_H_
|
||||
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/signal.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
@ -24,6 +26,12 @@
|
||||
#include <kernel/signal_receiver.h>
|
||||
#include <kernel/ipc_node.h>
|
||||
#include <object.h>
|
||||
#include <kernel/interface.h>
|
||||
#include <assertion.h>
|
||||
|
||||
/* base-local includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@ -50,9 +58,8 @@ struct Kernel::Thread_fault
|
||||
*/
|
||||
class Kernel::Thread
|
||||
:
|
||||
public Kernel::Object, public Cpu_job,
|
||||
public Ipc_node, public Signal_context_killer, public Signal_handler,
|
||||
private Timeout
|
||||
public Kernel::Object, public Cpu_job, public Signal_context_killer,
|
||||
public Signal_handler, private Timeout
|
||||
{
|
||||
private:
|
||||
|
||||
@ -121,15 +128,21 @@ class Kernel::Thread
|
||||
DEAD = 7,
|
||||
};
|
||||
|
||||
Signal_context * _pager = nullptr;
|
||||
Thread_fault _fault { };
|
||||
State _state;
|
||||
Signal_receiver * _signal_receiver;
|
||||
char const * const _label;
|
||||
capid_t _timeout_sigid = 0;
|
||||
bool _paused = false;
|
||||
bool _cancel_next_await_signal = false;
|
||||
bool const _core = false;
|
||||
void *_obj_id_ref_ptr[Genode::Msgbuf_base::MAX_CAPS_PER_MSG];
|
||||
Ipc_node _ipc_node;
|
||||
capid_t _ipc_capid { cap_id_invalid() };
|
||||
size_t _ipc_rcv_caps { 0 };
|
||||
Genode::Native_utcb *_utcb { nullptr };
|
||||
Pd *_pd { nullptr };
|
||||
Signal_context *_pager { nullptr };
|
||||
Thread_fault _fault { };
|
||||
State _state;
|
||||
Signal_receiver *_signal_receiver;
|
||||
char const *const _label;
|
||||
capid_t _timeout_sigid { 0 };
|
||||
bool _paused { false };
|
||||
bool _cancel_next_await_signal { false };
|
||||
bool const _core { false };
|
||||
|
||||
Genode::Constructible<Tlb_invalidation> _tlb_invalidation {};
|
||||
Genode::Constructible<Destroy> _destroy {};
|
||||
@ -258,6 +271,8 @@ class Kernel::Thread
|
||||
kobj.destruct();
|
||||
}
|
||||
|
||||
void _ipc_init(Genode::Native_utcb &utcb, Thread &callee);
|
||||
|
||||
|
||||
/***************************
|
||||
** Signal_context_killer **
|
||||
@ -276,15 +291,6 @@ class Kernel::Thread
|
||||
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:
|
||||
|
||||
Genode::Align_at<Genode::Cpu::Context> regs;
|
||||
@ -373,6 +379,16 @@ class Kernel::Thread
|
||||
|
||||
void print(Genode::Output &out) const;
|
||||
|
||||
/**************
|
||||
** Ipc_node **
|
||||
**************/
|
||||
|
||||
void ipc_send_request_succeeded() ;
|
||||
void ipc_send_request_failed() ;
|
||||
void ipc_await_request_succeeded();
|
||||
void ipc_await_request_failed() ;
|
||||
void ipc_copy_msg(Thread &sender) ;
|
||||
|
||||
|
||||
/*************
|
||||
** Cpu_job **
|
||||
@ -396,6 +412,15 @@ class Kernel::Thread
|
||||
|
||||
char const * label() const { return _label; }
|
||||
Thread_fault fault() const { return _fault; }
|
||||
Genode::Native_utcb *utcb() { return _utcb; }
|
||||
|
||||
Pd &pd() const
|
||||
{
|
||||
if (_pd)
|
||||
return *_pd;
|
||||
|
||||
ASSERT_NEVER_CALLED;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user