base-hw: do not inherit Kernel::Object

This prevents the use of Kernel::Object as base class for the specific kernel
objects and instead makes it a member of the kernel objects. Besides
simplifying inheritance hierarchies in base-hw, this prepares for the in-place
translation of the signaling module (and others) to Ada in the context of the
Spunky project.

Ref #3308
This commit is contained in:
Martin Stein 2019-04-29 23:37:39 +02:00 committed by Christian Helmuth
parent 88043e144a
commit 5e460394d2
8 changed files with 161 additions and 26 deletions

View File

@ -119,10 +119,11 @@ class Kernel::Irq : Genode::Avl_node<Irq>
};
class Kernel::User_irq : public Kernel::Irq, public Kernel::Object
class Kernel::User_irq : public Kernel::Irq
{
private:
Kernel::Object _kernel_object { *this };
Signal_context &_context;
/**
@ -186,6 +187,8 @@ class Kernel::User_irq : public Kernel::Irq, public Kernel::Object
*/
static void syscall_destroy(Genode::Kernel_object<User_irq> &irq) {
call(call_id_delete_irq(), (Call_arg) &irq); }
Object &kernel_object() { return _kernel_object; }
};
#endif /* _CORE__KERNEL__IRQ_H_ */

View File

@ -11,12 +11,99 @@ using namespace Kernel;
** Object **
************/
Object::Object(Thread &obj)
:
_type { THREAD },
_obj { (void *)&obj }
{ }
Object::Object(Irq &obj)
:
_type { IRQ },
_obj { (void *)&obj }
{ }
Object::Object(Signal_receiver &obj)
:
_type { SIGNAL_RECEIVER },
_obj { (void *)&obj }
{ }
Object::Object(Signal_context &obj)
:
_type { SIGNAL_CONTEXT },
_obj { (void *)&obj }
{ }
Object::Object(Pd &obj)
:
_type { PD },
_obj { (void *)&obj }
{ }
Object::Object(Vm &obj)
:
_type { VM },
_obj { (void *)&obj }
{ }
Object::~Object()
{
for (Object_identity * oi = first(); oi; oi = first())
oi->invalidate();
}
namespace Kernel {
template <> Pd *Object::obj<Pd>() const
{
if (_type != PD) {
return nullptr; }
return reinterpret_cast<Pd *>(_obj);
}
template <> Irq *Object::obj<Irq>() const
{
if (_type != IRQ) {
return nullptr; }
return reinterpret_cast<Irq *>(_obj);
}
template <> Signal_receiver *Object::obj<Signal_receiver>() const
{
if (_type != SIGNAL_RECEIVER) {
return nullptr; }
return reinterpret_cast<Signal_receiver *>(_obj);
}
template <> Signal_context *Object::obj<Signal_context>() const
{
if (_type != SIGNAL_CONTEXT) {
return nullptr; }
return reinterpret_cast<Signal_context *>(_obj);
}
template <> Thread *Object::obj<Thread>() const
{
if (_type != THREAD) {
return nullptr; }
return reinterpret_cast<Thread *>(_obj);
}
template <> Vm *Object::obj<Vm>() const
{
if (_type != VM) {
return nullptr; }
return reinterpret_cast<Vm *>(_obj);
}
}
/*********************
** Object_identity **

View File

@ -27,7 +27,16 @@
namespace Kernel
{
class Pd; /* forward declaration */
/*
* Forward declarations
*/
class Pd;
class Irq;
class Thread;
class Signal_context;
class Signal_receiver;
class Vm;
/**
* Base class of all Kernel objects
@ -73,12 +82,39 @@ namespace Kernel
}
struct Kernel::Object : private Object_identity_list
class Kernel::Object : private Object_identity_list
{
using Object_identity_list::remove;
using Object_identity_list::insert;
private:
virtual ~Object();
enum Type { THREAD, PD, SIGNAL_RECEIVER, SIGNAL_CONTEXT, IRQ, VM };
/*
* Noncopyable
*/
Object(Object const &) = delete;
Object &operator = (Object const &) = delete;
Type const _type;
void *const _obj;
public:
struct Cannot_cast_to_type : Genode::Exception { };
using Object_identity_list::remove;
using Object_identity_list::insert;
Object(Thread &obj);
Object(Irq &obj);
Object(Signal_receiver &obj);
Object(Signal_context &obj);
Object(Pd &obj);
Object(Vm &obj);
~Object();
template <typename T>
T *obj() const;
};
@ -102,7 +138,7 @@ class Kernel::Object_identity
~Object_identity();
template <typename KOBJECT>
KOBJECT * object() { return dynamic_cast<KOBJECT*>(_object); }
KOBJECT * object() { return _object->obj<KOBJECT>(); }
void invalidate();
};
@ -190,7 +226,7 @@ class Kernel::Core_object_identity : public Object_identity,
public:
Core_object_identity(T & object)
: Object_identity(object),
: Object_identity(object.kernel_object()),
Object_identity_reference(this, core_pd()) { }
capid_t core_capid() { return capid(); }

View File

