mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
libc: place pthreads round-robin
if the number of threads started exceed configured placement configuration Issue #3967
This commit is contained in:
parent
7de62734e5
commit
33a64f79dc
@ -113,7 +113,8 @@ namespace Libc {
|
||||
* Pthread/semaphore support
|
||||
*/
|
||||
void init_pthread_support(Monitor &, Timer_accessor &);
|
||||
void init_pthread_support(Genode::Cpu_session &, Xml_node);
|
||||
void init_pthread_support(Genode::Cpu_session &, Xml_node const &,
|
||||
Genode::Allocator &);
|
||||
void init_semaphore_support(Timer_accessor &);
|
||||
|
||||
struct Config_accessor : Interface
|
||||
|
@ -461,7 +461,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
|
||||
|
||||
init_semaphore_support(_timer_accessor);
|
||||
init_pthread_support(*this, _timer_accessor);
|
||||
init_pthread_support(env.cpu(), _pthread_config());
|
||||
init_pthread_support(env.cpu(), _pthread_config(), _heap);
|
||||
|
||||
_env.ep().register_io_progress_handler(*this);
|
||||
|
||||
|
@ -29,56 +29,111 @@
|
||||
#include <internal/pthread.h>
|
||||
|
||||
|
||||
static Genode::Cpu_session * _cpu_session { nullptr };
|
||||
static unsigned _id_cpu_map[32];
|
||||
static bool _verbose { false };
|
||||
using namespace Genode;
|
||||
|
||||
void Libc::init_pthread_support(Genode::Cpu_session &cpu_session,
|
||||
Genode::Xml_node node)
|
||||
|
||||
struct Placement_policy
|
||||
{
|
||||
struct Placement : Interface
|
||||
{
|
||||
unsigned pthread_id;
|
||||
unsigned cpu;
|
||||
|
||||
Placement (unsigned id, unsigned cpu)
|
||||
: pthread_id(id), cpu(cpu) { }
|
||||
};
|
||||
|
||||
Registry<Registered<Placement> > _policies { };
|
||||
|
||||
enum class Policy { ALL, SINGLE, MANUAL };
|
||||
|
||||
Policy _policy { Policy::ALL };
|
||||
|
||||
void policy(String<32> const &policy_name)
|
||||
{
|
||||
if (policy_name == "single-cpu")
|
||||
_policy = Policy::SINGLE;
|
||||
if (policy_name == "manual")
|
||||
_policy = Policy::MANUAL;
|
||||
if (policy_name == "all-cpus")
|
||||
_policy = Policy::ALL;
|
||||
}
|
||||
|
||||
unsigned placement(unsigned const pthread_id) const
|
||||
{
|
||||
switch (_policy) {
|
||||
case Policy::SINGLE:
|
||||
return 0U;
|
||||
case Policy::MANUAL: {
|
||||
unsigned cpu = 0U;
|
||||
bool found = false;
|
||||
_policies.for_each([&](auto const &policy) {
|
||||
if (policy.pthread_id == pthread_id) {
|
||||
cpu = policy.cpu;
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
/* if no entry is found, Policy::ALL is applied */
|
||||
return found ? cpu : pthread_id;
|
||||
}
|
||||
case Policy::ALL:
|
||||
default:
|
||||
return pthread_id;
|
||||
}
|
||||
}
|
||||
|
||||
void add_placement(Genode::Allocator &alloc, unsigned pthread, unsigned cpu)
|
||||
{
|
||||
new (alloc) Registered<Placement> (_policies, pthread, cpu);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Cpu_session *_cpu_session { nullptr };
|
||||
static bool _verbose { false };
|
||||
|
||||
|
||||
Placement_policy &placement_policy()
|
||||
{
|
||||
static Placement_policy policy { };
|
||||
return policy;
|
||||
}
|
||||
|
||||
|
||||
void Libc::init_pthread_support(Cpu_session &cpu_session,
|
||||
Xml_node const &node,
|
||||
Genode::Allocator &alloc)
|
||||
{
|
||||
_cpu_session = &cpu_session;
|
||||
|
||||
_verbose = node.attribute_value("verbose", false);
|
||||
|
||||
String<32> placement("all-cpus");
|
||||
placement = node.attribute_value("placement", placement);
|
||||
String<32> const policy_name = node.attribute_value("placement",
|
||||
String<32>("all-cpus"));
|
||||
placement_policy().policy(policy_name);
|
||||
|
||||
if (placement == "single-cpu") {
|
||||
return;
|
||||
}
|
||||
node.for_each_sub_node("thread", [&](Xml_node &policy) {
|
||||
|
||||
if (placement == "manual") {
|
||||
node.for_each_sub_node("thread", [](Xml_node &node) {
|
||||
if (node.has_attribute("id") && node.has_attribute("cpu")) {
|
||||
unsigned const id = node.attribute_value("id", 0U);
|
||||
unsigned const cpu = node.attribute_value("cpu", 0U);
|
||||
if (policy.has_attribute("id") && policy.has_attribute("cpu")) {
|
||||
unsigned const id = policy.attribute_value("id", 0U);
|
||||
unsigned const cpu = policy.attribute_value("cpu", 0U);
|
||||
|
||||
if (id < sizeof(_id_cpu_map) / sizeof(_id_cpu_map[0])) {
|
||||
_id_cpu_map[id] = cpu;
|
||||
if (_verbose)
|
||||
Genode::log("pthread.", id, " -> cpu ", cpu);
|
||||
} else {
|
||||
Genode::warning("pthread configuration ignored - "
|
||||
"id=", id, " cpu=", cpu);
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (_verbose)
|
||||
log("pthread.", id, " -> cpu ", cpu);
|
||||
|
||||
/* all-cpus and unknown case */
|
||||
for (unsigned i = 0; i < sizeof(_id_cpu_map) / sizeof(_id_cpu_map[0]); i++)
|
||||
_id_cpu_map[i] = i;
|
||||
placement_policy().add_placement(alloc, id, cpu);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static unsigned pthread_id()
|
||||
{
|
||||
static Genode::Mutex mutex;
|
||||
static Mutex mutex;
|
||||
|
||||
static unsigned id = 0;
|
||||
|
||||
Genode::Mutex::Guard guard(mutex);
|
||||
Mutex::Guard guard(mutex);
|
||||
|
||||
return id++;
|
||||
}
|
||||
@ -132,17 +187,15 @@ int Libc::pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
? (*attr)->stack_size
|
||||
: Libc::Component::stack_size();
|
||||
|
||||
using Genode::Affinity;
|
||||
|
||||
unsigned const id { pthread_id() };
|
||||
unsigned const cpu = (id < sizeof(_id_cpu_map) / sizeof(_id_cpu_map[0])) ? _id_cpu_map[id] : 0;
|
||||
unsigned const cpu = placement_policy().placement(id);
|
||||
|
||||
Genode::String<32> const pthread_name { "pthread.", id };
|
||||
String<32> const pthread_name { "pthread.", id };
|
||||
Affinity::Space space { _cpu_session->affinity_space() };
|
||||
Affinity::Location location { space.location_of_index(cpu) };
|
||||
|
||||
if (_verbose)
|
||||
Genode::log("create ", pthread_name, " -> cpu ", cpu);
|
||||
log("create ", pthread_name, " -> cpu ", cpu);
|
||||
|
||||
int result =
|
||||
Libc::pthread_create_from_session(thread, start_routine, arg,
|
||||
|
Loading…
Reference in New Issue
Block a user