diff --git a/repos/base-fiasco/src/core/platform_thread.cc b/repos/base-fiasco/src/core/platform_thread.cc index 5bd183547..18e7e7b81 100644 --- a/repos/base-fiasco/src/core/platform_thread.cc +++ b/repos/base-fiasco/src/core/platform_thread.cc @@ -105,7 +105,7 @@ void Platform_thread::unbind() void Platform_thread::state(Thread_state s) { PDBG("Not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index cbdd6ed24..5fbc8dc0d 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -7,6 +7,7 @@ SRC_CC += stack_area.cc \ core_region_map.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ + cpu_thread_component.cc \ cpu_session_support.cc \ dataspace_component.cc \ default_log.cc \ @@ -53,6 +54,7 @@ vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) diff --git a/repos/base-foc/src/core/native_cpu_component.cc b/repos/base-foc/src/core/native_cpu_component.cc index ad8df5986..fafa5c540 100644 --- a/repos/base-foc/src/core/native_cpu_component.cc +++ b/repos/base-foc/src/core/native_cpu_component.cc @@ -38,7 +38,7 @@ void Genode::Native_cpu_component::enable_vcpu(Genode::Thread_capability thread_ auto lambda = [&] (Cpu_thread_component *thread) { if (!thread) return; - l4_cap_idx_t tid = thread->platform_thread()->thread().local.dst(); + l4_cap_idx_t tid = thread->platform_thread().thread().local.dst(); l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state); if (l4_msgtag_has_error(tag)) @@ -55,7 +55,7 @@ Genode::Native_cpu_component::native_cap(Genode::Thread_capability cap) auto lambda = [&] (Cpu_thread_component *thread) { return (!thread) ? Native_capability() - : thread->platform_thread()->thread().local; + : thread->platform_thread().thread().local; }; return _thread_ep.apply(cap, lambda); } diff --git a/repos/base-foc/src/core/target.inc b/repos/base-foc/src/core/target.inc index edcfca630..6ba978f44 100644 --- a/repos/base-foc/src/core/target.inc +++ b/repos/base-foc/src/core/target.inc @@ -11,6 +11,7 @@ SRC_CC += stack_area.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ + cpu_thread_component.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -51,6 +52,7 @@ include $(GEN_CORE_DIR)/version.inc vpath stack_area.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR) vpath default_log.cc $(GEN_CORE_DIR) diff --git a/repos/base-foc/src/lib/base/thread_start.cc b/repos/base-foc/src/lib/base/thread_start.cc index fcecb7a16..bc4ef528a 100644 --- a/repos/base-foc/src/lib/base/thread_start.cc +++ b/repos/base-foc/src/lib/base/thread_start.cc @@ -18,6 +18,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -76,9 +77,11 @@ void Thread::start() { using namespace Fiasco; + Cpu_thread_client cpu_thread(_thread_cap); + /* get gate-capability and badge of new thread */ Thread_state state; - try { state = _cpu_session->state(_thread_cap); } + try { state = cpu_thread.state(); } catch (...) { throw Cpu_session::Thread_creation_failed(); } /* remember UTCB of the new thread */ @@ -92,11 +95,11 @@ void Thread::start() l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this; /* register initial IP and SP at core */ - _cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top()); + cpu_thread.start((addr_t)_thread_start, _stack->top()); } void Thread::cancel_blocking() { - _cpu_session->cancel_blocking(_thread_cap); + Cpu_thread_client(_thread_cap).cancel_blocking(); } diff --git a/repos/base-hw/lib/mk/core.inc b/repos/base-hw/lib/mk/core.inc index f60e4e238..36e7bb1ee 100644 --- a/repos/base-hw/lib/mk/core.inc +++ b/repos/base-hw/lib/mk/core.inc @@ -18,6 +18,7 @@ INC_DIR += $(BASE_HW_DIR)/src/include $(BASE_DIR)/src/include SRC_CC += console.cc SRC_CC += cpu_session_component.cc SRC_CC += cpu_session_support.cc +SRC_CC += cpu_thread_component.cc SRC_CC += core_region_map.cc SRC_CC += core_mem_alloc.cc SRC_CC += core_rpc_cap_alloc.cc diff --git a/repos/base-hw/src/core/cpu_session_support.cc b/repos/base-hw/src/core/cpu_session_support.cc index 48ee653ab..e3f7f1fbe 100644 --- a/repos/base-hw/src/core/cpu_session_support.cc +++ b/repos/base-hw/src/core/cpu_session_support.cc @@ -21,15 +21,9 @@ using namespace Genode; -Ram_dataspace_capability -Cpu_session_component::utcb(Thread_capability thread_cap) +Dataspace_capability Cpu_thread_component::utcb() { - /* look up requested UTCB dataspace */ - auto lambda = [] (Cpu_thread_component *t) { - if (!t) return Ram_dataspace_capability(); - return t->platform_thread()->utcb(); - }; - return _thread_ep->apply(thread_cap, lambda); + return _platform_thread.utcb(); } diff --git a/repos/base-hw/src/lib/base/thread_start.cc b/repos/base-hw/src/lib/base/thread_start.cc index f9f6fff76..554ff5f1c 100644 --- a/repos/base-hw/src/lib/base/thread_start.cc +++ b/repos/base-hw/src/lib/base/thread_start.cc @@ -17,6 +17,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -85,7 +86,7 @@ void Thread::start() { /* attach userland stack */ try { - Ram_dataspace_capability ds = _cpu_session->utcb(_thread_cap); + Dataspace_capability ds = Cpu_thread_client(_thread_cap).utcb(); size_t const size = sizeof(_stack->utcb()); addr_t dst = Stack_allocator::addr_to_base(_stack) + stack_virtual_size() - size - stack_area_virtual_base(); @@ -95,11 +96,11 @@ void Thread::start() sleep_forever(); } /* start thread with its initial IP and aligned SP */ - _cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top()); + Cpu_thread_client(_thread_cap).start((addr_t)_thread_start, _stack->top()); } void Thread::cancel_blocking() { - _cpu_session->cancel_blocking(_thread_cap); + Cpu_thread_client(_thread_cap).cancel_blocking(); } diff --git a/repos/base-linux/src/core/include/platform_thread.h b/repos/base-linux/src/core/include/platform_thread.h index 14c577717..9e2f6ec6a 100644 --- a/repos/base-linux/src/core/include/platform_thread.h +++ b/repos/base-linux/src/core/include/platform_thread.h @@ -119,13 +119,13 @@ namespace Genode { Thread_state state() { PDBG("Not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } void state(Thread_state) { PDBG("Not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } const char *name() { return _name; } diff --git a/repos/base-linux/src/core/native_cpu_component.cc b/repos/base-linux/src/core/native_cpu_component.cc index dc0b7b416..f4e905d35 100644 --- a/repos/base-linux/src/core/native_cpu_component.cc +++ b/repos/base-linux/src/core/native_cpu_component.cc @@ -21,7 +21,7 @@ using namespace Genode; void Native_cpu_component::thread_id(Thread_capability thread_cap, int pid, int tid) { _thread_ep.apply(thread_cap, [&] (Cpu_thread_component *thread) { - if (thread) thread->platform_thread()->thread_id(pid, tid); }); + if (thread) thread->platform_thread().thread_id(pid, tid); }); } @@ -32,7 +32,7 @@ Untyped_capability Native_cpu_component::server_sd(Thread_capability thread_cap) enum { DUMMY_LOCAL_NAME = 0 }; typedef Native_capability::Dst Dst; - return Untyped_capability(Dst(thread->platform_thread()->server_sd()), + return Untyped_capability(Dst(thread->platform_thread().server_sd()), DUMMY_LOCAL_NAME); }; return _thread_ep.apply(thread_cap, lambda); @@ -46,7 +46,7 @@ Untyped_capability Native_cpu_component::client_sd(Thread_capability thread_cap) enum { DUMMY_LOCAL_NAME = 0 }; typedef Native_capability::Dst Dst; - return Untyped_capability(Dst(thread->platform_thread()->client_sd()), + return Untyped_capability(Dst(thread->platform_thread().client_sd()), DUMMY_LOCAL_NAME); }; return _thread_ep.apply(thread_cap, lambda); diff --git a/repos/base-linux/src/core/target.mk b/repos/base-linux/src/core/target.mk index 914dbf50e..12e4d0bbc 100644 --- a/repos/base-linux/src/core/target.mk +++ b/repos/base-linux/src/core/target.mk @@ -13,6 +13,7 @@ SRC_CC = main.cc \ rom_session_component.cc \ cpu_session_component.cc \ cpu_session_support.cc \ + cpu_thread_component.cc \ pd_session_component.cc \ pd_upgrade_ram_quota.cc \ dataspace_component.cc \ @@ -44,6 +45,7 @@ vpath main.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) diff --git a/repos/base-linux/src/lib/base/child_process.cc b/repos/base-linux/src/lib/base/child_process.cc index 2992be980..8df9bba02 100644 --- a/repos/base-linux/src/lib/base/child_process.cc +++ b/repos/base-linux/src/lib/base/child_process.cc @@ -32,16 +32,19 @@ using namespace Genode; * thread. Those information will be provided to core by the constructor of * the 'Platform_env' of the new process. */ -Child::Process::Initial_thread::Initial_thread(Cpu_session &cpu, - Pd_session_capability pd, - char const *name) +Child::Initial_thread::Initial_thread(Cpu_session &cpu, + Pd_session_capability pd, + Name const &name) : - cpu(cpu), - cap(cpu.create_thread(pd, name, Affinity::Location(), Cpu_session::Weight())) + _cpu(cpu), + _cap(cpu.create_thread(pd, name, Affinity::Location(), Cpu_session::Weight())) { } -Child::Process::Initial_thread::~Initial_thread() { } +Child::Initial_thread::~Initial_thread() { } + + +void Child::Initial_thread::start(addr_t) { } /* @@ -60,13 +63,12 @@ Child::Process::Process(Dataspace_capability elf_ds, Pd_session_capability pd_cap, Pd_session &pd, Ram_session &ram, - Cpu_session &cpu, + Initial_thread_base &initial_thread, Region_map &local_rm, Region_map &remote_rm, - Parent_capability parent_cap, - char const *name) + Parent_capability parent_cap) : - initial_thread(cpu, pd_cap, name), + initial_thread(initial_thread), loaded_executable(elf_ds, ldso_ds, ram, local_rm, remote_rm, parent_cap) { /* skip loading when called during fork */ diff --git a/repos/base-linux/src/lib/base/thread_linux.cc b/repos/base-linux/src/lib/base/thread_linux.cc index e2a25c7de..06be634fd 100644 --- a/repos/base-linux/src/lib/base/thread_linux.cc +++ b/repos/base-linux/src/lib/base/thread_linux.cc @@ -18,6 +18,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -154,5 +155,5 @@ void Thread::start() void Thread::cancel_blocking() { - _cpu_session->cancel_blocking(_thread_cap); + Cpu_thread_client(_thread_cap).cancel_blocking(); } diff --git a/repos/base-nova/include/cpu_session/client.h b/repos/base-nova/include/cpu_session/client.h index d576d47a3..ea198a8a8 100644 --- a/repos/base-nova/include/cpu_session/client.h +++ b/repos/base-nova/include/cpu_session/client.h @@ -21,96 +21,48 @@ #include -namespace Genode { +namespace Genode { struct Cpu_session_client; } - struct Cpu_session_client : Rpc_client - { - explicit Cpu_session_client(Cpu_session_capability session) - : Rpc_client(static_cap_cast(session)) { } - Thread_capability - create_thread(Capability pd, Name const &name, - Affinity::Location affinity, Weight weight, addr_t utcb = 0) override { - return call(pd, name, affinity, weight, utcb); } +struct Genode::Cpu_session_client : Rpc_client +{ + explicit Cpu_session_client(Cpu_session_capability session) + : Rpc_client(static_cap_cast(session)) { } - Ram_dataspace_capability utcb(Thread_capability thread) override { - return call(thread); } + Thread_capability + create_thread(Capability pd, Name const &name, + Affinity::Location affinity, Weight weight, addr_t utcb = 0) override { + return call(pd, name, affinity, weight, utcb); } - void kill_thread(Thread_capability thread) override { - call(thread); } + void kill_thread(Thread_capability thread) override { + call(thread); } - int start(Thread_capability thread, addr_t ip, addr_t sp) override { - return call(thread, ip, sp); } + void exception_sigh(Signal_context_capability handler) override { + call(handler); } - void pause(Thread_capability thread) override - { - Native_capability block = call(thread); - if (!block.valid()) - return; + Affinity::Space affinity_space() const override { + return call(); } - Nova::sm_ctrl(block.local_name(), Nova::SEMAPHORE_DOWN); - } + Dataspace_capability trace_control() override { + return call(); } - void resume(Thread_capability thread) override { - call(thread); } + int ref_account(Cpu_session_capability session) override { + return call(session); } - void cancel_blocking(Thread_capability thread) override { - call(thread); } + int transfer_quota(Cpu_session_capability session, size_t amount) override { + return call(session, amount); } - Thread_state state(Thread_capability thread) override { - return call(thread); } + Quota quota() override { return call(); } - void state(Thread_capability thread, Thread_state const &state) override { - call(thread, state); } + Capability native_cpu() override { return call(); } - void exception_handler(Thread_capability thread, Signal_context_capability handler) override { - call(thread, handler); } + private: - void single_step(Thread_capability thread, bool enable) override - { - Native_capability block = call(thread, enable); - if (!block.valid()) - return; + Native_capability pause_sync(Thread_capability) { + return Native_capability(); } - Nova::sm_ctrl(block.local_name(), Nova::SEMAPHORE_DOWN); - } - - Affinity::Space affinity_space() const override { - return call(); } - - void affinity(Thread_capability thread, Affinity::Location location) override { - call(thread, location); } - - Dataspace_capability trace_control() override { - return call(); } - - unsigned trace_control_index(Thread_capability thread) override { - return call(thread); } - - Dataspace_capability trace_buffer(Thread_capability thread) override { - return call(thread); } - - Dataspace_capability trace_policy(Thread_capability thread) override { - return call(thread); } - - int ref_account(Cpu_session_capability session) override { - return call(session); } - - int transfer_quota(Cpu_session_capability session, size_t amount) override { - return call(session, amount); } - - Quota quota() override { return call(); } - - Capability native_cpu() override { return call(); } - - private: - - Native_capability pause_sync(Thread_capability) { - return Native_capability(); } - - Native_capability single_step_sync(Thread_capability, bool) { - return Native_capability(); } - }; -} + Native_capability single_step_sync(Thread_capability, bool) { + return Native_capability(); } +}; #endif /* _INCLUDE__CPU_SESSION__CLIENT_H_ */ diff --git a/repos/base-nova/src/core/cpu_session_extension.cc b/repos/base-nova/src/core/cpu_session_extension.cc index 4324f1924..af09380ba 100644 --- a/repos/base-nova/src/core/cpu_session_extension.cc +++ b/repos/base-nova/src/core/cpu_session_extension.cc @@ -24,10 +24,10 @@ Native_capability Cpu_session_component::pause_sync(Thread_capability thread_cap) { auto lambda = [] (Cpu_thread_component *thread) { - if (!thread || !thread->platform_thread()) + if (!thread) return Native_capability(); - return thread->platform_thread()->pause(); + return thread->platform_thread().pause(); }; return _thread_ep->apply(thread_cap, lambda); } @@ -39,10 +39,10 @@ Cpu_session_component::single_step_sync(Thread_capability thread_cap, bool enabl using namespace Genode; auto lambda = [enable] (Cpu_thread_component *thread) { - if (!thread || !thread->platform_thread()) + if (!thread) return Native_capability(); - return thread->platform_thread()->single_step_sync(enable); + return thread->platform_thread().single_step_sync(enable); }; return _thread_ep->apply(thread_cap, lambda); } diff --git a/repos/base-nova/src/core/include/cpu_session_component.h b/repos/base-nova/src/core/include/cpu_session_component.h index 5f6916184..0038c0437 100644 --- a/repos/base-nova/src/core/include/cpu_session_component.h +++ b/repos/base-nova/src/core/include/cpu_session_component.h @@ -26,6 +26,7 @@ /* core includes */ #include +#include #include #include #include @@ -33,325 +34,130 @@ #include #include -namespace Genode { - - /** - * RPC interface of CPU thread - * - * We make 'Cpu_thread' a RPC object only to be able to lookup CPU threads - * from thread capabilities supplied as arguments to CPU-session functions. - * A CPU thread does not provide an actual RPC interface. - */ - struct Cpu_thread - { - GENODE_RPC_INTERFACE(); - }; +namespace Genode { class Cpu_session_component; } - class Cpu_thread_component : public Rpc_object, - public List::Element, - public Trace::Source::Info_accessor - { - public: +class Genode::Cpu_session_component : public Rpc_object +{ + public: - typedef Trace::Session_label Session_label; - typedef Trace::Thread_name Thread_name; + typedef Cpu_thread_component::Session_label Session_label; - private: + private: - Rpc_entrypoint &_ep; - Pager_entrypoint &_pager_ep; - Capability _pd; - Region_map_component &_address_space_region_map; - Cpu_session::Weight const _weight; - Session_label const _session_label; - Thread_name const _name; - Platform_thread _platform_thread; - bool const _bound_to_pd; + Session_label _label; + Rpc_entrypoint *_session_ep; + Rpc_entrypoint *_thread_ep; + Pager_entrypoint *_pager_ep; + Allocator_guard _md_alloc; /* guarded meta-data allocator */ + Cpu_thread_allocator _thread_alloc; /* meta-data allocator */ + Lock _thread_alloc_lock; /* protect allocator access */ + List _thread_list; + Lock _thread_list_lock; /* protect thread list */ + unsigned _priority; /* priority of threads + created with this + session */ + Affinity::Location _location; /* CPU affinity of this + session */ + Trace::Source_registry &_trace_sources; + Trace::Control_area _trace_control_area; - bool _bind_to_pd(Pd_session_component &pd) - { - if (!pd.bind_thread(_platform_thread)) - throw Cpu_session::Thread_creation_failed(); - return true; - } + /* + * Members for quota accounting + */ - Signal_context_capability _sigh; /* exception handler */ + size_t _weight; + size_t _quota; + Cpu_session_component * _ref; + List _ref_members; + Lock _ref_members_lock; - struct Trace_control_slot - { - unsigned index = 0; - Trace::Control_area &trace_control_area; + Native_cpu_component _native_cpu; - Trace_control_slot(Trace::Control_area &trace_control_area) - : trace_control_area(trace_control_area) - { - if (!trace_control_area.alloc(index)) - throw Cpu_session::Out_of_metadata(); - } + friend class Native_cpu_component; - ~Trace_control_slot() - { - trace_control_area.free(index); - } + void _incr_weight(size_t); + void _decr_weight(size_t); + size_t _weight_to_quota(size_t) const; + void _decr_quota(size_t); + void _incr_quota(size_t); + void _update_thread_quota(Cpu_thread_component &) const; + void _update_each_thread_quota(); + void _transfer_quota(Cpu_session_component *, size_t); + void _insert_ref_member(Cpu_session_component *) { } + void _unsync_remove_ref_member(Cpu_session_component *) { } + void _remove_ref_member(Cpu_session_component *) { } + void _deinit_ref_account(); + void _deinit_threads(); - Trace::Control &control() - { - return *trace_control_area.at(index); - } - }; + /** + * Exception handler to be invoked unless overridden by a + * thread-specific handler via 'Cpu_thread::exception_sigh' + */ + Signal_context_capability _exception_sigh; - Trace_control_slot _trace_control_slot; + /** + * Raw thread-killing functionality + * + * This function is called from the 'kill_thread' function and + * the destructor. Each these functions grab the list lock + * by themselves and call this function to perform the actual + * killing. + */ + void _unsynchronized_kill_thread(Thread_capability cap); - Trace::Source _trace_source { *this, _trace_control_slot.control() }; + /** + * Convert session-local affinity location to physical location + */ + Affinity::Location _thread_affinity(Affinity::Location) const; - Weak_ptr _address_space = _platform_thread.address_space(); + public: - Rm_client _rm_client; + /** + * Constructor + */ + Cpu_session_component(Rpc_entrypoint *session_ep, + Rpc_entrypoint *thread_ep, + Pager_entrypoint *pager_ep, + Allocator *md_alloc, + Trace::Source_registry &trace_sources, + const char *args, Affinity const &affinity, + size_t quota); - public: + /** + * Destructor + */ + ~Cpu_session_component(); - /** - * Constructor - * - * \param ep entrypoint used for managing the thread RPC - * object - * \param pager_ep pager entrypoint used for handling the page - * faults of the thread - * \param pd PD session where the thread is executed - * \param weight scheduling weight relative to the other - * threads of the same CPU session - * \param quota initial quota counter-value of the weight - * \param labal label of the threads session - * \param name name for the thread - * \param priority scheduling priority - * \param utcb user-local UTCB base - * \param sigh initial exception handler - */ - Cpu_thread_component(Cpu_session_capability cpu_session_cap, - Rpc_entrypoint &ep, - Pager_entrypoint &pager_ep, - Pd_session_component &pd, - Trace::Control_area &trace_control_area, - Cpu_session::Weight weight, - size_t quota, - Affinity::Location location, - Session_label const &label, - Thread_name const &name, - unsigned priority, - addr_t utcb, - Signal_context_capability sigh) - : - _ep(ep), _pager_ep(pager_ep), _pd(pd.cap()), - _address_space_region_map(pd.address_space_region_map()), - _weight(weight), - _session_label(label), _name(name), - _platform_thread(name.string(), priority, location, utcb), - _bound_to_pd(_bind_to_pd(pd)), - _sigh(sigh), - _trace_control_slot(trace_control_area), - _rm_client(cpu_session_cap, _ep.manage(this), - &_address_space_region_map, - _platform_thread.pager_object_badge(), - _address_space, _platform_thread.affinity()) - { - update_exception_sigh(); - - _address_space_region_map.add_client(_rm_client); - - /* acquaint thread with its pager object */ - _pager_ep.manage(&_rm_client); - _platform_thread.pager(&_rm_client); - } - - ~Cpu_thread_component() - { - _pager_ep.dissolve(&_rm_client); - _ep.dissolve(this); - - _address_space_region_map.remove_client(_rm_client); - } - - void affinity(Affinity::Location affinity) - { - _platform_thread.affinity(affinity); - } + /** + * Register quota donation at allocator guard + */ + void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - /******************************************** - ** Trace::Source::Info_accessor interface ** - ********************************************/ + /*************************** + ** CPU session interface ** + ***************************/ - Trace::Source::Info trace_source_info() const - { - return { _session_label, _name, - _platform_thread.execution_time(), - _platform_thread.affinity() }; - } + Thread_capability create_thread(Capability, Name const &, + Affinity::Location, Weight, addr_t) override; + void kill_thread(Thread_capability) override; + void exception_sigh(Signal_context_capability) override; + Affinity::Space affinity_space() const override; + Dataspace_capability trace_control() override; + int ref_account(Cpu_session_capability c) override; + int transfer_quota(Cpu_session_capability, size_t) override; + Quota quota() override; + + Capability native_cpu() { return _native_cpu.cap(); } - /************************ - ** Accessor functions ** - ************************/ + /****************************** + ** NOVA specific extensions ** + ******************************/ - Platform_thread *platform_thread() { return &_platform_thread; } - - Trace::Source *trace_source() { return &_trace_source; } - - size_t weight() const { return Cpu_session::Weight::DEFAULT_WEIGHT; } - - void sigh(Signal_context_capability sigh) - { - _sigh = sigh; - update_exception_sigh(); - } - - /** - * Propagate exception handler to platform thread - */ - void update_exception_sigh(); - - /** - * Return index within the CPU-session's trace control area - */ - unsigned trace_control_index() const { return _trace_control_slot.index; } - }; - - - class Cpu_session_component : public Rpc_object - { - public: - - typedef Cpu_thread_component::Session_label Session_label; - - private: - - Session_label _label; - Rpc_entrypoint *_session_ep; - Rpc_entrypoint *_thread_ep; - Pager_entrypoint *_pager_ep; - Allocator_guard _md_alloc; /* guarded meta-data allocator */ - Cpu_thread_allocator _thread_alloc; /* meta-data allocator */ - Lock _thread_alloc_lock; /* protect allocator access */ - List _thread_list; - Lock _thread_list_lock; /* protect thread list */ - unsigned _priority; /* priority of threads - created with this - session */ - Affinity::Location _location; /* CPU affinity of this - session */ - Trace::Source_registry &_trace_sources; - Trace::Control_area _trace_control_area; - - /* - * Members for quota accounting - */ - - size_t _weight; - size_t _quota; - Cpu_session_component * _ref; - List _ref_members; - Lock _ref_members_lock; - - Native_cpu_component _native_cpu; - - friend class Native_cpu_component; - - void _incr_weight(size_t); - void _decr_weight(size_t); - size_t _weight_to_quota(size_t) const; - void _decr_quota(size_t); - void _incr_quota(size_t); - void _update_thread_quota(Cpu_thread_component *) const; - void _update_each_thread_quota(); - void _transfer_quota(Cpu_session_component *, size_t); - void _insert_ref_member(Cpu_session_component *) { } - void _unsync_remove_ref_member(Cpu_session_component *) { } - void _remove_ref_member(Cpu_session_component *) { } - void _deinit_ref_account(); - void _deinit_threads(); - - /** - * Exception handler that will be invoked unless overridden by a - * call of 'Cpu_session::exception_handler'. - */ - Signal_context_capability _default_exception_handler; - - /** - * Raw thread-killing functionality - * - * This function is called from the 'kill_thread' function and - * the destructor. Each these functions grab the list lock - * by themselves and call this function to perform the actual - * killing. - */ - void _unsynchronized_kill_thread(Thread_capability cap); - - /** - * Convert session-local affinity location to physical location - */ - Affinity::Location _thread_affinity(Affinity::Location) const; - - public: - - /** - * Constructor - */ - Cpu_session_component(Rpc_entrypoint *session_ep, - Rpc_entrypoint *thread_ep, - Pager_entrypoint *pager_ep, - Allocator *md_alloc, - Trace::Source_registry &trace_sources, - const char *args, Affinity const &affinity, - size_t quota); - - /** - * Destructor - */ - ~Cpu_session_component(); - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - - - /*************************** - ** CPU session interface ** - ***************************/ - - Thread_capability create_thread(Capability, Name const &, - Affinity::Location, Weight, addr_t) override; - Ram_dataspace_capability utcb(Thread_capability thread) override; - void kill_thread(Thread_capability) override; - int start(Thread_capability, addr_t, addr_t) override; - void pause(Thread_capability thread_cap) override; - void resume(Thread_capability thread_cap) override; - void single_step(Thread_capability thread_cap, bool enable) override; - void cancel_blocking(Thread_capability) override; - Thread_state state(Thread_capability) override; - void state(Thread_capability, Thread_state const &) override; - void exception_handler(Thread_capability, Signal_context_capability) override; - Affinity::Space affinity_space() const override; - void affinity(Thread_capability, Affinity::Location) override; - Dataspace_capability trace_control() override; - unsigned trace_control_index(Thread_capability) override; - Dataspace_capability trace_buffer(Thread_capability) override; - Dataspace_capability trace_policy(Thread_capability) override; - int ref_account(Cpu_session_capability c) override; - int transfer_quota(Cpu_session_capability, size_t) override; - Quota quota() override; - - Capability native_cpu() { return _native_cpu.cap(); } - - - /****************************** - ** NOVA specific extensions ** - ******************************/ - - Native_capability pause_sync(Thread_capability) override; - Native_capability single_step_sync(Thread_capability, bool) override; - }; -} + Native_capability pause_sync(Thread_capability) override; + Native_capability single_step_sync(Thread_capability, bool) override; +}; #endif /* _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/include/platform_thread.h b/repos/base-nova/src/core/include/platform_thread.h index 53b9cae12..56d5a6e28 100644 --- a/repos/base-nova/src/core/include/platform_thread.h +++ b/repos/base-nova/src/core/include/platform_thread.h @@ -68,7 +68,7 @@ namespace Genode { /** * Constructor */ - Platform_thread(const char *name = 0, + Platform_thread(size_t, const char *name = 0, unsigned priority = 0, Affinity::Location affinity = Affinity::Location(), int thread_id = THREAD_INVALID); diff --git a/repos/base-nova/src/core/native_cpu_component.cc b/repos/base-nova/src/core/native_cpu_component.cc index d8d6a3919..e2a8955fb 100644 --- a/repos/base-nova/src/core/native_cpu_component.cc +++ b/repos/base-nova/src/core/native_cpu_component.cc @@ -28,7 +28,7 @@ Native_cpu_component::pager_cap(Thread_capability thread_cap) if (!thread) return Native_capability(); - return thread->platform_thread()->pager()->cap(); + return thread->platform_thread().pager()->cap(); }; return _thread_ep.apply(thread_cap, lambda); } diff --git a/repos/base-nova/src/core/platform_thread.cc b/repos/base-nova/src/core/platform_thread.cc index 9e23cc0c7..d68fce1f3 100644 --- a/repos/base-nova/src/core/platform_thread.cc +++ b/repos/base-nova/src/core/platform_thread.cc @@ -249,7 +249,7 @@ void Platform_thread::resume() Thread_state Platform_thread::state() { - if (!_pager) throw Cpu_session::State_access_failed(); + if (!_pager) throw Cpu_thread::State_access_failed(); Thread_state s; @@ -261,7 +261,7 @@ Thread_state Platform_thread::state() return s; } - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } @@ -269,7 +269,7 @@ void Platform_thread::state(Thread_state s) { /* you can do it only once */ if (_sel_exc_base != Native_thread::INVALID_INDEX) - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); /* * s.sel_exc_base exception base of thread in caller @@ -345,7 +345,7 @@ unsigned long long Platform_thread::execution_time() const } -Platform_thread::Platform_thread(const char *name, unsigned prio, +Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, Affinity::Location affinity, int thread_id) : _pd(0), _pager(0), _id_base(cap_map()->insert(2)), diff --git a/repos/base-nova/src/core/target.inc b/repos/base-nova/src/core/target.inc index c5604c06f..02ddda718 100644 --- a/repos/base-nova/src/core/target.inc +++ b/repos/base-nova/src/core/target.inc @@ -11,6 +11,7 @@ SRC_CC = stack_area.cc \ cpu_session_component.cc \ cpu_session_extension.cc \ cpu_session_support.cc \ + cpu_thread_component.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -53,6 +54,7 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-nova/src/lib/base/thread_start.cc b/repos/base-nova/src/lib/base/thread_start.cc index d2f8b8aa6..7a0ee4a80 100644 --- a/repos/base-nova/src/lib/base/thread_start.cc +++ b/repos/base-nova/src/lib/base/thread_start.cc @@ -21,6 +21,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -164,11 +165,11 @@ void Thread::start() /* local thread have no start instruction pointer - set via portal entry */ addr_t thread_ip = global ? reinterpret_cast(_thread_start) : 0; - try { _cpu_session->state(_thread_cap, state); } + Cpu_thread_client cpu_thread(_thread_cap); + try { cpu_thread.state(state); } catch (...) { throw Cpu_session::Thread_creation_failed(); } - if (_cpu_session->start(_thread_cap, thread_ip, _stack->top())) - throw Cpu_session::Thread_creation_failed(); + cpu_thread.start(thread_ip, _stack->top()); /* request native EC thread cap */ native_thread().ec_sel = cap_map()->insert(1); @@ -193,7 +194,7 @@ void Thread::start() if (global) /* request creation of SC to let thread run*/ - _cpu_session->resume(_thread_cap); + cpu_thread.resume(); } diff --git a/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc b/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc index 73380be3b..2bf59faed 100644 --- a/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc +++ b/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc @@ -60,6 +60,6 @@ Thread_state Platform_thread::state() void Platform_thread::state(Thread_state) { PDBG("Not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc index 31c10b166..b1c4111e1 100644 --- a/repos/base-okl4/src/core/target.inc +++ b/repos/base-okl4/src/core/target.inc @@ -11,6 +11,7 @@ SRC_CC += stack_area.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ + cpu_thread_component.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -48,6 +49,7 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/src/core/cpu_session_platform.cc b/repos/base-pistachio/src/core/cpu_session_platform.cc index 8d2f12c78..d7e9b8d82 100644 --- a/repos/base-pistachio/src/core/cpu_session_platform.cc +++ b/repos/base-pistachio/src/core/cpu_session_platform.cc @@ -17,10 +17,11 @@ using namespace Genode; using namespace Pistachio; -Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread_cap) + +Dataspace_capability Cpu_thread_component::utcb() { PERR("%s: Not implemented", __PRETTY_FUNCTION__); - return Ram_dataspace_capability(); + return Dataspace_capability(); } diff --git a/repos/base-pistachio/src/core/platform_thread.cc b/repos/base-pistachio/src/core/platform_thread.cc index 5b31c0fe0..d34bbc64a 100644 --- a/repos/base-pistachio/src/core/platform_thread.cc +++ b/repos/base-pistachio/src/core/platform_thread.cc @@ -175,7 +175,7 @@ void Platform_thread::unbind() void Platform_thread::state(Thread_state) { PDBG("Not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index d4bb70adf..ff81129f6 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -10,6 +10,7 @@ SRC_CC = stack_area.cc \ core_region_map.cc \ cpu_session_component.cc \ cpu_session_platform.cc \ + cpu_thread_component.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -49,6 +50,7 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/lib/mk/core.mk b/repos/base-sel4/lib/mk/core.mk index 5e9d1e5ba..2c6e860a5 100644 --- a/repos/base-sel4/lib/mk/core.mk +++ b/repos/base-sel4/lib/mk/core.mk @@ -9,6 +9,7 @@ SRC_CC += \ rom_session_component.cc \ cpu_session_component.cc \ cpu_session_support.cc \ + cpu_thread_component.cc \ pd_session_component.cc \ rpc_cap_factory.cc \ pd_assign_pci.cc \ @@ -47,6 +48,7 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/src/core/platform_thread.cc b/repos/base-sel4/src/core/platform_thread.cc index 49b4fa8df..b084d3646 100644 --- a/repos/base-sel4/src/core/platform_thread.cc +++ b/repos/base-sel4/src/core/platform_thread.cc @@ -172,14 +172,14 @@ void Platform_thread::resume() void Platform_thread::state(Thread_state s) { PDBG("not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } Thread_state Platform_thread::state() { PDBG("not implemented"); - throw Cpu_session::State_access_failed(); + throw Cpu_thread::State_access_failed(); } diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h index 23d80475e..c4c69dbc5 100644 --- a/repos/base/include/base/child.h +++ b/repos/base/include/base/child.h @@ -152,6 +152,46 @@ struct Genode::Child_policy */ class Genode::Child : protected Rpc_object { + public: + + struct Initial_thread_base + { + /** + * Start execution at specified instruction pointer + */ + virtual void start(addr_t ip) = 0; + + /** + * Return capability of the initial thread + */ + virtual Capability cap() = 0; + }; + + struct Initial_thread : Initial_thread_base + { + private: + + Cpu_session &_cpu; + Thread_capability _cap; + + public: + + typedef Cpu_session::Name Name; + + /** + * Constructor + * + * \throw Cpu_session::Thread_creation_failed + * \throw Cpu_session::Out_of_metadata + */ + Initial_thread(Cpu_session &, Pd_session_capability, Name const &); + ~Initial_thread(); + + void start(addr_t) override; + + Capability cap() { return _cap; } + }; + private: class Session; @@ -200,17 +240,11 @@ class Genode::Child : protected Rpc_object struct Process { - struct Initial_thread - { - Cpu_session &cpu; - Thread_capability cap; - Initial_thread(Cpu_session &, Pd_session_capability, char const *); - ~Initial_thread(); - } initial_thread; - class Missing_dynamic_linker : Exception { }; class Invalid_executable : Exception { }; + Initial_thread_base &initial_thread; + struct Loaded_executable { /** @@ -246,12 +280,9 @@ class Genode::Child : protected Rpc_object * * \param ram RAM session used to allocate the BSS and * DATA segments for the new process - * \param cpu CPU session used to create the initial thread * \param parent parent of the new protection domain * \param name name of protection domain * - * \throw Cpu_session::Thread_creation_failed - * \throw Cpu_session::Out_of_metadata * \throw Missing_dynamic_linker * \throw Invalid_executable * \throw Region_map::Attach_failed @@ -272,11 +303,10 @@ class Genode::Child : protected Rpc_object Pd_session_capability pd_cap, Pd_session &pd, Ram_session &ram, - Cpu_session &cpu, + Initial_thread_base &initial_thread, Region_map &local_rm, Region_map &remote_rm, - Parent_capability parent, - char const *name); + Parent_capability parent); ~Process(); }; @@ -327,39 +357,39 @@ class Genode::Child : protected Rpc_object /** * Constructor * - * \param elf_ds dataspace that contains the ELF binary - * \param ldso_ds dataspace that contains the dynamic linker, - * started if 'elf_ds' is a dynamically linked - * executable - * \param pd_cap capability of the new protection domain, - * used as argument for creating the initial - * thread, and handed out to the child as its - * environment - * \param pd PD session used for assigning the parent - * capability of the new process - * \param ram_cap RAM session capability handed out to the - * child as its environment - * \param ram RAM session used to allocate the BSS and - * DATA segments and as backing store for the - * local heap partition to keep child-specific - * meta data - * \param cpu_cap CPU session capability handed out to the - * child as its environment - * \param cpu CPU session for the new protection domain - * \param local_rm local address space - * \param remote_rm address space of new protection domain - * \param pd_service provider of the 'pd' session - * \param ram_service provider of the 'ram' session - * \param cpu_service provider of the 'cpu' session + * \param elf_ds dataspace that contains the ELF binary + * \param ldso_ds dataspace that contains the dynamic linker, + * started if 'elf_ds' is a dynamically linked + * executable + * \param pd_cap capability of the new protection domain, + * used as argument for creating the initial + * thread, and handed out to the child as its + * environment + * \param pd PD session used for assigning the parent + * capability of the new process + * \param ram_cap RAM session capability handed out to the + * child as its environment + * \param ram RAM session used to allocate the BSS and + * DATA segments and as backing store for the + * local heap partition to keep child-specific + * meta data + * \param cpu_cap CPU session capability handed out to the + * child as its environment + * \param initial_thread initial thread of the new protection domain + * \param local_rm local address space + * \param remote_rm address space of new protection domain + * \param pd_service provider of the 'pd' session + * \param ram_service provider of the 'ram' session + * \param cpu_service provider of the 'cpu' session * * \throw Ram_session::Alloc_failed * \throw Process_startup_failed * - * Usually, the pairs of 'pd' and 'pd_cap', 'cpu' and 'cpu_cap', - * 'ram' and 'ram_cap' belong to each other. References to the - * session interfaces are passed as separate arguments in addition + * Usually, the pairs of 'pd' and 'pd_cap', 'initial_thread' and + * 'cpu_cap', 'ram' and 'ram_cap' belong to each other. References to + * the session interfaces are passed as separate arguments in addition * to the capabilities to allow the creator of a child to operate on - * locally implemented sessions during the child initialization. + * locally implemented interfaces during the child initialization. * * The 'ram_service', 'cpu_service', and 'pd_service' arguments are * needed to direct quota upgrades referring to the resources of @@ -373,7 +403,7 @@ class Genode::Child : protected Rpc_object Ram_session_capability ram_cap, Ram_session &ram, Cpu_session_capability cpu_cap, - Cpu_session &cpu, + Initial_thread_base &initial_thread, Region_map &local_rm, Region_map &remote_rm, Rpc_entrypoint &entrypoint, diff --git a/repos/base/include/cpu_session/client.h b/repos/base/include/cpu_session/client.h index f2484196d..6dfc5ed3b 100644 --- a/repos/base/include/cpu_session/client.h +++ b/repos/base/include/cpu_session/client.h @@ -30,54 +30,18 @@ struct Genode::Cpu_session_client : Rpc_client Affinity::Location affinity, Weight weight, addr_t utcb = 0) override { return call(pd, name, affinity, weight, utcb); } - Ram_dataspace_capability utcb(Thread_capability thread) override { - return call(thread); } - void kill_thread(Thread_capability thread) override { call(thread); } - int start(Thread_capability thread, addr_t ip, addr_t sp) override { - return call(thread, ip, sp); } - - void pause(Thread_capability thread) override { - call(thread); } - - void resume(Thread_capability thread) override { - call(thread); } - - void cancel_blocking(Thread_capability thread) override { - call(thread); } - - Thread_state state(Thread_capability thread) override { - return call(thread); } - - void state(Thread_capability thread, Thread_state const &state) override { - call(thread, state); } - - void exception_handler(Thread_capability thread, Signal_context_capability handler) override { - call(thread, handler); } - - void single_step(Thread_capability thread, bool enable) override { - call(thread, enable); } + void exception_sigh(Signal_context_capability sigh) override { + call(sigh); } Affinity::Space affinity_space() const override { return call(); } - void affinity(Thread_capability thread, Affinity::Location location) override { - call(thread, location); } - Dataspace_capability trace_control() override { return call(); } - unsigned trace_control_index(Thread_capability thread) override { - return call(thread); } - - Dataspace_capability trace_buffer(Thread_capability thread) override { - return call(thread); } - - Dataspace_capability trace_policy(Thread_capability thread) override { - return call(thread); } - int ref_account(Cpu_session_capability session) override { return call(session); } diff --git a/repos/base/include/cpu_session/cpu_session.h b/repos/base/include/cpu_session/cpu_session.h index 8f07f33c8..f189987ab 100644 --- a/repos/base/include/cpu_session/cpu_session.h +++ b/repos/base/include/cpu_session/cpu_session.h @@ -15,15 +15,12 @@ #define _INCLUDE__CPU_SESSION__CPU_SESSION_H_ #include +#include #include -#include -#include #include -#include -#include #include #include -#include +#include #include namespace Genode { struct Cpu_session; } @@ -36,7 +33,6 @@ struct Genode::Cpu_session : Session *********************/ class Thread_creation_failed : public Exception { }; - class State_access_failed : public Exception { }; class Quota_exceeded : public Thread_creation_failed { }; class Out_of_metadata : public Exception { }; @@ -88,11 +84,6 @@ struct Genode::Cpu_session : Session Weight weight, addr_t utcb = 0) = 0; - /** - * Get dataspace of the UTCB that is used by the specified thread - */ - virtual Ram_dataspace_capability utcb(Thread_capability thread) = 0; - /** * Kill an existing thread * @@ -101,82 +92,16 @@ struct Genode::Cpu_session : Session virtual void kill_thread(Thread_capability thread) = 0; /** - * Modify instruction and stack pointer of thread - start the - * thread + * Register default signal handler for exceptions * - * \param thread thread to start - * \param ip initial instruction pointer - * \param sp initial stack pointer - * - * \return 0 on success - */ - virtual int start(Thread_capability thread, addr_t ip, addr_t sp) = 0; - - /** - * Pause the specified thread - * - * After calling this method, the execution of the thread can be - * continued by calling 'resume'. - */ - virtual void pause(Thread_capability thread) = 0; - - /** - * Resume the specified thread - */ - virtual void resume(Thread_capability thread) = 0; - - /** - * Cancel a currently blocking operation - * - * \param thread thread to unblock - */ - virtual void cancel_blocking(Thread_capability thread) = 0; - - /** - * Get the current state of a specific thread - * - * \param thread targeted thread - * \return state of the targeted thread - * \throw State_access_failed - */ - virtual Thread_state state(Thread_capability thread) = 0; - - /** - * Override the current state of a specific thread - * - * \param thread targeted thread - * \param state state that shall be applied - * \throw State_access_failed - */ - virtual void state(Thread_capability thread, - Thread_state const &state) = 0; - - /** - * Register signal handler for exceptions of the specified thread - * - * If 'thread' is an invalid capability, the default exception - * handler for the CPU session is set. This handler is used for - * all threads that have no explicitly installed exception handler. - * The new default signal handler will take effect for threads - * created after the call. + * This handler is used for all threads that have no explicitly installed + * exception handler. * * On Linux, this exception is delivered when the process triggers * a SIGCHLD. On other platforms, this exception is delivered on * the occurrence of CPU exceptions such as division by zero. */ - virtual void exception_handler(Thread_capability thread, - Signal_context_capability handler) = 0; - - /** - * Enable/disable single stepping for specified thread. - * - * Since this method is currently supported by a small number of - * platforms, we provide a default implementation - * - * \param thread thread to set into single step mode - * \param enable true = enable single-step mode; false = disable - */ - virtual void single_step(Thread_capability, bool) {} + virtual void exception_sigh(Signal_context_capability) = 0; /** * Return affinity space of CPU nodes available to the CPU session @@ -186,17 +111,6 @@ struct Genode::Cpu_session : Session */ virtual Affinity::Space affinity_space() const = 0; - /** - * Define affinity of thread to one or multiple CPU nodes - * - * In the normal case, a thread is assigned to a single CPU. - * Specifying more than one CPU node is supposed to principally - * allow a CPU service to balance the load of threads among - * multiple CPUs. - */ - virtual void affinity(Thread_capability thread, - Affinity::Location affinity) = 0; - /** * Translate generic priority value to kernel-specific priority levels * @@ -234,31 +148,6 @@ struct Genode::Cpu_session : Session */ virtual Dataspace_capability trace_control() = 0; - /** - * Request index of a trace control block for given thread - * - * The trace control dataspace contains the control blocks for - * all threads of the CPU session. Each thread gets assigned a - * different index by the CPU service. - */ - virtual unsigned trace_control_index(Thread_capability thread) = 0; - - /** - * Request trace buffer for the specified thread - * - * The trace buffer is not accounted to the CPU session. It is - * owned by a TRACE session. - */ - virtual Dataspace_capability trace_buffer(Thread_capability thread) = 0; - - /** - * Request trace policy - * - * The trace policy buffer is not accounted to the CPU session. It - * is owned by a TRACE session. - */ - virtual Dataspace_capability trace_policy(Thread_capability thread) = 0; - /** * Define reference account for the CPU session * @@ -329,27 +218,10 @@ struct Genode::Cpu_session : Session GENODE_TYPE_LIST(Thread_creation_failed, Out_of_metadata), Capability, Name const &, Affinity::Location, Weight, addr_t); - GENODE_RPC(Rpc_utcb, Ram_dataspace_capability, utcb, Thread_capability); GENODE_RPC(Rpc_kill_thread, void, kill_thread, Thread_capability); - GENODE_RPC(Rpc_start, int, start, Thread_capability, addr_t, addr_t); - GENODE_RPC(Rpc_pause, void, pause, Thread_capability); - GENODE_RPC(Rpc_resume, void, resume, Thread_capability); - GENODE_RPC(Rpc_cancel_blocking, void, cancel_blocking, Thread_capability); - GENODE_RPC_THROW(Rpc_get_state, Thread_state, state, - GENODE_TYPE_LIST(State_access_failed), - Thread_capability); - GENODE_RPC_THROW(Rpc_set_state, void, state, - GENODE_TYPE_LIST(State_access_failed), - Thread_capability, Thread_state const &); - GENODE_RPC(Rpc_exception_handler, void, exception_handler, - Thread_capability, Signal_context_capability); - GENODE_RPC(Rpc_single_step, void, single_step, Thread_capability, bool); + GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability); GENODE_RPC(Rpc_affinity_space, Affinity::Space, affinity_space); - GENODE_RPC(Rpc_affinity, void, affinity, Thread_capability, Affinity::Location); GENODE_RPC(Rpc_trace_control, Dataspace_capability, trace_control); - GENODE_RPC(Rpc_trace_control_index, unsigned, trace_control_index, Thread_capability); - GENODE_RPC(Rpc_trace_buffer, Dataspace_capability, trace_buffer, Thread_capability); - GENODE_RPC(Rpc_trace_policy, Dataspace_capability, trace_policy, Thread_capability); GENODE_RPC(Rpc_ref_account, int, ref_account, Cpu_session_capability); GENODE_RPC(Rpc_transfer_quota, int, transfer_quota, Cpu_session_capability, size_t); GENODE_RPC(Rpc_quota, Quota, quota); @@ -364,30 +236,19 @@ struct Genode::Cpu_session : Session * of employing the convenience macro 'GENODE_RPC_INTERFACE'. */ typedef Meta::Type_tuple - > > > > > > > > > > > > > > > > > > > > Rpc_functions; + > > > > > > > > Rpc_functions; }; + struct Genode::Cpu_session::Quota { size_t super_period_us; diff --git a/repos/base/include/cpu_thread/capability.h b/repos/base/include/cpu_thread/capability.h new file mode 100644 index 000000000..5298d72e8 --- /dev/null +++ b/repos/base/include/cpu_thread/capability.h @@ -0,0 +1,22 @@ +/* + * \brief Thread capability type + * \author Norman Feske + * \date 2016-05-11 + */ + +/* + * Copyright (C) 2016 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 _INCLUDE__CPU_THREAD__CAPABILITY_H_ +#define _INCLUDE__CPU_THREAD__CAPABILITY_H_ + +#include +#include + +namespace Genode { typedef Capability Cpu_thread_capability; } + +#endif /* _INCLUDE__CPU_THREAD__CAPABILITY_H_ */ diff --git a/repos/base/include/cpu_thread/client.h b/repos/base/include/cpu_thread/client.h new file mode 100644 index 000000000..b3417528c --- /dev/null +++ b/repos/base/include/cpu_thread/client.h @@ -0,0 +1,68 @@ +/* + * \brief Client-side CPU thread interface + * \author Norman Feske + * \date 2016-05-10 + */ + +/* + * Copyright (C) 2016 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 _INCLUDE__CPU_THREAD__CLIENT_H_ +#define _INCLUDE__CPU_THREAD__CLIENT_H_ + +#include +#include + +namespace Genode { struct Cpu_thread_client; } + + +struct Genode::Cpu_thread_client : Rpc_client +{ + explicit Cpu_thread_client(Thread_capability cap) + : Rpc_client(cap) { } + + Dataspace_capability utcb() override { + return call(); } + + void start(addr_t ip, addr_t sp) override { + call(ip, sp); } + + void pause() override { + call(); } + + void resume() override { + call(); } + + void cancel_blocking() override { + call(); } + + Thread_state state() override { + return call(); } + + void state(Thread_state const &state) override { + call(state); } + + void exception_sigh(Signal_context_capability handler) override { + call(handler); } + + void single_step(bool enabled) override { + call(enabled); } + + void affinity(Affinity::Location location) override { + call(location); } + + unsigned trace_control_index() override { + return call(); } + + Dataspace_capability trace_buffer() override { + return call(); } + + Dataspace_capability trace_policy() override { + return call(); } +}; + +#endif /* _INCLUDE__CPU_THREAD__CLIENT_H_ */ diff --git a/repos/base/include/cpu_thread/cpu_thread.h b/repos/base/include/cpu_thread/cpu_thread.h new file mode 100644 index 000000000..4c71ffa6e --- /dev/null +++ b/repos/base/include/cpu_thread/cpu_thread.h @@ -0,0 +1,182 @@ +/* + * \brief CPU thread interface + * \author Norman Feske + * \date 2016-05-10 + */ + +/* + * Copyright (C) 2016 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 _INCLUDE__CPU_THREAD__CPU_THREAD_H_ +#define _INCLUDE__CPU_THREAD__CPU_THREAD_H_ + +#include +#include +#include +#include +#include +#include + +namespace Genode { struct Cpu_thread; } + + +struct Genode::Cpu_thread +{ + class State_access_failed : public Exception { }; + + /** + * Get dataspace of the thread's user-level thread-control block (UTCB) + */ + virtual Dataspace_capability utcb() = 0; + + /** + * Modify instruction and stack pointer of thread - start the thread + * + * \param thread thread to start + * \param ip initial instruction pointer + * \param sp initial stack pointer + */ + virtual void start(addr_t ip, addr_t sp) = 0; + + /** + * Pause the thread + * + * After calling this method, the execution of the thread can be + * continued by calling 'resume'. + */ + virtual void pause() = 0; + + /** + * Resume the thread + */ + virtual void resume() = 0; + + /** + * Cancel a currently blocking operation + */ + virtual void cancel_blocking() = 0; + + /** + * Get the current thread state + * + * \return state of the targeted thread + * \throw State_access_failed + */ + virtual Thread_state state() = 0; + + /** + * Override the current thread state + * + * \param state state that shall be applied + * \throw State_access_failed + */ + virtual void state(Thread_state const &state) = 0; + + /** + * Register signal handler for exceptions of the thread + * + * On Linux, this exception is delivered when the process triggers + * a SIGCHLD. On other platforms, this exception is delivered on + * the occurrence of CPU exceptions such as division by zero. + */ + virtual void exception_sigh(Signal_context_capability handler) = 0; + + /** + * Enable/disable single stepping + * + * Since this method is currently supported by a small number of + * platforms, we provide a default implementation + * + * \param enabled true = enable single-step mode; false = disable + */ + virtual void single_step(bool enabled) = 0; + + /** + * Define affinity of thread to one or multiple CPU nodes + * + * In the normal case, a thread is assigned to a single CPU. Specifying + * more than one CPU node is supposed to principally allow a CPU service to + * balance the load of threads among multiple CPUs. + * + * \param location location within the affinity space of the thread's + * CPU session + */ + virtual void affinity(Affinity::Location location) = 0; + + /** + * Request index within the trace control block of the thread's CPU session + * + * The trace control dataspace contains the control blocks for all threads + * of the CPU session. Each thread gets assigned a different index by the + * CPU service. + */ + virtual unsigned trace_control_index() = 0; + + /** + * Request trace buffer for the thread + * + * The trace buffer is not accounted to the CPU session. It is owned by a + * TRACE session. + */ + virtual Dataspace_capability trace_buffer() = 0; + + /** + * Request trace policy + * + * The trace policy buffer is not accounted to the CPU session. It is owned + * by a TRACE session. + */ + virtual Dataspace_capability trace_policy() = 0; + + + /********************* + ** RPC declaration ** + *********************/ + + GENODE_RPC(Rpc_utcb, Dataspace_capability, utcb); + GENODE_RPC(Rpc_start, void, start, addr_t, addr_t); + GENODE_RPC(Rpc_pause, void, pause); + GENODE_RPC(Rpc_resume, void, resume); + GENODE_RPC(Rpc_cancel_blocking, void, cancel_blocking); + GENODE_RPC_THROW(Rpc_get_state, Thread_state, state, + GENODE_TYPE_LIST(State_access_failed)); + GENODE_RPC_THROW(Rpc_set_state, void, state, + GENODE_TYPE_LIST(State_access_failed), + Thread_state const &); + GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability); + GENODE_RPC(Rpc_single_step, void, single_step, bool); + GENODE_RPC(Rpc_affinity, void, affinity, Affinity::Location); + GENODE_RPC(Rpc_trace_control_index, unsigned, trace_control_index); + GENODE_RPC(Rpc_trace_buffer, Dataspace_capability, trace_buffer); + GENODE_RPC(Rpc_trace_policy, Dataspace_capability, trace_policy); + + /* + * 'GENODE_RPC_INTERFACE' declaration done manually + * + * The number of RPC functions of this interface exceeds the maximum + * number of elements supported by 'Meta::Type_list'. Therefore, we + * construct the type list by hand using nested type tuples instead + * of employing the convenience macro 'GENODE_RPC_INTERFACE'. + */ + typedef Meta::Type_tuple + > > > > > > > > > > > > Rpc_functions; +}; + +#endif /* _INCLUDE__CPU_THREAD__CPU_THREAD_H_ */ diff --git a/repos/base/include/thread/capability.h b/repos/base/include/thread/capability.h index 3f9800901..f67d61413 100644 --- a/repos/base/include/thread/capability.h +++ b/repos/base/include/thread/capability.h @@ -2,6 +2,8 @@ * \brief Thread capability type * \author Norman Feske * \date 2008-08-16 + * + * \deprecated Use cpu_thread/capability.h instead */ /* @@ -14,16 +16,8 @@ #ifndef _INCLUDE__THREAD__CAPABILITY_H_ #define _INCLUDE__THREAD__CAPABILITY_H_ -#include +#include -namespace Genode { - - /* - * The 'Thread_capability' type is created by the CPU session. - * Hence, we use the CPU session's 'Cpu_thread' as association. - */ - class Cpu_thread; - typedef Capability Thread_capability; -} +namespace Genode { typedef Cpu_thread_capability Thread_capability; } #endif /* _INCLUDE__THREAD__CAPABILITY_H_ */ diff --git a/repos/base/src/core/cpu_session_component.cc b/repos/base/src/core/cpu_session_component.cc index 55b195570..8d4f9dd59 100644 --- a/repos/base/src/core/cpu_session_component.cc +++ b/repos/base/src/core/cpu_session_component.cc @@ -27,12 +27,6 @@ using namespace Genode; static constexpr bool verbose = false; -void Cpu_thread_component::update_exception_sigh() -{ - if (platform_thread()->pager()) - platform_thread()->pager()->exception_handler(_sigh); -}; - Thread_capability Cpu_session_component::create_thread(Capability pd_cap, Name const &name, @@ -54,6 +48,7 @@ Thread_capability Cpu_session_component::create_thread(Capability pd name.string(), weight.value, QUOTA_LIMIT); weight = Weight(QUOTA_LIMIT); } + Lock::Guard thread_list_lock_guard(_thread_list_lock); _incr_weight(weight.value); @@ -69,18 +64,18 @@ Thread_capability Cpu_session_component::create_thread(Capability pd thread = new (&_thread_alloc) Cpu_thread_component( cap(), *_thread_ep, *_pager_ep, *pd, _trace_control_area, - weight, _weight_to_quota(weight.value), + _trace_sources, weight, _weight_to_quota(weight.value), _thread_affinity(affinity), _label, thread_name, - _priority, utcb, _default_exception_handler); + _priority, utcb); }; try { _thread_ep->apply(pd_cap, create_thread_lambda); } catch (Region_map::Out_of_metadata) { throw Out_of_metadata(); } catch (Allocator::Out_of_memory) { throw Out_of_metadata(); } - _thread_list.insert(thread); + thread->session_exception_sigh(_exception_sigh); - _trace_sources.insert(thread->trace_source()); + _thread_list.insert(thread); return thread->cap(); } @@ -114,8 +109,6 @@ void Cpu_session_component::_unsynchronized_kill_thread(Thread_capability thread _thread_list.remove(thread); - _trace_sources.remove(thread->trace_source()); - _decr_weight(thread->weight()); { @@ -133,118 +126,14 @@ void Cpu_session_component::kill_thread(Thread_capability thread_cap) } -int Cpu_session_component::start(Thread_capability thread_cap, - addr_t ip, addr_t sp) +void Cpu_session_component::exception_sigh(Signal_context_capability sigh) { - auto lambda = [&] (Cpu_thread_component *thread) { - if (!thread) return -1; + _exception_sigh = sigh; - /* - * If an exception handler was installed prior to the call of 'set_pager', - * we need to update the pager object with the current exception handler. - */ - thread->update_exception_sigh(); + Lock::Guard lock_guard(_thread_list_lock); - return thread->platform_thread()->start((void *)ip, (void *)sp); - }; - return _thread_ep->apply(thread_cap, lambda); -} - - -void Cpu_session_component::pause(Thread_capability thread_cap) -{ - auto lambda = [this] (Cpu_thread_component *thread) { - if (!thread) return; - - thread->platform_thread()->pause(); - }; - _thread_ep->apply(thread_cap, lambda); -} - - -void Cpu_session_component::single_step(Thread_capability thread_cap, bool enabled) -{ - auto lambda = [this, enabled] (Cpu_thread_component *thread) { - if (!thread) return; - - thread->platform_thread()->single_step(enabled); - }; - _thread_ep->apply(thread_cap, lambda); -} - - -void Cpu_session_component::resume(Thread_capability thread_cap) -{ - auto lambda = [this] (Cpu_thread_component *thread) { - if (!thread) return; - - thread->platform_thread()->resume(); - }; - _thread_ep->apply(thread_cap, lambda); -} - - -void Cpu_session_component::cancel_blocking(Thread_capability thread_cap) -{ - auto lambda = [this] (Cpu_thread_component *thread) { - if (!thread) return; - - thread->platform_thread()->cancel_blocking(); - }; - _thread_ep->apply(thread_cap, lambda); -} - - -Thread_state Cpu_session_component::state(Thread_capability thread_cap) -{ - auto lambda = [this] (Cpu_thread_component *thread) { - if (!thread) throw State_access_failed(); - - return thread->platform_thread()->state(); - }; - return _thread_ep->apply(thread_cap, lambda); -} - - -void Cpu_session_component::state(Thread_capability thread_cap, - Thread_state const &state) -{ - auto lambda = [&] (Cpu_thread_component *thread) { - if (!thread) throw State_access_failed(); - - thread->platform_thread()->state(state); - }; - _thread_ep->apply(thread_cap, lambda); -} - - -void -Cpu_session_component::exception_handler(Thread_capability thread_cap, - Signal_context_capability sigh_cap) -{ - /* - * By specifying an invalid thread capability, the caller sets the default - * exception handler for the CPU session. - */ - if (!thread_cap.valid()) { - _default_exception_handler = sigh_cap; - return; - } - - /* - * If an invalid signal handler is specified for a valid thread, we revert - * the signal handler to the CPU session's default signal handler. - */ - if (!sigh_cap.valid()) { - sigh_cap = _default_exception_handler; - } - - auto lambda = [&] (Cpu_thread_component *thread) { - if (!thread) return; - - thread->sigh(sigh_cap); - }; - _thread_ep->apply(thread_cap, lambda); + for (Cpu_thread_component *t = _thread_list.first(); t; t = t->next()) + t->session_exception_sigh(_exception_sigh); } @@ -258,57 +147,12 @@ Affinity::Space Cpu_session_component::affinity_space() const } -void Cpu_session_component::affinity(Thread_capability thread_cap, - Affinity::Location location) -{ - auto lambda = [&] (Cpu_thread_component *thread) { - if (!thread) return; - - thread->affinity(_thread_affinity(location)); - }; - _thread_ep->apply(thread_cap, lambda); -} - - Dataspace_capability Cpu_session_component::trace_control() { return _trace_control_area.dataspace(); } -unsigned Cpu_session_component::trace_control_index(Thread_capability thread_cap) -{ - auto lambda = [] (Cpu_thread_component *thread) -> unsigned { - if (!thread) return 0; - - return thread->trace_control_index(); - }; - return _thread_ep->apply(thread_cap, lambda); -} - - -Dataspace_capability Cpu_session_component::trace_buffer(Thread_capability thread_cap) -{ - auto lambda = [this] (Cpu_thread_component *thread) { - if (!thread) return Dataspace_capability(); - - return thread->trace_source()->buffer(); - }; - return _thread_ep->apply(thread_cap, lambda); -} - - -Dataspace_capability Cpu_session_component::trace_policy(Thread_capability thread_cap) -{ - auto lambda = [this] (Cpu_thread_component *thread) { - if (!thread) return Dataspace_capability(); - - return thread->trace_source()->policy(); - }; - return _thread_ep->apply(thread_cap, lambda); -} - - static size_t remaining_session_ram_quota(char const *args) { /* @@ -472,9 +316,9 @@ void Cpu_session_component::_deinit_threads() void Cpu_session_component:: -_update_thread_quota(Cpu_thread_component * const thread) const +_update_thread_quota(Cpu_thread_component &thread) const { - thread->platform_thread()->quota(_weight_to_quota(thread->weight())); + thread.quota(_weight_to_quota(thread.weight())); } @@ -511,12 +355,11 @@ void Cpu_session_component::_incr_quota(size_t const quota) void Cpu_session_component::_update_each_thread_quota() { Cpu_thread_component * thread = _thread_list.first(); - for (; thread; thread = thread->next()) { _update_thread_quota(thread); } + for (; thread; thread = thread->next()) { _update_thread_quota(*thread); } } -size_t -Cpu_session_component::_weight_to_quota(size_t const weight) const { +size_t Cpu_session_component::_weight_to_quota(size_t const weight) const { return (weight * _quota) / _weight; } diff --git a/repos/base/src/core/cpu_session_support.cc b/repos/base/src/core/cpu_session_support.cc index a5ad4ba19..41debdeb6 100644 --- a/repos/base/src/core/cpu_session_support.cc +++ b/repos/base/src/core/cpu_session_support.cc @@ -14,16 +14,16 @@ /* Genode includes */ #include -/* Core includes */ +/* core includes */ #include using namespace Genode; -Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread_cap) +Dataspace_capability Cpu_thread_component::utcb() { PERR("%s: Not implemented", __PRETTY_FUNCTION__); - return Ram_dataspace_capability(); + return Dataspace_capability(); } diff --git a/repos/base/src/core/cpu_thread_component.cc b/repos/base/src/core/cpu_thread_component.cc new file mode 100644 index 000000000..3265df0aa --- /dev/null +++ b/repos/base/src/core/cpu_thread_component.cc @@ -0,0 +1,113 @@ +/* + * \brief Core implementation of the CPU thread interface + * \author Norman Feske + * \date 2016-05-10 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* core includes */ +#include + +using namespace Genode; + + +void Cpu_thread_component::_update_exception_sigh() +{ + Signal_context_capability sigh = _thread_sigh.valid() + ? _thread_sigh : _session_sigh; + if (_platform_thread.pager()) + _platform_thread.pager()->exception_handler(sigh); +} + + +void Cpu_thread_component::quota(size_t quota) +{ + _platform_thread.quota(quota); +} + + +void Cpu_thread_component::session_exception_sigh(Signal_context_capability sigh) +{ + _session_sigh = sigh; + _update_exception_sigh(); +} + + +void Cpu_thread_component::start(addr_t ip, addr_t sp) +{ + _platform_thread.start((void *)ip, (void *)sp); +} + + +void Cpu_thread_component::pause() +{ + _platform_thread.pause(); +} + + +void Cpu_thread_component::single_step(bool enabled) +{ + _platform_thread.single_step(enabled); +} + + +void Cpu_thread_component::resume() +{ + _platform_thread.resume(); +} + + +void Cpu_thread_component::cancel_blocking() +{ + _platform_thread.cancel_blocking(); +} + + +Thread_state Cpu_thread_component::state() +{ + return _platform_thread.state(); +} + + +void Cpu_thread_component::state(Thread_state const &state) +{ + _platform_thread.state(state); +} + + +void Cpu_thread_component::exception_sigh(Signal_context_capability sigh) +{ + _thread_sigh = sigh; + _update_exception_sigh(); +} + + +void Cpu_thread_component::affinity(Affinity::Location location) +{ + _platform_thread.affinity(location); +} + + +unsigned Cpu_thread_component::trace_control_index() +{ + return _trace_control_slot.index; +} + + +Dataspace_capability Cpu_thread_component::trace_buffer() +{ + return _trace_source.buffer(); +} + + +Dataspace_capability Cpu_thread_component::trace_policy() +{ + return _trace_source.policy(); +} + diff --git a/repos/base/src/core/include/cpu_session_component.h b/repos/base/src/core/include/cpu_session_component.h index ccdeb8720..dc36b0725 100644 --- a/repos/base/src/core/include/cpu_session_component.h +++ b/repos/base/src/core/include/cpu_session_component.h @@ -23,6 +23,7 @@ /* core includes */ #include +#include #include #include #include @@ -30,342 +31,145 @@ #include #include -namespace Genode { - - /** - * RPC interface of CPU thread - * - * We make 'Cpu_thread' a RPC object only to be able to lookup CPU threads - * from thread capabilities supplied as arguments to CPU-session functions. - * A CPU thread does not provide an actual RPC interface. - */ - struct Cpu_thread - { - GENODE_RPC_INTERFACE(); - }; +namespace Genode { class Cpu_session_component; } - class Cpu_thread_component : public Rpc_object, - public List::Element, - public Trace::Source::Info_accessor - { - public: +class Genode::Cpu_session_component : public Rpc_object, + public List::Element +{ + public: - typedef Trace::Session_label Session_label; - typedef Trace::Thread_name Thread_name; + typedef Cpu_thread_component::Session_label Session_label; - private: + private: - Rpc_entrypoint &_ep; - Pager_entrypoint &_pager_ep; - Capability _pd; - Region_map_component &_address_space_region_map; - Cpu_session::Weight const _weight; - Session_label const _session_label; - Thread_name const _name; - Platform_thread _platform_thread; - bool const _bound_to_pd; + Session_label _label; + Rpc_entrypoint * const _session_ep; + Rpc_entrypoint *_thread_ep; + Pager_entrypoint *_pager_ep; + Allocator_guard _md_alloc; /* guarded meta-data allocator */ + Cpu_thread_allocator _thread_alloc; /* meta-data allocator */ + Lock _thread_alloc_lock; /* protect allocator access */ + List _thread_list; + Lock _thread_list_lock; /* protect thread list */ + unsigned _priority; /* priority of threads + created with this + session */ + Affinity::Location _location; /* CPU affinity of this + session */ + Trace::Source_registry &_trace_sources; + Trace::Control_area _trace_control_area; - bool _bind_to_pd(Pd_session_component &pd) - { - if (!pd.bind_thread(_platform_thread)) - throw Cpu_session::Thread_creation_failed(); - return true; - } + /* + * Members for quota accounting + */ - Signal_context_capability _sigh; /* exception handler */ + size_t _weight; + size_t _quota; + Cpu_session_component * _ref; + List _ref_members; + Lock _ref_members_lock; - struct Trace_control_slot - { - unsigned index = 0; - Trace::Control_area &trace_control_area; + Native_cpu_component _native_cpu; - Trace_control_slot(Trace::Control_area &trace_control_area) - : trace_control_area(trace_control_area) - { - if (!trace_control_area.alloc(index)) - throw Cpu_session::Out_of_metadata(); - } + friend class Native_cpu_component; - ~Trace_control_slot() - { - trace_control_area.free(index); - } + /* + * Utilities for quota accounting + */ - Trace::Control &control() - { - return *trace_control_area.at(index); - } - }; + void _incr_weight(size_t const weight); + void _decr_weight(size_t const weight); + size_t _weight_to_quota(size_t const weight) const; + void _decr_quota(size_t const quota); + void _incr_quota(size_t const quota); + void _update_thread_quota(Cpu_thread_component &) const; + void _update_each_thread_quota(); + void _transfer_quota(Cpu_session_component * const dst, + size_t const quota); - Trace_control_slot _trace_control_slot; + void _insert_ref_member(Cpu_session_component * const s) + { + Lock::Guard lock_guard(_ref_members_lock); + _ref_members.insert(s); + s->_ref = this; + } - Trace::Source _trace_source { *this, _trace_control_slot.control() }; + void _unsync_remove_ref_member(Cpu_session_component * const s) + { + s->_ref = 0; + _ref_members.remove(s); + } - Weak_ptr _address_space = _platform_thread.address_space(); + void _remove_ref_member(Cpu_session_component * const s) + { + Lock::Guard lock_guard(_ref_members_lock); + _unsync_remove_ref_member(s); + } - Rm_client _rm_client; + void _deinit_ref_account(); + void _deinit_threads(); - public: + /** + * Exception handler to be invoked unless overridden by a + * thread-specific handler via 'Cpu_thread::exception_sigh' + */ + Signal_context_capability _exception_sigh; - /** - * Constructor - * - * \param ep entrypoint used for managing the thread RPC - * object - * \param pager_ep pager entrypoint used for handling the page - * faults of the thread - * \param pd PD session where the thread is executed - * \param weight scheduling weight relative to the other - * threads of the same CPU session - * \param quota initial quota counter-value of the weight - * \param labal label of the threads session - * \param name name for the thread - * \param priority scheduling priority - * \param utcb user-local UTCB base - * \param sigh initial exception handler - */ - Cpu_thread_component(Cpu_session_capability cpu_session_cap, - Rpc_entrypoint &ep, - Pager_entrypoint &pager_ep, - Pd_session_component &pd, - Trace::Control_area &trace_control_area, - Cpu_session::Weight weight, - size_t quota, - Affinity::Location location, - Session_label const &label, - Thread_name const &name, - unsigned priority, - addr_t utcb, - Signal_context_capability sigh) - : - _ep(ep), _pager_ep(pager_ep), _pd(pd.cap()), - _address_space_region_map(pd.address_space_region_map()), - _weight(weight), - _session_label(label), _name(name), - _platform_thread(quota, name.string(), priority, location, utcb), - _bound_to_pd(_bind_to_pd(pd)), - _sigh(sigh), - _trace_control_slot(trace_control_area), - _rm_client(cpu_session_cap, _ep.manage(this), - &_address_space_region_map, - _platform_thread.pager_object_badge(), - _address_space, _platform_thread.affinity()) - { - update_exception_sigh(); + /** + * Raw thread-killing functionality + * + * This function is called from the 'kill_thread' function and + * the destructor. Each these functions grab the list lock + * by themselves and call this function to perform the actual + * killing. + */ + void _unsynchronized_kill_thread(Thread_capability cap); - _address_space_region_map.add_client(_rm_client); + /** + * Convert session-local affinity location to physical location + */ + Affinity::Location _thread_affinity(Affinity::Location) const; - /* acquaint thread with its pager object */ - _pager_ep.manage(&_rm_client); - _platform_thread.pager(&_rm_client); - } + public: - ~Cpu_thread_component() - { - _pager_ep.dissolve(&_rm_client); - _ep.dissolve(this); + /** + * Constructor + */ + Cpu_session_component(Rpc_entrypoint *session_ep, + Rpc_entrypoint *thread_ep, + Pager_entrypoint *pager_ep, + Allocator *md_alloc, + Trace::Source_registry &trace_sources, + const char *args, Affinity const &affinity, + size_t quota); - _address_space_region_map.remove_client(_rm_client); - } + /** + * Destructor + */ + ~Cpu_session_component(); - void affinity(Affinity::Location affinity) - { - _platform_thread.affinity(affinity); - } + /** + * Register quota donation at allocator guard + */ + void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - /******************************************** - ** Trace::Source::Info_accessor interface ** - ********************************************/ + /*************************** + ** CPU session interface ** + ***************************/ - Trace::Source::Info trace_source_info() const - { - return { _session_label, _name, - _platform_thread.execution_time(), - _platform_thread.affinity() }; - } + Thread_capability create_thread(Capability, Name const &, + Affinity::Location, Weight, addr_t) override; + void kill_thread(Thread_capability) override; + void exception_sigh(Signal_context_capability) override; + Affinity::Space affinity_space() const override; + Dataspace_capability trace_control() override; + int ref_account(Cpu_session_capability c) override; + int transfer_quota(Cpu_session_capability, size_t) override; + Quota quota() override; - - /************************ - ** Accessor functions ** - ************************/ - - Capability pd() const { return _pd; } - - Platform_thread *platform_thread() { return &_platform_thread; } - - Trace::Source *trace_source() { return &_trace_source; } - - size_t weight() const { return _weight.value; } - - void sigh(Signal_context_capability sigh) - { - _sigh = sigh; - update_exception_sigh(); - } - - /** - * Propagate exception handler to platform thread - */ - void update_exception_sigh(); - - /** - * Return index within the CPU-session's trace control area - */ - unsigned trace_control_index() const { return _trace_control_slot.index; } - }; - - - class Cpu_session_component : public Rpc_object, - public List::Element - { - public: - - typedef Cpu_thread_component::Session_label Session_label; - - private: - - Session_label _label; - Rpc_entrypoint * const _session_ep; - Rpc_entrypoint *_thread_ep; - Pager_entrypoint *_pager_ep; - Allocator_guard _md_alloc; /* guarded meta-data allocator */ - Cpu_thread_allocator _thread_alloc; /* meta-data allocator */ - Lock _thread_alloc_lock; /* protect allocator access */ - List _thread_list; - Lock _thread_list_lock; /* protect thread list */ - unsigned _priority; /* priority of threads - created with this - session */ - Affinity::Location _location; /* CPU affinity of this - session */ - Trace::Source_registry &_trace_sources; - Trace::Control_area _trace_control_area; - - /* - * Members for quota accounting - */ - - size_t _weight; - size_t _quota; - Cpu_session_component * _ref; - List _ref_members; - Lock _ref_members_lock; - - Native_cpu_component _native_cpu; - - friend class Native_cpu_component; - - /* - * Utilities for quota accounting - */ - - void _incr_weight(size_t const weight); - void _decr_weight(size_t const weight); - size_t _weight_to_quota(size_t const weight) const; - void _decr_quota(size_t const quota); - void _incr_quota(size_t const quota); - void _update_thread_quota(Cpu_thread_component *) const; - void _update_each_thread_quota(); - void _transfer_quota(Cpu_session_component * const dst, - size_t const quota); - - void _insert_ref_member(Cpu_session_component * const s) - { - Lock::Guard lock_guard(_ref_members_lock); - _ref_members.insert(s); - s->_ref = this; - } - - void _unsync_remove_ref_member(Cpu_session_component * const s) - { - s->_ref = 0; - _ref_members.remove(s); - } - - void _remove_ref_member(Cpu_session_component * const s) - { - Lock::Guard lock_guard(_ref_members_lock); - _unsync_remove_ref_member(s); - } - - void _deinit_ref_account(); - void _deinit_threads(); - - /** - * Exception handler that will be invoked unless overridden by a - * call of 'Cpu_session::exception_handler'. - */ - Signal_context_capability _default_exception_handler; - - /** - * Raw thread-killing functionality - * - * This function is called from the 'kill_thread' function and - * the destructor. Each these functions grab the list lock - * by themselves and call this function to perform the actual - * killing. - */ - void _unsynchronized_kill_thread(Thread_capability cap); - - /** - * Convert session-local affinity location to physical location - */ - Affinity::Location _thread_affinity(Affinity::Location) const; - - public: - - /** - * Constructor - */ - Cpu_session_component(Rpc_entrypoint *session_ep, - Rpc_entrypoint *thread_ep, - Pager_entrypoint *pager_ep, - Allocator *md_alloc, - Trace::Source_registry &trace_sources, - const char *args, Affinity const &affinity, - size_t quota); - - /** - * Destructor - */ - ~Cpu_session_component(); - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - - - /*************************** - ** CPU session interface ** - ***************************/ - - Thread_capability create_thread(Capability, Name const &, - Affinity::Location, Weight, addr_t) override; - Ram_dataspace_capability utcb(Thread_capability thread) override; - void kill_thread(Thread_capability) override; - int start(Thread_capability, addr_t, addr_t) override; - void pause(Thread_capability thread_cap) override; - void resume(Thread_capability thread_cap) override; - void single_step(Thread_capability thread_cap, bool enable) override; - void cancel_blocking(Thread_capability) override; - Thread_state state(Thread_capability) override; - void state(Thread_capability, Thread_state const &) override; - void exception_handler(Thread_capability, Signal_context_capability) override; - Affinity::Space affinity_space() const override; - void affinity(Thread_capability, Affinity::Location) override; - Dataspace_capability trace_control() override; - unsigned trace_control_index(Thread_capability) override; - Dataspace_capability trace_buffer(Thread_capability) override; - Dataspace_capability trace_policy(Thread_capability) override; - int ref_account(Cpu_session_capability c) override; - int transfer_quota(Cpu_session_capability, size_t) override; - Quota quota() override; - - Capability native_cpu() override { return _native_cpu.cap(); } - }; -} + Capability native_cpu() override { return _native_cpu.cap(); } +}; #endif /* _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_ */ diff --git a/repos/base/src/core/include/cpu_thread_component.h b/repos/base/src/core/include/cpu_thread_component.h new file mode 100644 index 000000000..13ac0939c --- /dev/null +++ b/repos/base/src/core/include/cpu_thread_component.h @@ -0,0 +1,224 @@ +/* + * \brief CPU thread RPC object + * \author Norman Feske + * \date 2016-05-10 + */ + +/* + * Copyright (C) 2016 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__CPU_THREAD_COMPONENT_H_ +#define _CORE__INCLUDE__CPU_THREAD_COMPONENT_H_ + +/* Genode includes */ +#include +#include +#include + +/* core includes */ +#include +#include +#include +#include +#include +#include + +namespace Genode { class Cpu_thread_component; } + + +class Genode::Cpu_thread_component : public Rpc_object, + public List::Element, + public Trace::Source::Info_accessor +{ + public: + + typedef Trace::Session_label Session_label; + typedef Trace::Thread_name Thread_name; + + private: + + Rpc_entrypoint &_ep; + Pager_entrypoint &_pager_ep; + Capability _pd; + Region_map_component &_address_space_region_map; + Cpu_session::Weight const _weight; + Session_label const _session_label; + Thread_name const _name; + Platform_thread _platform_thread; + bool const _bound_to_pd; + + bool _bind_to_pd(Pd_session_component &pd) + { + if (!pd.bind_thread(_platform_thread)) + throw Cpu_session::Thread_creation_failed(); + return true; + } + + /** + * Exception handler as defined by 'Cpu_session::exception_sigh' + */ + Signal_context_capability _session_sigh; + + /** + * Exception handler as defined by 'Cpu_thread::exception_sigh' + */ + Signal_context_capability _thread_sigh; + + struct Trace_control_slot + { + unsigned index = 0; + Trace::Control_area &trace_control_area; + + Trace_control_slot(Trace::Control_area &trace_control_area) + : trace_control_area(trace_control_area) + { + if (!trace_control_area.alloc(index)) + throw Cpu_session::Out_of_metadata(); + } + + ~Trace_control_slot() + { + trace_control_area.free(index); + } + + Trace::Control &control() + { + return *trace_control_area.at(index); + } + }; + + Trace_control_slot _trace_control_slot; + + Trace::Source _trace_source { *this, _trace_control_slot.control() }; + + Trace::Source_registry &_trace_sources; + + Weak_ptr _address_space = _platform_thread.address_space(); + + Rm_client _rm_client; + + /** + * Propagate exception handler to platform thread + */ + void _update_exception_sigh(); + + public: + + /** + * Constructor + * + * \param ep entrypoint used for managing the thread RPC + * object + * \param pager_ep pager entrypoint used for handling the page + * faults of the thread + * \param pd PD session where the thread is executed + * \param weight scheduling weight relative to the other + * threads of the same CPU session + * \param quota initial quota counter-value of the weight + * \param labal label of the threads session + * \param name name for the thread + * \param priority scheduling priority + * \param utcb user-local UTCB base + */ + Cpu_thread_component(Cpu_session_capability cpu_session_cap, + Rpc_entrypoint &ep, + Pager_entrypoint &pager_ep, + Pd_session_component &pd, + Trace::Control_area &trace_control_area, + Trace::Source_registry &trace_sources, + Cpu_session::Weight weight, + size_t quota, + Affinity::Location location, + Session_label const &label, + Thread_name const &name, + unsigned priority, + addr_t utcb) + : + _ep(ep), _pager_ep(pager_ep), _pd(pd.cap()), + _address_space_region_map(pd.address_space_region_map()), + _weight(weight), + _session_label(label), _name(name), + _platform_thread(quota, name.string(), priority, location, utcb), + _bound_to_pd(_bind_to_pd(pd)), + _trace_control_slot(trace_control_area), + _trace_sources(trace_sources), + _rm_client(cpu_session_cap, _ep.manage(this), + &_address_space_region_map, + _platform_thread.pager_object_badge(), + _address_space, _platform_thread.affinity()) + { + _address_space_region_map.add_client(_rm_client); + + /* acquaint thread with its pager object */ + _pager_ep.manage(&_rm_client); + _platform_thread.pager(&_rm_client); + _trace_sources.insert(&_trace_source); + } + + ~Cpu_thread_component() + { + _trace_sources.remove(&_trace_source); + _pager_ep.dissolve(&_rm_client); + _ep.dissolve(this); + + _address_space_region_map.remove_client(_rm_client); + } + + + /******************************************** + ** Trace::Source::Info_accessor interface ** + ********************************************/ + + Trace::Source::Info trace_source_info() const + { + return { _session_label, _name, + _platform_thread.execution_time(), + _platform_thread.affinity() }; + } + + + /************************ + ** Accessor functions ** + ************************/ + + /** + * Define default exception handler installed for the CPU session + */ + void session_exception_sigh(Signal_context_capability); + + Capability pd() const { return _pd; } + + void quota(size_t); + + /* + * Called by platform-specific 'Native_cpu' operations + */ + Platform_thread &platform_thread() { return _platform_thread; } + + size_t weight() const { return _weight.value; } + + + /************************** + ** CPU thread interface ** + *************************/ + + Dataspace_capability utcb() override; + void start(addr_t, addr_t) override; + void pause() override; + void resume() override; + void single_step(bool) override; + void cancel_blocking() override; + Thread_state state() override; + void state(Thread_state const &) override; + void exception_sigh(Signal_context_capability) override; + void affinity(Affinity::Location) override; + unsigned trace_control_index() override; + Dataspace_capability trace_buffer() override; + Dataspace_capability trace_policy() override; +}; + +#endif /* _CORE__INCLUDE__CPU_THREAD_COMPONENT_H_ */ diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index a6affd2d8..f81caf514 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -125,6 +125,8 @@ class Core_child : public Child_policy Ram_session_client _ram; Cpu_session_client _cpu; + Child::Initial_thread _initial_thread { _cpu, _pd, "name" }; + Region_map_client _address_space; Child _child; @@ -139,11 +141,11 @@ class Core_child : public Child_policy Cpu_session_capability cpu, Service_registry &services) : - _entrypoint(nullptr, STACK_SIZE, "init", false), + _entrypoint(nullptr, STACK_SIZE, "name", false), _local_services(services), _pd(pd), _ram(ram), _cpu(cpu), _address_space(Pd_session_client(pd).address_space()), - _child(elf_ds, _ldso_ds, _pd, _pd, _ram, _ram, _cpu, _cpu, + _child(elf_ds, _ldso_ds, _pd, _pd, _ram, _ram, _cpu, _initial_thread, *env()->rm_session(), _address_space, _entrypoint, *this, *_local_services.find(Pd_session::service_name()), *_local_services.find(Ram_session::service_name()), diff --git a/repos/base/src/lib/base/child.cc b/repos/base/src/lib/base/child.cc index 3feb66e79..fb248939e 100644 --- a/repos/base/src/lib/base/child.cc +++ b/repos/base/src/lib/base/child.cc @@ -445,7 +445,7 @@ void Child::exit(int exit_value) Thread_capability Child::main_thread_cap() const { - return _process.initial_thread.cap; + return _process.initial_thread.cap(); } @@ -482,7 +482,7 @@ Child::Child(Dataspace_capability elf_ds, Ram_session_capability ram_cap, Ram_session &ram, Cpu_session_capability cpu_cap, - Cpu_session &cpu, + Initial_thread_base &initial_thread, Region_map &local_rm, Region_map &remote_rm, Rpc_entrypoint &entrypoint, @@ -500,8 +500,8 @@ try : _parent_cap(_entrypoint.manage(this)), _policy(policy), _server(_ram), - _process(elf_ds, ldso_ds, pd_cap, pd, ram, cpu, local_rm, remote_rm, - _parent_cap, policy.name()) + _process(elf_ds, ldso_ds, pd_cap, pd, ram, initial_thread, local_rm, remote_rm, + _parent_cap) { } catch (Cpu_session::Thread_creation_failed) { throw Process_startup_failed(); } catch (Cpu_session::Out_of_metadata) { throw Process_startup_failed(); } diff --git a/repos/base/src/lib/base/child_process.cc b/repos/base/src/lib/base/child_process.cc index f181030e2..7d0d46d8d 100644 --- a/repos/base/src/lib/base/child_process.cc +++ b/repos/base/src/lib/base/child_process.cc @@ -15,6 +15,7 @@ /* Genode includes */ #include #include +#include /* base-internal includes */ #include @@ -162,18 +163,24 @@ Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds } -Child::Process::Initial_thread::Initial_thread(Cpu_session &cpu, - Pd_session_capability pd, - char const *name) +Child::Initial_thread::Initial_thread(Cpu_session &cpu, + Pd_session_capability pd, + Name const &name) : - cpu(cpu), - cap(cpu.create_thread(pd, name, Affinity::Location(), Cpu_session::Weight())) + _cpu(cpu), + _cap(cpu.create_thread(pd, name, Affinity::Location(), Cpu_session::Weight())) { } -Child::Process::Initial_thread::~Initial_thread() +Child::Initial_thread::~Initial_thread() { - cpu.kill_thread(cap); + _cpu.kill_thread(_cap); +} + + +void Child::Initial_thread::start(addr_t ip) +{ + Cpu_thread_client(_cap).start(ip, 0); } @@ -182,13 +189,12 @@ Child::Process::Process(Dataspace_capability elf_ds, Pd_session_capability pd_cap, Pd_session &pd, Ram_session &ram, - Cpu_session &cpu, + Initial_thread_base &initial_thread, Region_map &local_rm, Region_map &remote_rm, - Parent_capability parent_cap, - char const *name) + Parent_capability parent_cap) : - initial_thread(cpu, pd_cap, name), + initial_thread(initial_thread), loaded_executable(elf_ds, ldso_ds, ram, local_rm, remote_rm, parent_cap) { /* register parent interface for new protection domain */ @@ -203,10 +209,7 @@ Child::Process::Process(Dataspace_capability elf_ds, return; /* start main thread */ - if (cpu.start(initial_thread.cap, loaded_executable.entry, 0)) { - PERR("start of initial thread failed"); - throw Cpu_session::Thread_creation_failed(); - } + initial_thread.start(loaded_executable.entry); } diff --git a/repos/base/src/lib/base/thread_start.cc b/repos/base/src/lib/base/thread_start.cc index 824426bd6..80b19baf0 100644 --- a/repos/base/src/lib/base/thread_start.cc +++ b/repos/base/src/lib/base/thread_start.cc @@ -16,6 +16,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -62,11 +63,11 @@ void Thread::start() throw Cpu_session::Thread_creation_failed(); /* start execution at initial instruction pointer and stack pointer */ - _cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top()); + Cpu_thread_client(_thread_cap).start((addr_t)_thread_start, _stack->top()); } void Thread::cancel_blocking() { - _cpu_session->cancel_blocking(_thread_cap); + Cpu_thread_client(_thread_cap).cancel_blocking(); } diff --git a/repos/base/src/lib/base/trace.cc b/repos/base/src/lib/base/trace.cc index 19e9a577a..ddaf8473e 100644 --- a/repos/base/src/lib/base/trace.cc +++ b/repos/base/src/lib/base/trace.cc @@ -17,6 +17,7 @@ #include #include #include +#include /* local includes */ #include @@ -74,7 +75,7 @@ bool Trace::Logger::_evaluate_control() Control::Inhibit_guard guard(*control); /* obtain policy */ - Dataspace_capability policy_ds = cpu->trace_policy(thread_cap); + Dataspace_capability policy_ds = Cpu_thread_client(thread_cap).trace_policy(); if (!policy_ds.valid()) { PWRN("could not obtain trace policy"); @@ -100,7 +101,7 @@ bool Trace::Logger::_evaluate_control() /* obtain buffer */ buffer = 0; - Dataspace_capability buffer_ds = cpu->trace_buffer(thread_cap); + Dataspace_capability buffer_ds = Cpu_thread_client(thread_cap).trace_buffer(); if (!buffer_ds.valid()) { PWRN("could not obtain trace buffer"); @@ -139,7 +140,7 @@ void Trace::Logger::init(Thread_capability thread, Cpu_session *cpu_session, thread_cap = thread; cpu = cpu_session; - unsigned const index = cpu->trace_control_index(thread); + unsigned const index = Cpu_thread_client(thread).trace_control_index(); Dataspace_capability ds = cpu->trace_control(); size_t size = Dataspace_client(ds).size(); if ((index + 1)*sizeof(Trace::Control) > size) { diff --git a/repos/base/src/test/fpu/main.cc b/repos/base/src/test/fpu/main.cc index 37ee424b9..93da62ea4 100644 --- a/repos/base/src/test/fpu/main.cc +++ b/repos/base/src/test/fpu/main.cc @@ -39,7 +39,7 @@ class Sync_signal_transmitter : public Signal_transmitter } }; -class Fpu_user : public Thread_deprecated<4 * 1024> +class Fpu_user : public Thread_deprecated<0x2000> { private: diff --git a/repos/base/src/test/rm_fault/main.cc b/repos/base/src/test/rm_fault/main.cc index 831290182..dfae84381 100644 --- a/repos/base/src/test/rm_fault/main.cc +++ b/repos/base/src/test/rm_fault/main.cc @@ -79,10 +79,11 @@ class Test_child : public Child_policy */ Rpc_entrypoint _entrypoint; - Region_map_client _address_space; - Pd_session_client _pd; - Ram_session_client _ram; - Cpu_session_client _cpu; + Region_map_client _address_space; + Pd_session_client _pd; + Ram_session_client _ram; + Cpu_session_client _cpu; + Child::Initial_thread _initial_thread; Child _child; @@ -101,8 +102,9 @@ class Test_child : public Child_policy : _entrypoint(cap, STACK_SIZE, "child", false), _address_space(pd.address_space()), _pd(pd), _ram(ram), _cpu(cpu), + _initial_thread(_cpu, _pd, "child"), _child(elf_ds, Dataspace_capability(), _pd, _pd, _ram, _ram, - _cpu, _cpu, *env()->rm_session(), _address_space, + _cpu, _initial_thread, *env()->rm_session(), _address_space, _entrypoint, *this), _log_service("LOG") { diff --git a/repos/base/src/test/thread/main.cc b/repos/base/src/test/thread/main.cc index 3ce08e756..ae359faf8 100644 --- a/repos/base/src/test/thread/main.cc +++ b/repos/base/src/test/thread/main.cc @@ -21,6 +21,7 @@ #include #include #include +#include using namespace Genode; @@ -259,16 +260,17 @@ static void test_pause_resume(Env &env) while (thread.loop < 1) { } Thread_state state; + Cpu_thread_client thread_client(thread.cap()); log("--- pausing ---"); - env.cpu().pause(thread.cap()); + thread_client.pause(); unsigned loop_paused = thread.loop; log("--- paused ---"); log("--- reading thread state ---"); try { - state = env.cpu().state(thread.cap()); - } catch (Cpu_session::State_access_failed) { + state = thread_client.state(); + } catch (Cpu_thread::State_access_failed) { throw -10; } if (loop_paused != thread.loop) @@ -276,7 +278,7 @@ static void test_pause_resume(Env &env) thread.beep = true; log("--- resuming thread ---"); - env.cpu().resume(thread.cap()); + thread_client.resume(); while (thread.loop == loop_paused) { } diff --git a/repos/demo/include/launchpad/launchpad.h b/repos/demo/include/launchpad/launchpad.h index 306cfd9ce..1d1762bd8 100644 --- a/repos/demo/include/launchpad/launchpad.h +++ b/repos/demo/include/launchpad/launchpad.h @@ -171,6 +171,8 @@ class Launchpad_child : public Genode::List::Element Genode::Ram_session_client _ram; Genode::Cpu_session_client _cpu; + Genode::Child::Initial_thread _initial_thread; + Genode::Server _server; Launchpad_child_policy _policy; @@ -193,12 +195,13 @@ class Launchpad_child : public Genode::List::Element _launchpad(launchpad), _entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false), _address_space(Genode::Pd_session_client(pd).address_space()), - _rom(rom), _pd(pd), _ram(ram), _cpu(cpu), _server(_ram), + _rom(rom), _pd(pd), _ram(ram), _cpu(cpu), + _initial_thread(_cpu, _pd, name), _server(_ram), _policy(name, &_server, parent_services, child_services, config_ds, elf_ds, &_entrypoint), - _child(elf_ds, _ldso_ds(), _pd, _pd, _ram, _ram, _cpu, _cpu, - *Genode::env()->rm_session(), _address_space, - _entrypoint, _policy) + _child(elf_ds, _ldso_ds(), _pd, _pd, _ram, _ram, _cpu, + _initial_thread, *Genode::env()->rm_session(), + _address_space, _entrypoint, _policy) { _entrypoint.activate(); } diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h index 5f3704004..f9dad23f4 100644 --- a/repos/os/include/cli_monitor/child.h +++ b/repos/os/include/cli_monitor/child.h @@ -48,6 +48,9 @@ class Child_base : public Genode::Child_policy Label const _label; + size_t _ram_quota; + size_t _ram_limit; + struct Resources { Genode::Pd_connection pd; @@ -65,11 +68,11 @@ class Child_base : public Genode::Child_policy if (Genode::env()->ram_session()->transfer_quota(ram.cap(), ram_quota) != 0) throw Quota_exceeded(); } - }; + } _resources; + + Genode::Child::Initial_thread _initial_thread { _resources.cpu, _resources.pd, + _label.string() }; - size_t _ram_quota; - size_t _ram_limit; - Resources _resources; Genode::Region_map_client _address_space { _resources.pd.address_space() }; Genode::Service_registry _parent_services; Genode::Rom_connection _binary_rom; @@ -122,7 +125,7 @@ class Child_base : public Genode::Child_policy _binary_policy("binary", _binary_rom.dataspace(), &_entrypoint), _config_policy("config", _entrypoint, &_resources.ram), _child(_binary_rom.dataspace(), ldso_ds, _resources.pd, _resources.pd, - _resources.ram, _resources.ram, _resources.cpu, _resources.cpu, + _resources.ram, _resources.ram, _resources.cpu, _initial_thread, *Genode::env()->rm_session(), _address_space, _entrypoint, *this), _yield_response_sigh_cap(yield_response_sig_cap), diff --git a/repos/os/include/init/child.h b/repos/os/include/init/child.h index 5c8fb9144..e05d40272 100644 --- a/repos/os/include/init/child.h +++ b/repos/os/include/init/child.h @@ -501,6 +501,8 @@ class Init::Child : Genode::Child_policy } } _resources; + Genode::Child::Initial_thread _initial_thread { _resources.cpu, _resources.pd, + _name.unique }; /* * Entry point used for serving the parent interface and the * locally provided ROM sessions for the 'config' and 'binary' @@ -559,7 +561,8 @@ class Init::Child : Genode::Child_policy _name(start_node, name_registry), _resources(start_node, _name.unique, prio_levels, affinity_space), - _entrypoint(&cap_session, ENTRYPOINT_STACK_SIZE, _name.unique, false, _resources.affinity.location()), + _entrypoint(&cap_session, ENTRYPOINT_STACK_SIZE, _name.unique, false, + _resources.affinity.location()), _binary_rom(_name.file, _name.file), _binary_rom_ds(_binary_rom.dataspace()), _config(_resources.ram.cap(), start_node), @@ -567,7 +570,7 @@ class Init::Child : Genode::Child_policy _child(_binary_rom_ds, ldso_ds, _resources.pd, _resources.pd, _resources.ram, _resources.ram, - _resources.cpu, _resources.cpu, + _resources.cpu, _initial_thread, *Genode::env()->rm_session(), _address_space, _entrypoint, *this), _parent_services(parent_services), _child_services(child_services), diff --git a/repos/os/include/os/slave.h b/repos/os/include/os/slave.h index ef1fbdd27..c75940074 100644 --- a/repos/os/include/os/slave.h +++ b/repos/os/include/os/slave.h @@ -176,9 +176,10 @@ class Genode::Slave if (ram_ref.transfer_quota(ram.cap(), ram_quota)) throw Quota_exceeded(); } - }; + } _resources; + + Genode::Child::Initial_thread _initial_thread; - Resources _resources; Genode::Region_map_client _address_space { _resources.pd.address_space() }; Genode::Child _child; @@ -191,8 +192,9 @@ class Genode::Slave Dataspace_capability ldso_ds = Dataspace_capability()) : _resources(slave_policy.name(), ram_quota, ram_ref_cap), + _initial_thread(_resources.cpu, _resources.pd, slave_policy.name()), _child(slave_policy.binary(), ldso_ds, _resources.pd, _resources.pd, - _resources.ram, _resources.ram, _resources.cpu, _resources.cpu, + _resources.ram, _resources.ram, _resources.cpu, _initial_thread, *env()->rm_session(), _address_space, entrypoint, slave_policy) { } diff --git a/repos/os/src/server/loader/child.h b/repos/os/src/server/loader/child.h index a5650d52d..17ca98dfb 100644 --- a/repos/os/src/server/loader/child.h +++ b/repos/os/src/server/loader/child.h @@ -33,10 +33,9 @@ namespace Loader { { private: - struct Label { - char string[Session::Name::MAX_SIZE]; - Label(char const *l) { strncpy(string, l, sizeof(string)); } - } _label; + typedef String Label; + + Label _label; Rpc_entrypoint &_ep; @@ -67,12 +66,16 @@ namespace Loader { * Install CPU exception and RM fault handler assigned by * the loader client via 'Loader_session::fault_handler'. */ - cpu.exception_handler(Thread_capability(), fault_sigh); + cpu.exception_sigh(fault_sigh); Region_map_client address_space(pd.address_space()); address_space.fault_handler(fault_sigh); } } _resources; + Genode::Child::Initial_thread _initial_thread { _resources.cpu, + _resources.pd, + _label.string() }; + Region_map_client _address_space { _resources.pd.address_space() }; Service_registry &_parent_services; @@ -117,7 +120,7 @@ namespace Loader { : _label(label), _ep(ep), - _resources(_label.string, ram_session_client, ram_quota, fault_sigh), + _resources(_label.string(), ram_session_client, ram_quota, fault_sigh), _parent_services(parent_services), _local_nitpicker_service(local_nitpicker_service), _local_rom_service(local_rom_service), @@ -125,11 +128,11 @@ namespace Loader { _local_pd_service(local_pd_service), _binary_rom_session(_rom_session(binary_name)), _binary_policy("binary", _binary_rom_session.dataspace(), &_ep), - _labeling_policy(_label.string), + _labeling_policy(_label.string()), _child(_binary_rom_session.dataspace(), ldso_ds, _resources.pd, _resources.pd, _resources.ram, _resources.ram, - _resources.cpu, _resources.cpu, + _resources.cpu, _initial_thread, *env()->rm_session(), _address_space, _ep, *this) { } @@ -143,15 +146,15 @@ namespace Loader { ** Child-policy interface ** ****************************/ - char const *name() const { return _label.string; } + char const *name() const override { return _label.string(); } - void filter_session_args(char const *service, char *args, size_t args_len) + void filter_session_args(char const *service, char *args, size_t args_len) override { _labeling_policy.filter_session_args(service, args, args_len); } Service *resolve_session_request(const char *name, - const char *args) + const char *args) override { Service *service = 0; diff --git a/repos/os/src/server/loader/main.cc b/repos/os/src/server/loader/main.cc index 3d43ee60e..5d9fa6687 100644 --- a/repos/os/src/server/loader/main.cc +++ b/repos/os/src/server/loader/main.cc @@ -156,7 +156,7 @@ class Loader::Session_component : public Rpc_object Affinity const &affinity) { Capability cap = env()->parent()->session(args, affinity); - Cpu_session_client(cap).exception_handler(Thread_capability(), fault_sigh); + Cpu_session_client(cap).exception_sigh(fault_sigh); return cap; } diff --git a/repos/os/src/test/bomb/main.cc b/repos/os/src/test/bomb/main.cc index fa77a6b71..a8da82b68 100644 --- a/repos/os/src/test/bomb/main.cc +++ b/repos/os/src/test/bomb/main.cc @@ -42,16 +42,17 @@ class Bomb_child_resources Genode::Rom_connection _rom; Genode::Ram_connection _ram; Genode::Cpu_connection _cpu; - char _name[32]; + + typedef String<32> Name; + Name _name; Genode::Region_map_client _address_space { _pd.address_space() }; Bomb_child_resources(const char *file_name, const char *name, Genode::size_t ram_quota) - : _pd(name), _rom(file_name, name), _ram(name), _cpu(name) + : + _pd(name), _rom(file_name, name), _ram(name), _cpu(name), _name(name) { - Genode::strncpy(_name, name, sizeof(_name)); - _ram.ref_account(env()->ram_session_cap()); Genode::env()->ram_session()->transfer_quota(_ram.cap(), ram_quota); @@ -65,11 +66,14 @@ class Bomb_child_resources class Bomb_child : private Bomb_child_resources, public Genode::Child_policy, - private Init::Child_policy_enforce_labeling, public Genode::List::Element { private: + Init::Child_policy_enforce_labeling _enforce_labeling_policy; + + Genode::Child::Initial_thread _initial_thread; + /* * Entry point used for serving the parent interface */ @@ -90,10 +94,11 @@ class Bomb_child : private Bomb_child_resources, unsigned generation) : Bomb_child_resources(file_name, unique_name, ram_quota), - Init::Child_policy_enforce_labeling(Bomb_child_resources::_name), + _enforce_labeling_policy(_name.string()), + _initial_thread(_cpu, _pd, unique_name), _entrypoint(cap_session, STACK_SIZE, "bomb_ep_child", false), _child(_rom.dataspace(), Genode::Dataspace_capability(), - _pd, _pd, _ram, _ram, _cpu, _cpu, + _pd, _pd, _ram, _ram, _cpu, _initial_thread, *Genode::env()->rm_session(), _address_space, _entrypoint, *this), _parent_services(parent_services), _config_policy("config", _entrypoint, &_ram) @@ -113,11 +118,11 @@ class Bomb_child : private Bomb_child_resources, ** Child-policy interface ** ****************************/ - const char *name() const { return Bomb_child_resources::_name; } + const char *name() const { return Bomb_child_resources::_name.string(); } void filter_session_args(const char * x, char *args, Genode::size_t args_len) { - Child_policy_enforce_labeling::filter_session_args(0, args, args_len); + _enforce_labeling_policy.filter_session_args(0, args, args_len); } Service *resolve_session_request(const char *service_name, diff --git a/repos/os/src/test/fault_detection/main.cc b/repos/os/src/test/fault_detection/main.cc index 28bbb4e6d..0b0b9d394 100644 --- a/repos/os/src/test/fault_detection/main.cc +++ b/repos/os/src/test/fault_detection/main.cc @@ -68,7 +68,7 @@ class Test_child : public Genode::Child_policy env()->ram_session()->transfer_quota(ram.cap(), CHILD_QUOTA); /* register default exception handler */ - cpu.exception_handler(Thread_capability(), sigh); + cpu.exception_sigh(sigh); /* register handler for unresolvable page faults */ Region_map_client address_space(pd.address_space()); @@ -76,6 +76,8 @@ class Test_child : public Genode::Child_policy } } _resources; + Genode::Child::Initial_thread _initial_thread; + /* * The order of the following members is important. The services must * appear before the child to ensure the correct order of destruction. @@ -99,12 +101,13 @@ class Test_child : public Genode::Child_policy Genode::Signal_context_capability sigh) : _resources(sigh, elf_name), + _initial_thread(_resources.cpu, _resources.pd, elf_name), _elf(elf_name), _log_service("LOG"), _rm_service("RM"), _child(_elf.dataspace(), Genode::Dataspace_capability(), _resources.pd, _resources.pd, _resources.ram, _resources.ram, - _resources.cpu, _resources.cpu, + _resources.cpu, _initial_thread, *Genode::env()->rm_session(), _address_space, ep, *this) { } diff --git a/repos/os/src/test/vfs_stress/main.cc b/repos/os/src/test/vfs_stress/main.cc index d59c161e9..30050497e 100644 --- a/repos/os/src/test/vfs_stress/main.cc +++ b/repos/os/src/test/vfs_stress/main.cc @@ -40,6 +40,7 @@ #include #include #include +#include using namespace Genode; @@ -149,7 +150,7 @@ struct Stress_thread : public Genode::Thread_deprecated<4*1024*sizeof(Genode::ad Stress_thread(Vfs::File_system &vfs, char const *parent, Affinity::Location affinity) : Thread_deprecated(parent), path(parent), count(0), vfs(vfs) { - env()->cpu_session()->affinity(cap(), affinity); + Cpu_thread_client(cap()).affinity(affinity); } }; diff --git a/repos/ports-foc/src/lib/l4lx/include/vcpu.h b/repos/ports-foc/src/lib/l4lx/include/vcpu.h index 661d410f5..8ac17beb6 100644 --- a/repos/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/repos/ports-foc/src/lib/l4lx/include/vcpu.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -62,7 +63,7 @@ namespace L4lx { _data(data ? *data : 0), _vcpu_state(vcpu_state), _cpu_nr(cpu_nr), - _utcb((Fiasco::l4_utcb_t *)_cpu_session->state(cap()).utcb) + _utcb((Fiasco::l4_utcb_t *)Genode::Cpu_thread_client(cap()).state().utcb) { start(); @@ -95,8 +96,7 @@ namespace L4lx { void set_affinity(unsigned i) { - cpu_connection()->affinity(_thread_cap, - Genode::Affinity::Location(i, 0)); + Genode::Cpu_thread_client(_thread_cap).affinity(Genode::Affinity::Location(i, 0)); } }; diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index dcfdf24b0..7a7d5bf57 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -23,6 +23,7 @@ #include #include #include +#include /* NOVA includes */ #include @@ -76,7 +77,9 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread state.sel_exc_base = Native_thread::INVALID_INDEX; state.is_vcpu = true; - _cpu_session->state(vcpu_vm, state); + Cpu_thread_client cpu_thread(vcpu_vm); + + cpu_thread.state(state); /* obtain interface to NOVA-specific CPU session operations */ Nova_native_cpu_client native_cpu(_cpu_session->native_cpu()); @@ -91,7 +94,7 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread delegate_vcpu_portals(pager_cap, exc_base()); /* start vCPU in separate PD */ - _cpu_session->start(vcpu_vm, 0, 0); + cpu_thread.start(0, 0); /* * Request native EC thread cap and put it next to the diff --git a/repos/ports/src/app/gdb_monitor/app_child.h b/repos/ports/src/app/gdb_monitor/app_child.h index 9a2892f6f..9bb31bda4 100644 --- a/repos/ports/src/app/gdb_monitor/app_child.h +++ b/repos/ports/src/app/gdb_monitor/app_child.h @@ -65,6 +65,8 @@ namespace Gdb_monitor { Region_map_client _address_space { _pd.address_space() }; + Child::Initial_thread _initial_thread; + Child _child; Genode::Rpc_entrypoint *_root_ep; @@ -244,8 +246,9 @@ namespace Gdb_monitor { _cpu_root(&_entrypoint, env()->heap() /* should be _child.heap() */, &_gdb_stub_thread), _cpu_session(_get_cpu_session_cap()), _ram_session(ram_session), + _initial_thread(_cpu_session, _pd.cap(), unique_name), _child(elf_ds, ldso_ds, _pd.cap(), _pd, - _ram_session, _ram_session, _cpu_session, _cpu_session, + _ram_session, _ram_session, _cpu_session, _initial_thread, *Genode::env()->rm_session(), _address_space, _entrypoint, *this), _root_ep(root_ep), _rom_service(&_entrypoint, _child.heap()) diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc index bf2112d9b..0115c94cf 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc @@ -82,10 +82,10 @@ Cpu_session_component::create_thread(Capability pd, } -Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread) -{ - return _parent_cpu_session.utcb(thread); -} +//Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread) +//{ +// return _parent_cpu_session.utcb(thread); +//} void Cpu_session_component::kill_thread(Thread_capability thread_cap) @@ -123,70 +123,69 @@ Thread_capability Cpu_session_component::next(Thread_capability thread_cap) } -int Cpu_session_component::start(Thread_capability thread_cap, - addr_t ip, addr_t sp) +//int Cpu_session_component::start(Thread_capability thread_cap, +// addr_t ip, addr_t sp) +//{ +// Thread_info *thread_info = _thread_info(thread_cap); +// +// if (thread_info) +// exception_handler(thread_cap, _exception_signal_receiver->manage(thread_info)); +// +// int result = _parent_cpu_session.start(thread_cap, ip, sp); +// +// if (thread_info) { +// /* pause the first thread */ +// if (thread_info->lwpid() == GENODE_LWP_BASE) +// pause(thread_cap); +// +// genode_add_thread(thread_info->lwpid()); +// } +// +// return result; +//} + + +//void Cpu_session_component::pause(Thread_capability thread_cap) +//{ +// _parent_cpu_session.pause(thread_cap); +//} + + +//void Cpu_session_component::resume(Thread_capability thread_cap) +//{ +// _parent_cpu_session.resume(thread_cap); +//} + + +//void Cpu_session_component::cancel_blocking(Thread_capability thread_cap) +//{ +// _parent_cpu_session.cancel_blocking(thread_cap); +//} + + +//void Cpu_session_component::state(Thread_capability thread_cap, +// Thread_state const &state) +//{ +// _parent_cpu_session.state(thread_cap, state); +//} + + +//Thread_state Cpu_session_component::state(Thread_capability thread_cap) +//{ +// return _parent_cpu_session.state(thread_cap); +//} + + +void Cpu_session_component::exception_sigh(Signal_context_capability sigh_cap) { - Thread_info *thread_info = _thread_info(thread_cap); - - if (thread_info) - exception_handler(thread_cap, _exception_signal_receiver->manage(thread_info)); - - int result = _parent_cpu_session.start(thread_cap, ip, sp); - - if (thread_info) { - /* pause the first thread */ - if (thread_info->lwpid() == GENODE_LWP_BASE) - pause(thread_cap); - - genode_add_thread(thread_info->lwpid()); - } - - return result; + _parent_cpu_session.exception_sigh(sigh_cap); } -void Cpu_session_component::pause(Thread_capability thread_cap) -{ - _parent_cpu_session.pause(thread_cap); -} - - -void Cpu_session_component::resume(Thread_capability thread_cap) -{ - _parent_cpu_session.resume(thread_cap); -} - - -void Cpu_session_component::cancel_blocking(Thread_capability thread_cap) -{ - _parent_cpu_session.cancel_blocking(thread_cap); -} - - -void Cpu_session_component::state(Thread_capability thread_cap, - Thread_state const &state) -{ - _parent_cpu_session.state(thread_cap, state); -} - - -Thread_state Cpu_session_component::state(Thread_capability thread_cap) -{ - return _parent_cpu_session.state(thread_cap); -} - - -void Cpu_session_component::exception_handler(Thread_capability thread_cap, - Signal_context_capability sigh_cap) -{ - _parent_cpu_session.exception_handler(thread_cap, sigh_cap); -} - - -void Cpu_session_component::single_step(Thread_capability thread_cap, bool enable) -{ - _parent_cpu_session.single_step(thread_cap, enable); -} +//void Cpu_session_component::single_step(Thread_capability thread_cap, bool enable) +//{ +// _parent_cpu_session.single_step(thread_cap, enable); +//} Affinity::Space Cpu_session_component::affinity_space() const @@ -195,11 +194,11 @@ Affinity::Space Cpu_session_component::affinity_space() const } -void Cpu_session_component::affinity(Thread_capability thread_cap, - Affinity::Location location) -{ - _parent_cpu_session.affinity(thread_cap, location); -} +//void Cpu_session_component::affinity(Thread_capability thread_cap, +// Affinity::Location location) +//{ +// _parent_cpu_session.affinity(thread_cap, location); +//} Dataspace_capability Cpu_session_component::trace_control() @@ -208,22 +207,22 @@ Dataspace_capability Cpu_session_component::trace_control() } -unsigned Cpu_session_component::trace_control_index(Thread_capability thread) -{ - return _parent_cpu_session.trace_control_index(thread); -} +//unsigned Cpu_session_component::trace_control_index(Thread_capability thread) +//{ +// return _parent_cpu_session.trace_control_index(thread); +//} -Dataspace_capability Cpu_session_component::trace_buffer(Thread_capability thread) -{ - return _parent_cpu_session.trace_buffer(thread); -} +//Dataspace_capability Cpu_session_component::trace_buffer(Thread_capability thread) +//{ +// return _parent_cpu_session.trace_buffer(thread); +//} -Dataspace_capability Cpu_session_component::trace_policy(Thread_capability thread) -{ - return _parent_cpu_session.trace_policy(thread); -} +//Dataspace_capability Cpu_session_component::trace_policy(Thread_capability thread) +//{ +// return _parent_cpu_session.trace_policy(thread); +//} Capability Cpu_session_component::native_cpu() diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.h b/repos/ports/src/app/gdb_monitor/cpu_session_component.h index 1d792dbca..b919749fc 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.h +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.h @@ -58,23 +58,10 @@ class Cpu_session_component : public Rpc_object Thread_capability create_thread(Capability, Name const &, Affinity::Location, Weight, addr_t) override; - Ram_dataspace_capability utcb(Thread_capability thread) override; void kill_thread(Thread_capability) override; - int start(Thread_capability, addr_t, addr_t) override; - void pause(Thread_capability thread_cap) override; - void resume(Thread_capability thread_cap) override; - void cancel_blocking(Thread_capability) override; - Thread_state state(Thread_capability) override; - void state(Thread_capability, Thread_state const &) override; - void exception_handler(Thread_capability thread, - Signal_context_capability handler) override; - void single_step(Thread_capability thread, bool enable) override; + void exception_sigh(Signal_context_capability handler) override; Affinity::Space affinity_space() const override; - void affinity(Thread_capability, Affinity::Location) override; Dataspace_capability trace_control() override; - unsigned trace_control_index(Thread_capability) override; - Dataspace_capability trace_buffer(Thread_capability) override; - Dataspace_capability trace_policy(Thread_capability) override; int ref_account(Cpu_session_capability c) override; int transfer_quota(Cpu_session_capability c, size_t q) override; Quota quota() override; diff --git a/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc b/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc index cac441e80..120453fc4 100644 --- a/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc +++ b/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc @@ -24,6 +24,7 @@ int linux_detach_one_lwp (struct inferior_list_entry *entry, void *args); #include #include #include +#include #include "cpu_session_component.h" @@ -113,7 +114,7 @@ extern "C" void genode_stop_all_threads() Thread_capability thread_cap = csc->first(); while (thread_cap.valid()) { - csc->pause(thread_cap); + Cpu_thread_client(thread_cap).pause(); thread_cap = csc->next(thread_cap); } } @@ -126,7 +127,7 @@ extern "C" void genode_resume_all_threads() Thread_capability thread_cap = csc->first(); while (thread_cap.valid()) { - csc->resume(thread_cap); + Cpu_thread_client(thread_cap).resume(); thread_cap = csc->next(thread_cap); } } @@ -162,7 +163,7 @@ void genode_interrupt_thread(unsigned long lwpid) return; } - csc->pause(thread_cap); + Cpu_thread_client(thread_cap).pause(); } @@ -177,8 +178,9 @@ void genode_continue_thread(unsigned long lwpid, int single_step) return; } - csc->single_step(thread_cap, single_step); - csc->resume(thread_cap); + Cpu_thread_client cpu_thread(thread_cap); + cpu_thread.single_step(single_step); + cpu_thread.resume(); } @@ -206,7 +208,7 @@ unsigned long genode_find_segfault_lwpid() try { - Thread_state thread_state = csc->state(thread_cap); + Thread_state thread_state = Cpu_thread_client(thread_cap).state(); if (thread_state.unresolved_page_fault) { @@ -214,12 +216,12 @@ unsigned long genode_find_segfault_lwpid() * On base-foc it is necessary to pause the thread before * IP and SP are available in the thread state. */ - csc->pause(thread_cap); + Cpu_thread_client(thread_cap).pause(); return csc->lwpid(thread_cap); } - } catch (Cpu_session::State_access_failed) { } + } catch (Cpu_thread::State_access_failed) { } thread_cap = csc->next(thread_cap); } diff --git a/repos/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc b/repos/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc index 533f7186b..c9c6aac66 100644 --- a/repos/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc +++ b/repos/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc @@ -19,6 +19,8 @@ extern "C" { #define _private private } +#include + #include "cpu_session_component.h" #include "gdb_stub_thread.h" @@ -33,7 +35,9 @@ Thread_state get_current_thread_state() ptid_t ptid = ((struct inferior_list_entry*)current_inferior)->id; - return csc->state(csc->thread_cap(ptid.lwp)); + Cpu_thread_client cpu_thread(csc->thread_cap(ptid.lwp)); + + return cpu_thread.state(); } void set_current_thread_state(Thread_state thread_state) @@ -42,6 +46,8 @@ void set_current_thread_state(Thread_state thread_state) ptid_t ptid = ((struct inferior_list_entry*)current_inferior)->id; - csc->state(csc->thread_cap(ptid.lwp), thread_state); + Cpu_thread_client cpu_thread(csc->thread_cap(ptid.lwp)); + + cpu_thread.state(thread_state); } diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h index 766dc8b78..b608eb3ad 100644 --- a/repos/ports/src/noux/child.h +++ b/repos/ports/src/noux/child.h @@ -166,6 +166,8 @@ namespace Noux { } _resources; + Genode::Child::Initial_thread _initial_thread; + Region_map_client _address_space { _pd.address_space() }; /** @@ -359,6 +361,7 @@ namespace Noux { _entrypoint(cap_session, STACK_SIZE, "noux_process", false), _pd(binary_name, resources_ep, _ds_registry), _resources(binary_name, resources_ep, _ds_registry, _pd.core_pd_cap(), false), + _initial_thread(_resources.cpu, _pd.cap(), binary_name), _args(ARGS_DS_SIZE, args), _env(env), _elf(binary_name, root_dir, root_dir->dataspace(binary_name)), @@ -385,7 +388,7 @@ namespace Noux { _child(forked ? Dataspace_capability() : _elf._binary_ds, _ldso_ds, _pd.cap(), _pd, _resources.ram.cap(), _resources.ram, - _resources.cpu.cap(), _resources.cpu, + _resources.cpu.cap(), _initial_thread, *Genode::env()->rm_session(), _address_space, _entrypoint, _child_policy, _parent_pd_service, _parent_ram_service, _local_cpu_service) diff --git a/repos/ports/src/noux/cpu_session_component.h b/repos/ports/src/noux/cpu_session_component.h index e25c9d076..fc2e9344a 100644 --- a/repos/ports/src/noux/cpu_session_component.h +++ b/repos/ports/src/noux/cpu_session_component.h @@ -27,6 +27,7 @@ /* Genode includes */ #include #include +#include namespace Noux { @@ -69,7 +70,8 @@ namespace Noux { */ void start_main_thread(addr_t ip, addr_t sp) { - _cpu.start(_threads[MAIN_THREAD_IDX], ip, sp); + Capability main_thread = _threads[MAIN_THREAD_IDX]; + Cpu_thread_client(main_thread).start(ip, sp); } Cpu_session_capability cpu_cap() { return _cpu.cap(); } @@ -106,9 +108,6 @@ namespace Noux { throw Thread_creation_failed(); } - Ram_dataspace_capability utcb(Thread_capability thread) override { - return _cpu.utcb(thread); } - void kill_thread(Thread_capability thread) override { /* purge local copy of thread capability */ @@ -119,55 +118,15 @@ namespace Noux { _cpu.kill_thread(thread); } - int start(Thread_capability thread, addr_t ip, addr_t sp) override - { - if (_forked) { - PINF("defer attempt to start thread at ip 0x%lx", ip); - return 0; - } - return _cpu.start(thread, ip, sp); - } - - void pause(Thread_capability thread) override { - _cpu.pause(thread); } - - void resume(Thread_capability thread) override { - _cpu.resume(thread); } - - void cancel_blocking(Thread_capability thread) override { - _cpu.cancel_blocking(thread); } - - Thread_state state(Thread_capability thread) override { - return _cpu.state(thread); } - - void state(Thread_capability thread, Thread_state const &state) override { - _cpu.state(thread, state); } - - void exception_handler(Thread_capability thread, - Signal_context_capability handler) override { - _cpu.exception_handler(thread, handler); } - - void single_step(Thread_capability thread, bool enable) override { - _cpu.single_step(thread, enable); } + void exception_sigh(Signal_context_capability handler) override { + _cpu.exception_sigh(handler); } Affinity::Space affinity_space() const override { return _cpu.affinity_space(); } - void affinity(Thread_capability thread, Affinity::Location location) override { - _cpu.affinity(thread, location); } - Dataspace_capability trace_control() override { return _cpu.trace_control(); } - unsigned trace_control_index(Thread_capability thread) override { - return _cpu.trace_control_index(thread); } - - Dataspace_capability trace_buffer(Thread_capability thread) override { - return _cpu.trace_buffer(thread); } - - Dataspace_capability trace_policy(Thread_capability thread) override { - return _cpu.trace_policy(thread); } - Quota quota() override { return _cpu.quota(); } int ref_account(Cpu_session_capability c) override {