@ -39,7 +39,7 @@ namespace Kernel
}
class Kernel::Pd : public Kernel::Object
class Kernel::Pd
{
public:
@ -49,6 +49,7 @@ class Kernel::Pd : public Kernel::Object
private:
Kernel::Object _kernel_object { *this };
Hw::Page_table &_table;
Genode::Platform_pd &_platform_pd;
Capid_allocator _capid_alloc { };
@ -108,6 +109,7 @@ class Kernel::Pd : public Kernel::Object
** Accessors **
***************/
Object &kernel_object() { return _kernel_object; }
Genode::Platform_pd &platform_pd() { return _platform_pd; }
Hw::Page_table &translation_table() { return _table; }
Capid_allocator &capid_alloc() { return _capid_alloc; }
@ -118,7 +120,7 @@ class Kernel::Pd : public Kernel::Object
template<>
inline Kernel::Core_object_identity<Kernel::Pd>::Core_object_identity(Kernel::Pd & pd)
: Object_identity(pd),
: Object_identity(pd.kernel_object()),
Object_identity_reference(this, pd.core_pd() ? pd : core_pd()) { }
#endif /* _CORE__KERNEL__PD_H_ */

View File

@ -104,7 +104,7 @@ class Kernel::Signal_context_killer
void cancel_waiting();
};
class Kernel::Signal_context : public Kernel::Object
class Kernel::Signal_context
{
friend class Signal_receiver;
friend class Signal_context_killer;
@ -119,14 +119,15 @@ class Kernel::Signal_context : public Kernel::Object
typedef Genode::Fifo_element<Signal_context> Fifo_element;
Fifo_element _deliver_fe { *this };
Fifo_element _contexts_fe { *this };
Kernel::Object _kernel_object { *this };
Fifo_element _deliver_fe { *this };
Fifo_element _contexts_fe { *this };
Signal_receiver & _receiver;
addr_t const _imprint;
Signal_context_killer * _killer { nullptr };
unsigned _submits { 0 };
bool _ack { true };
bool _killed { false };
Signal_context_killer * _killer { nullptr };
unsigned _submits { 0 };
bool _ack { true };
bool _killed { false };
/**
* Tell receiver about the submits of the context if any
@ -209,9 +210,11 @@ class Kernel::Signal_context : public Kernel::Object
*/
static void syscall_destroy(Genode::Kernel_object<Signal_context> &c) {
call(call_id_delete_signal_context(), (Call_arg)&c); }
Object &kernel_object() { return _kernel_object; }
};
class Kernel::Signal_receiver : public Kernel::Object
class Kernel::Signal_receiver
{
friend class Signal_context;
friend class Signal_handler;
@ -222,9 +225,10 @@ class Kernel::Signal_receiver : public Kernel::Object
template <typename T> class Fifo : public Genode::Fifo<T> { };
Fifo<Signal_handler::Fifo_element> _handlers { };
Fifo<Signal_context::Fifo_element> _deliver { };
Fifo<Signal_context::Fifo_element> _contexts { };
Kernel::Object _kernel_object { *this };
Fifo<Signal_handler::Fifo_element> _handlers { };
Fifo<Signal_context::Fifo_element> _deliver { };
Fifo<Signal_context::Fifo_element> _contexts { };
/**
* Recognize that context 'c' has submits to deliver
@ -282,6 +286,8 @@ class Kernel::Signal_receiver : public Kernel::Object
*/
static void syscall_destroy(Genode::Kernel_object<Signal_receiver> &r) {
call(call_id_delete_signal_receiver(), (Call_arg)&r); }
Object &kernel_object() { return _kernel_object; }
};
#endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */

View File

@ -819,6 +819,7 @@ void Thread::_mmu_exception()
Thread::Thread(unsigned const priority, unsigned const quota,
char const * const label, bool core)
:
Kernel::Object { *this },
Cpu_job(priority, quota), _ipc_node(*this), _state(AWAITS_START),
_signal_receiver(0), _label(label), _core(core), regs(core) { }

View File

@ -56,9 +56,7 @@ struct Kernel::Thread_fault
/**
* Kernel back-end for userland execution-contexts
*/
class Kernel::Thread
:
public Kernel::Object, public Cpu_job, private Timeout
class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
{
private:
@ -404,6 +402,7 @@ class Kernel::Thread
** Accessors **
***************/
Object &kernel_object() { return *this; }
char const * label() const { return _label; }
Thread_fault fault() const { return _fault; }
Genode::Native_utcb *utcb() { return _utcb; }

View File

@ -33,8 +33,7 @@ namespace Kernel
}
class Kernel::Vm : public Cpu_job,
public Kernel::Object
class Kernel::Vm : public Cpu_job
{
private:
@ -48,6 +47,7 @@ class Kernel::Vm : public Cpu_job,
enum Scheduler_state { ACTIVE, INACTIVE };
Object _kernel_object { *this };
unsigned _id = 0;
State & _state;
Signal_context & _context;
@ -110,6 +110,7 @@ class Kernel::Vm : public Cpu_job,
static void syscall_destroy(Genode::Kernel_object<Vm> & vm) {
call(call_id_delete_vm(), (Call_arg) &vm); }
Object &kernel_object() { return _kernel_object; }
/****************
** Vm_session **