From 5e460394d2db25d070113bacf04c94a67ff7af36 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 29 Apr 2019 23:37:39 +0200 Subject: [PATCH] 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 --- repos/base-hw/src/core/kernel/irq.h | 5 +- repos/base-hw/src/core/kernel/object.cc | 87 +++++++++++++++++++ repos/base-hw/src/core/kernel/object.h | 50 +++++++++-- repos/base-hw/src/core/kernel/pd.h | 6 +- .../base-hw/src/core/kernel/signal_receiver.h | 28 +++--- repos/base-hw/src/core/kernel/thread.cc | 1 + repos/base-hw/src/core/kernel/thread.h | 5 +- repos/base-hw/src/core/kernel/vm.h | 5 +- 8 files changed, 161 insertions(+), 26 deletions(-) diff --git a/repos/base-hw/src/core/kernel/irq.h b/repos/base-hw/src/core/kernel/irq.h index 3d8c22034..2b5a7b454 100644 --- a/repos/base-hw/src/core/kernel/irq.h +++ b/repos/base-hw/src/core/kernel/irq.h @@ -119,10 +119,11 @@ class Kernel::Irq : Genode::Avl_node }; -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 &irq) { call(call_id_delete_irq(), (Call_arg) &irq); } + + Object &kernel_object() { return _kernel_object; } }; #endif /* _CORE__KERNEL__IRQ_H_ */ diff --git a/repos/base-hw/src/core/kernel/object.cc b/repos/base-hw/src/core/kernel/object.cc index 8e445cf32..c44250853 100644 --- a/repos/base-hw/src/core/kernel/object.cc +++ b/repos/base-hw/src/core/kernel/object.cc @@ -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() const + { + if (_type != PD) { + return nullptr; } + + return reinterpret_cast(_obj); + } + + template <> Irq *Object::obj() const + { + if (_type != IRQ) { + return nullptr; } + + return reinterpret_cast(_obj); + } + + template <> Signal_receiver *Object::obj() const + { + if (_type != SIGNAL_RECEIVER) { + return nullptr; } + + return reinterpret_cast(_obj); + } + + template <> Signal_context *Object::obj() const + { + if (_type != SIGNAL_CONTEXT) { + return nullptr; } + + return reinterpret_cast(_obj); + } + + template <> Thread *Object::obj() const + { + if (_type != THREAD) { + return nullptr; } + + return reinterpret_cast(_obj); + } + + template <> Vm *Object::obj() const + { + if (_type != VM) { + return nullptr; } + + return reinterpret_cast(_obj); + } +} + /********************* ** Object_identity ** diff --git a/repos/base-hw/src/core/kernel/object.h b/repos/base-hw/src/core/kernel/object.h index 89a032d8e..954ba2ef0 100644 --- a/repos/base-hw/src/core/kernel/object.h +++ b/repos/base-hw/src/core/kernel/object.h @@ -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 + T *obj() const; }; @@ -102,7 +138,7 @@ class Kernel::Object_identity ~Object_identity(); template - KOBJECT * object() { return dynamic_cast(_object); } + KOBJECT * object() { return _object->obj(); } 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(); } diff --git a/repos/base-hw/src/core/kernel/pd.h b/repos/base-hw/src/core/kernel/pd.h index 18b7af7e6..e9956e36d 100644 --- a/repos/base-hw/src/core/kernel/pd.h +++ b/repos/base-hw/src/core/kernel/pd.h @@ -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::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_ */ diff --git a/repos/base-hw/src/core/kernel/signal_receiver.h b/repos/base-hw/src/core/kernel/signal_receiver.h index 4e23ec6ad..94804b350 100644 --- a/repos/base-hw/src/core/kernel/signal_receiver.h +++ b/repos/base-hw/src/core/kernel/signal_receiver.h @@ -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 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 &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 class Fifo : public Genode::Fifo { }; - Fifo _handlers { }; - Fifo _deliver { }; - Fifo _contexts { }; + Kernel::Object _kernel_object { *this }; + Fifo _handlers { }; + Fifo _deliver { }; + Fifo _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 &r) { call(call_id_delete_signal_receiver(), (Call_arg)&r); } + + Object &kernel_object() { return _kernel_object; } }; #endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */ diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 5ee8f8e51..b9fe33949 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -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) { } diff --git a/repos/base-hw/src/core/kernel/thread.h b/repos/base-hw/src/core/kernel/thread.h index 98086398e..56718156a 100644 --- a/repos/base-hw/src/core/kernel/thread.h +++ b/repos/base-hw/src/core/kernel/thread.h @@ -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; } diff --git a/repos/base-hw/src/core/kernel/vm.h b/repos/base-hw/src/core/kernel/vm.h index 94472bede..a6de42846 100644 --- a/repos/base-hw/src/core/kernel/vm.h +++ b/repos/base-hw/src/core/kernel/vm.h @@ -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) { call(call_id_delete_vm(), (Call_arg) &vm); } + Object &kernel_object() { return _kernel_object; } /**************** ** Vm_session **