diff --git a/repos/base-fiasco/src/core/platform_thread.cc b/repos/base-fiasco/src/core/platform_thread.cc
index 5bd1835475..18e7e7b818 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 cbdd6ed240..5fbc8dc0d2 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 ad8df5986d..fafa5c5409 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 edcfca6303..6ba978f441 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 fcecb7a165..bc4ef528ac 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 f60e4e2381..36e7bb1eea 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 48ee653ab8..e3f7f1fbe5 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 f9f6fff76a..554ff5f1c6 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 14c5777170..9e2f6ec6ac 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 dc0b7b4160..f4e905d356 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 914dbf50eb..12e4d0bbc4 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 2992be9807..8df9bba027 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 e2a25c7dee..06be634fd6 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 d576d47a3d..ea198a8a8e 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 4324f19247..af09380ba9 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 5f6916184a..0038c04370 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 53b9cae12c..56d5a6e287 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 d8d6a39192..e2a8955fbd 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 9e23cc0c7d..d68fce1f3f 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 c5604c06f9..02ddda7186 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 d2f8b8aa60..7a0ee4a80e 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 73380be3b8..2bf59faed5 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 31c10b166b..b1c4111e15 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 8d2f12c785..d7e9b8d824 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 5b31c0fe0b..d34bbc64a5 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 d4bb70adf7..ff81129f69 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 5e9d1e5ba2..2c6e860a51 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 49b4fa8dfb..b084d3646f 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 23d80475ee..c4c69dbc5e 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 f2484196df..6dfc5ed3b9 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 8f07f33c8b..f189987ab2 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 0000000000..5298d72e8a
--- /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 0000000000..b3417528c1
--- /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 0000000000..4c71ffa6ed
--- /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 3f9800901a..f67d61413e 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 55b1955702..8d4f9dd59c 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 a5ad4ba191..41debdeb67 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 0000000000..3265df0aa5
--- /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 ccdeb8720d..dc36b07257 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 0000000000..13ac0939c4
--- /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 a6affd2d8e..f81caf5141 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 3feb66e79a..fb248939e8 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 f181030e2c..7d0d46d8d6 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 824426bd60..80b19baf00 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 19e9a577a8..ddaf8473e5 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 37ee424b9f..93da62ea4a 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 831290182c..dfae843815 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 3ce08e7560..ae359faf89 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 306cfd9ce0..1d1762bd83 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 5f3704004f..f9dad23f4b 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 5c8fb91445..e05d40272d 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 ef1fbdd276..c75940074c 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 a5650d52d7..17ca98dfb4 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 3d43ee60e4..5d9fa66873 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 fa77a6b718..a8da82b68e 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 28bbb4e6dc..0b0b9d394c 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 d59c161e9f..30050497e5 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 661d410f51..8ac17beb6c 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 dcfdf24b00..7a7d5bf57e 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 9a2892f6fa..9bb31bda46 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 bf2112d9b0..0115c94cfc 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 1d792dbcac..b919749fc4 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 cac441e80c..120453fc4f 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 533f7186b0..c9c6aac666 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 766dc8b782..b608eb3ad0 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 e25c9d076d..fc2e9344ae 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 {