mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-21 16:39:39 +00:00
core: tie Platform_thread to Platform_pd
This patch tightens the coupling of the 'Platform_thread' objects with their corresponding 'Platform_pd' objects by specifying the 'Platform_pd' as constructor argument, keeping the relationship as a reference (instead of a pointer), and constraining the lifetime of 'Platform_pd' objects to the lifetime of the PD. It thereby clears the way to simplify the thread creation since all PD-related information (like quota budgets) are now known at the construction time of the 'Platform_thread'. The return value of 'Platform_thread::start' has been removed because it is not evaluated by 'Cpu_thread_component'. Related to #5256
This commit is contained in:
@ -57,27 +57,33 @@ Cpu_session_component::create_thread(Capability<Pd_session> pd_cap,
|
||||
|
||||
Mutex::Guard slab_lock_guard(_thread_alloc_lock);
|
||||
|
||||
try {
|
||||
Cpu_thread_component &thread = *new (&_thread_alloc)
|
||||
Cpu_thread_component(
|
||||
cap(), _thread_ep, _pager_ep, *pd, _trace_control_area,
|
||||
_trace_sources, weight, _weight_to_quota(weight.value),
|
||||
_thread_affinity(affinity), _label, name,
|
||||
_priority, utcb);
|
||||
pd->with_threads([&] (Pd_session_component::Threads &pd_threads) {
|
||||
pd->with_platform_pd([&] (Platform_pd &platform_pd) {
|
||||
try {
|
||||
Cpu_thread_component &thread = *new (&_thread_alloc)
|
||||
Cpu_thread_component(
|
||||
cap(), *this, _thread_ep, _pager_ep, *pd, platform_pd,
|
||||
pd_threads, _trace_control_area, _trace_sources,
|
||||
weight, _weight_to_quota(weight.value),
|
||||
_thread_affinity(affinity), _label, name,
|
||||
_priority, utcb);
|
||||
|
||||
if (!thread.valid()) {
|
||||
destroy(_thread_alloc, &thread);
|
||||
return;
|
||||
}
|
||||
if (!thread.valid()) { /* 'Platform_thread' creation failed */
|
||||
destroy(&_thread_alloc, &thread);
|
||||
result = Create_thread_error::DENIED;
|
||||
return;
|
||||
}
|
||||
|
||||
thread.session_exception_sigh(_exception_sigh);
|
||||
thread.session_exception_sigh(_exception_sigh);
|
||||
|
||||
_thread_list.insert(&thread);
|
||||
result = thread.cap();
|
||||
}
|
||||
catch (Out_of_ram) { result = Create_thread_error::OUT_OF_RAM; }
|
||||
catch (Out_of_caps) { result = Create_thread_error::OUT_OF_CAPS; }
|
||||
catch (...) { result = Create_thread_error::DENIED; }
|
||||
_thread_list.insert(&thread);
|
||||
result = thread.cap();
|
||||
}
|
||||
catch (Out_of_ram) { result = Create_thread_error::OUT_OF_RAM; }
|
||||
catch (Out_of_caps) { result = Create_thread_error::OUT_OF_CAPS; }
|
||||
catch (...) { result = Create_thread_error::DENIED; }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (result.failed()) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_thread_component.h>
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
@ -26,6 +26,9 @@ void Cpu_thread_component::_update_exception_sigh()
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::destroy() { _cpu.kill_thread(cap()); }
|
||||
|
||||
|
||||
void Cpu_thread_component::quota(size_t quota)
|
||||
{
|
||||
_platform_thread.quota(quota);
|
||||
|
@ -28,7 +28,10 @@
|
||||
#include <trace/control_area.h>
|
||||
#include <trace/source_registry.h>
|
||||
|
||||
namespace Core { class Cpu_thread_component; }
|
||||
namespace Core {
|
||||
class Cpu_session_component;
|
||||
class Cpu_thread_component;
|
||||
}
|
||||
|
||||
|
||||
class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
@ -39,6 +42,8 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
|
||||
typedef Trace::Thread_name Thread_name;
|
||||
|
||||
using Pd_threads = Pd_session_component::Threads;
|
||||
|
||||
private:
|
||||
|
||||
friend class List<Cpu_thread_component>;
|
||||
@ -46,17 +51,13 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Pager_entrypoint &_pager_ep;
|
||||
Cpu_session_component &_cpu;
|
||||
Region_map_component &_address_space_region_map;
|
||||
Cpu_session::Weight const _weight;
|
||||
Session_label const _session_label;
|
||||
Thread_name const _name;
|
||||
Pd_threads::Element _pd_element;
|
||||
Platform_thread _platform_thread;
|
||||
bool const _bound_to_pd;
|
||||
|
||||
bool _bind_to_pd(Pd_session_component &pd)
|
||||
{
|
||||
return pd.bind_thread(_platform_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handler as defined by 'Cpu_session::exception_sigh'
|
||||
@ -138,9 +139,12 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
* \param utcb user-local UTCB base
|
||||
*/
|
||||
Cpu_thread_component(Cpu_session_capability cpu_session_cap,
|
||||
Cpu_session_component &cpu,
|
||||
Rpc_entrypoint &ep,
|
||||
Pager_entrypoint &pager_ep,
|
||||
Pd_session_component &pd,
|
||||
Platform_pd &platform_pd,
|
||||
Pd_threads &pd_threads,
|
||||
Trace::Control_area &trace_control_area,
|
||||
Trace::Source_registry &trace_sources,
|
||||
Cpu_session::Weight weight,
|
||||
@ -151,12 +155,12 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
unsigned priority,
|
||||
addr_t utcb)
|
||||
:
|
||||
_ep(ep), _pager_ep(pager_ep),
|
||||
_ep(ep), _pager_ep(pager_ep), _cpu(cpu),
|
||||
_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)),
|
||||
_pd_element(pd_threads, *this),
|
||||
_platform_thread(platform_pd, quota, name.string(), priority, location, utcb),
|
||||
_trace_control_slot(trace_control_area),
|
||||
_trace_sources(trace_sources),
|
||||
_managed_thread_cap(_ep, *this),
|
||||
@ -181,7 +185,9 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
_address_space_region_map.remove_client(_rm_client);
|
||||
}
|
||||
|
||||
bool valid() const { return _bound_to_pd; };
|
||||
bool valid() { return _platform_thread.valid(); }
|
||||
|
||||
void destroy(); /* solely called by ~Pd_session_component */
|
||||
|
||||
|
||||
/********************************************
|
||||
|
@ -38,7 +38,10 @@
|
||||
#include <platform_generic.h>
|
||||
#include <account.h>
|
||||
|
||||
namespace Core { class Pd_session_component; }
|
||||
namespace Core {
|
||||
class Pd_session_component;
|
||||
class Cpu_thread_component;
|
||||
}
|
||||
|
||||
|
||||
class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
@ -47,6 +50,8 @@ class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
|
||||
enum class Managing_system { DENIED, PERMITTED };
|
||||
|
||||
using Threads = Registry<Cpu_thread_component>;
|
||||
|
||||
private:
|
||||
|
||||
Constructible<Account<Cap_quota> > _cap_account { };
|
||||
@ -71,6 +76,8 @@ class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
|
||||
Managing_system _managing_system;
|
||||
|
||||
Threads _threads { };
|
||||
|
||||
friend class Native_pd_component;
|
||||
|
||||
|
||||
@ -159,6 +166,8 @@ class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
}
|
||||
}
|
||||
|
||||
~Pd_session_component();
|
||||
|
||||
/**
|
||||
* Initialize cap and RAM accounts without providing a reference account
|
||||
*
|
||||
@ -171,20 +180,16 @@ class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
_ram_account.construct(_ram_quota_guard(), _label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate thread with PD
|
||||
*
|
||||
* \return true on success
|
||||
*
|
||||
* This function may fail for platform-specific reasons such as a
|
||||
* limit on the number of threads per protection domain or a limited
|
||||
* thread ID namespace.
|
||||
*/
|
||||
bool bind_thread(Platform_thread &thread)
|
||||
void with_platform_pd(auto const &fn)
|
||||
{
|
||||
return _pd->bind_thread(thread);
|
||||
if (_pd.constructed())
|
||||
fn(*_pd);
|
||||
else
|
||||
error("unexpected call for 'with_platform_pd'");
|
||||
}
|
||||
|
||||
void with_threads(auto const &fn) { fn(_threads); }
|
||||
|
||||
Region_map_component &address_space_region_map()
|
||||
{
|
||||
return _address_space;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
/* core includes */
|
||||
#include <pd_session_component.h>
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
@ -207,3 +208,15 @@ Pd_session_component::attach_dma(Dataspace_capability ds_cap, addr_t at)
|
||||
|
||||
return _address_space.attach_dma(ds_cap, at);
|
||||
}
|
||||
|
||||
|
||||
Pd_session_component::~Pd_session_component()
|
||||
{
|
||||
/*
|
||||
* As `Platform_thread` objects point to their corresponding `Platform_pd`
|
||||
* objects, we need to destroy the threads when the `Platform_pd` ceases to
|
||||
* exist.
|
||||
*/
|
||||
_threads.for_each([&] (Cpu_thread_component &thread) {
|
||||
thread.destroy(); });
|
||||
}
|
||||
|
Reference in New Issue
Block a user