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

@ -32,8 +32,6 @@ struct Core::Platform_pd
{
Platform_pd(Allocator &, char const *) { }
bool bind_thread(Platform_thread &) { return true; }
void assign_parent(Capability<Parent>) { }
};

View File

@ -17,13 +17,17 @@
/* Genode includes */
#include <base/thread_state.h>
#include <base/trace/types.h>
#include <base/registry.h>
#include <base/weak_ptr.h>
#include <cpu_session/cpu_session.h>
/* core includes */
#include <pager.h>
namespace Core { class Platform_thread; }
namespace Core {
class Platform_thread;
class Platform_pd;
}
/*
@ -34,32 +38,17 @@ namespace Core { class Platform_thread; }
* turn, we find the exception handler's 'Signal_context_capability'.
*/
class Core::Platform_thread : public List<Platform_thread>::Element
class Core::Platform_thread : Noncopyable
{
using Location = Affinity::Location;
using Execution_time = Trace::Execution_time;
private:
struct Registry
{
Mutex _mutex { };
List<Platform_thread> _list { };
void insert(Platform_thread *thread);
void remove(Platform_thread *thread);
/**
* Trigger exception handler for 'Platform_thread' with matching PID.
*/
void submit_exception(unsigned long pid);
};
/**
* Return singleton instance of 'Platform_thread::Registry'
*/
static Registry &_registry();
unsigned long _tid = -1;
unsigned long _pid = -1;
char _name[32] { };
String<32> const _name;
/*
* Dummy pager object that is solely used for storing the
@ -67,84 +56,60 @@ class Core::Platform_thread : public List<Platform_thread>::Element
*/
Pager_object _pager { };
/**
* Singleton instance of platform-thread registry used to deliver
* exceptions.
*/
static Registry<Platform_thread> &_registry();
Registry<Platform_thread>::Element _elem { _registry(), *this };
public:
/**
* Constructor
*/
Platform_thread(size_t, const char *name, unsigned priority,
Affinity::Location, addr_t);
~Platform_thread();
Platform_thread(Platform_pd &, size_t, auto const &name, auto...)
: _name(name) { }
/**
* Pause this thread
* Return true if thread creation succeeded
*/
void pause();
bool valid() const { return true; }
const char *name() { return _name.string(); }
/**
* Enable/disable single stepping
* Notify Genode::Signal handler about sigchld
*/
void single_step(bool) { }
/**
* Resume this thread
*/
void resume();
/**
* Dummy implementation of platform-thread interface
*/
Pager_object &pager() { return _pager; }
void pager(Pager_object &) { }
int start(void *, void *) { return 0; }
Thread_state state()
{
return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
}
void state(Thread_state) { }
const char *name() { return _name; }
/**
* Set the executing CPU for this thread
*
* SMP is currently not directly supported on Genode/Linux
* (but indirectly by the Linux kernel).
*/
void affinity(Affinity::Location) { }
/**
* Request the affinity of this thread
*/
Affinity::Location affinity() const { return Affinity::Location(); }
static void submit_exception(unsigned pid);
/**
* Register process ID and thread ID of thread
*/
void thread_id(int pid, int tid) { _pid = pid, _tid = tid; }
/**
* Notify Genode::Signal handler about sigchld
/*
* Part of the platform-thread interface that is not used on Linux
*/
static void submit_exception(int pid)
void pause() { };
void single_step(bool) { }
void resume() { }
Pager_object &pager() { return _pager; }
void pager(Pager_object &) { }
void start(void *, void *) { }
void affinity(Location) { }
Location affinity() const { return { }; }
void quota(size_t) { }
void state(Thread_state) { }
Execution_time execution_time() const { return { 0, 0 }; }
unsigned long pager_object_badge() const { return 0; }
Thread_state state()
{
_registry().submit_exception(pid);
return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
}
/**
* Set CPU quota of the thread to 'quota'
*/
void quota(size_t const) { /* not supported*/ }
/**
* Return execution time consumed by the thread
*/
Trace::Execution_time execution_time() const { return { 0, 0 }; }
unsigned long pager_object_badge() const { return 0; }
};
#endif /* _CORE__INCLUDE__PLATFORM_THREAD_H_ */

View File

@ -22,80 +22,24 @@
using namespace Core;
typedef Token<Scanner_policy_identifier_with_underline> Tid_token;
/*******************************
** Platform_thread::Registry **
*******************************/
void Platform_thread::Registry::insert(Platform_thread *thread)
void Platform_thread::submit_exception(unsigned pid)
{
Mutex::Guard guard(_mutex);
_list.insert(thread);
}
void Platform_thread::Registry::remove(Platform_thread *thread)
{
Mutex::Guard guard(_mutex);
_list.remove(thread);
}
void Platform_thread::Registry::submit_exception(unsigned long pid)
{
Mutex::Guard guard(_mutex);
/* traverse list to find 'Platform_thread' with matching PID */
for (Platform_thread *curr = _list.first(); curr; curr = curr->next()) {
if (curr->_tid == pid) {
Signal_context_capability sigh = curr->_pager._sigh;
if (sigh.valid())
Signal_transmitter(sigh).submit();
bool submitted = false;
_registry().for_each([&] (Platform_thread const &thread) {
if (submitted || thread._tid != pid)
return;
}
}
Signal_context_capability sigh = thread._pager._sigh;
if (sigh.valid())
Signal_transmitter(sigh).submit();
submitted = true;
});
}
Platform_thread::Registry &Platform_thread::_registry()
Registry<Platform_thread> &Platform_thread::_registry()
{
static Platform_thread::Registry registry;
static Registry<Platform_thread> registry { };
return registry;
}
/*********************
** Platform_thread **
*********************/
Platform_thread::Platform_thread(size_t, const char *name, unsigned,
Affinity::Location, addr_t)
{
copy_cstring(_name, name, min(sizeof(_name), Genode::strlen(name) + 1));
_registry().insert(this);
}
Platform_thread::~Platform_thread()
{
_registry().remove(this);
}
void Platform_thread::pause()
{
warning(__func__, "not implemented");
}
void Platform_thread::resume()
{
warning(__func__, "not implemented");
}