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:
Norman Feske
2024-06-26 17:26:12 +02:00
parent c18f7c7594
commit d44ec53cd3
45 changed files with 628 additions and 1013 deletions

View File

@ -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()) {

View File

@ -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);

View File

@ -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 */
/********************************************

View File

@ -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;

View File

@ -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(); });
}