Extend Cpu_session with thread-affinity API

This patch introduces the functions 'affinity' and 'num_cpus' to the CPU
session interface. The interface extension will allow the assignment of
individual threads to CPUs. At this point, it is just a stub with no
actual platform support.
This commit is contained in:
Norman Feske
2012-09-04 17:32:55 +02:00
parent 43db231e77
commit 83bdfea9b0
29 changed files with 125 additions and 23 deletions

View File

@ -114,9 +114,9 @@ namespace Genode {
unsigned long pager_object_badge() const { return _tid; } unsigned long pager_object_badge() const { return _tid; }
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no); void affinity(unsigned cpu);
/** /**
* Get thread name * Get thread name

View File

@ -27,7 +27,7 @@ using namespace Genode;
using namespace Codezero; using namespace Codezero;
void Platform_thread::set_cpu(unsigned int cpu_no) void Platform_thread::affinity(unsigned int cpu_no)
{ {
PDBG("not yet implemented"); PDBG("not yet implemented");
} }

View File

@ -111,6 +111,13 @@ namespace Genode {
*/ */
int state(Genode::Thread_state *state_dst); int state(Genode::Thread_state *state_dst);
/**
* Set the executing CPU for this thread
*
* SMP is not supported on L4/Fiasco.
*/
void affinity(unsigned) { }
/************************ /************************
** Accessor functions ** ** Accessor functions **

View File

@ -67,6 +67,15 @@ namespace Genode {
void exception_handler(Thread_capability thread, Signal_context_capability handler) { void exception_handler(Thread_capability thread, Signal_context_capability handler) {
call<Rpc_exception_handler>(thread, handler); } call<Rpc_exception_handler>(thread, handler); }
void single_step(Thread_capability thread, bool enable) {
call<Rpc_single_step>(thread, enable); }
unsigned num_cpus() const {
return call<Rpc_num_cpus>(); }
void affinity(Thread_capability thread, unsigned cpu) {
call<Rpc_affinity>(thread, cpu); }
void enable_vcpu(Thread_capability cap, addr_t vcpu_state) { void enable_vcpu(Thread_capability cap, addr_t vcpu_state) {
call<Rpc_enable_vcpu>(cap, vcpu_state); } call<Rpc_enable_vcpu>(cap, vcpu_state); }

View File

@ -141,6 +141,8 @@ namespace Genode {
int name(Thread_capability, char *, size_t); int name(Thread_capability, char *, size_t);
int state(Thread_capability, Thread_state *); int state(Thread_capability, Thread_state *);
void exception_handler(Thread_capability, Signal_context_capability); void exception_handler(Thread_capability, Signal_context_capability);
unsigned num_cpus() const;
void affinity(Thread_capability, unsigned);
/*********************************** /***********************************

View File

@ -124,6 +124,11 @@ namespace Genode {
*/ */
int state(Genode::Thread_state *state_dst); int state(Genode::Thread_state *state_dst);
/**
* Set the executing CPU for this thread
*/
void affinity(unsigned cpu);
/************************ /************************
** Accessor functions ** ** Accessor functions **

View File

@ -180,6 +180,11 @@ void Platform_thread::cancel_blocking()
} }
void Platform_thread::affinity(unsigned cpu)
{
}
void Platform_thread::_create_thread() void Platform_thread::_create_thread()
{ {
l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP, l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP,

View File

@ -92,9 +92,9 @@ namespace Genode {
unsigned long pager_object_badge() const; unsigned long pager_object_badge() const;
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no); void affinity(unsigned cpu);
/** /**
* Get thread name * Get thread name

View File

@ -20,7 +20,7 @@
using namespace Genode; using namespace Genode;
void Platform_thread::set_cpu(unsigned int cpu_no) void Platform_thread::affinity(unsigned int cpu_no)
{ {
PERR("not yet implemented"); PERR("not yet implemented");
} }

View File

@ -139,9 +139,9 @@ namespace Genode {
unsigned long pager_object_badge() { return _id; } unsigned long pager_object_badge() { return _id; }
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no) void affinity(unsigned cpu)
{ {
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n"; kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
while (1) ; while (1) ;

View File

@ -59,6 +59,7 @@ namespace Genode {
int start(void *ip, void *sp) { return 0; } int start(void *ip, void *sp) { return 0; }
int state(Thread_state *state_dst) { return 0; } int state(Thread_state *state_dst) { return 0; }
const char *name() { return _name; } const char *name() { return _name; }
void affinity(unsigned) { }
}; };
} }

View File

@ -141,9 +141,9 @@ namespace Genode {
inline unsigned long pager_object_badge() const { return _tid; } inline unsigned long pager_object_badge() const { return _tid; }
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no = 0); void affinity(unsigned cpu);
/** /**
* Get thread name * Get thread name

View File

@ -81,7 +81,7 @@ Kernel::Utcb* Genode::physical_utcb(Native_thread_id tid)
} }
void Platform_thread::set_cpu(unsigned int cpu_no) { PERR("not implemented"); } void Platform_thread::affinity(unsigned int cpu_no) { PERR("not implemented"); }
void Platform_thread::cancel_blocking() { PERR("not implemented"); } void Platform_thread::cancel_blocking() { PERR("not implemented"); }

View File

@ -80,6 +80,12 @@ namespace Genode {
Native_capability native_cap(Thread_capability cap) { Native_capability native_cap(Thread_capability cap) {
return call<Rpc_native_cap>(cap); } return call<Rpc_native_cap>(cap); }
unsigned num_cpus() const {
return call<Rpc_num_cpus>(); }
void affinity(Thread_capability thread, unsigned cpu) {
call<Rpc_affinity>(thread, cpu); }
private: private:
Native_capability pause_sync(Thread_capability target) { Native_capability pause_sync(Thread_capability target) {

View File

@ -142,6 +142,8 @@ namespace Genode {
int name(Thread_capability, char *, size_t); int name(Thread_capability, char *, size_t);
int state(Thread_capability, Thread_state *); int state(Thread_capability, Thread_state *);
void exception_handler(Thread_capability, Signal_context_capability); void exception_handler(Thread_capability, Signal_context_capability);
unsigned num_cpus() const;
void affinity(Thread_capability, unsigned);
/*********************************** /***********************************

View File

@ -114,9 +114,9 @@ namespace Genode {
unsigned long pager_object_badge() const; unsigned long pager_object_badge() const;
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no); void affinity(unsigned cpu);
/** /**
* Get thread name * Get thread name

View File

@ -35,7 +35,7 @@ using namespace Genode;
** Platform thread ** ** Platform thread **
*********************/ *********************/
void Platform_thread::set_cpu(unsigned int cpu_no) void Platform_thread::affinity(unsigned int cpu_no)
{ {
PERR("not yet implemented"); PERR("not yet implemented");
} }

View File

@ -130,9 +130,9 @@ namespace Genode {
unsigned long pager_object_badge() const; unsigned long pager_object_badge() const;
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no); void affinity(unsigned cpu);
/***************************** /*****************************

View File

@ -36,7 +36,7 @@ using namespace Genode;
using namespace Okl4; using namespace Okl4;
void Platform_thread::set_cpu(unsigned int cpu_no) void Platform_thread::affinity(unsigned int cpu_no)
{ {
PERR("not yet implemented"); PERR("not yet implemented");
} }

View File

@ -130,9 +130,9 @@ namespace Genode {
return convert_native_thread_id_to_badge(_l4_thread_id); } return convert_native_thread_id_to_badge(_l4_thread_id); }
/** /**
* Set the executing CPU for this thread. * Set the executing CPU for this thread
*/ */
void set_cpu(unsigned int cpu_no); void affinity(unsigned cpu);
/********************************** /**********************************

View File

@ -39,7 +39,7 @@ static const bool verbose2 = true;
#define PT_DBG(args...) if (verbose) PDBG(args); else {} #define PT_DBG(args...) if (verbose) PDBG(args); else {}
void Platform_thread::set_cpu(unsigned int cpu_no) void Platform_thread::affinity(unsigned int cpu_no)
{ {
if (cpu_no >= L4_NumProcessors(get_kip())) { if (cpu_no >= L4_NumProcessors(get_kip())) {
PERR("Invalid processor number."); PERR("Invalid processor number.");
@ -98,7 +98,7 @@ int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no)
} }
/* get the thread running on the right cpu */ /* get the thread running on the right cpu */
set_cpu(cpu_no); affinity(cpu_no);
/* assign priority */ /* assign priority */
if (!L4_Set_Priority(thread, if (!L4_Set_Priority(thread,

View File

@ -62,6 +62,12 @@ namespace Genode {
void single_step(Thread_capability thread, bool enable) { void single_step(Thread_capability thread, bool enable) {
call<Rpc_single_step>(thread, enable); } call<Rpc_single_step>(thread, enable); }
unsigned num_cpus() const {
return call<Rpc_num_cpus>(); }
void affinity(Thread_capability thread, unsigned cpu) {
call<Rpc_affinity>(thread, cpu); }
}; };
} }

View File

@ -161,6 +161,19 @@ namespace Genode {
*/ */
virtual void single_step(Thread_capability thread, bool enable) {} virtual void single_step(Thread_capability thread, bool enable) {}
/**
* Return number of CPUs available via the CPU session
*/
virtual unsigned num_cpus() const = 0;
/**
* Assign thread to a CPU
*
* The 'cpu' argument is a CPU index starting at 0. It must be
* smaller than the value returned by 'num_cpus()'.
*/
virtual void affinity(Thread_capability thread, unsigned cpu) = 0;
/** /**
* Translate generic priority value to kernel-specific priority levels * Translate generic priority value to kernel-specific priority levels
* *
@ -211,6 +224,8 @@ namespace Genode {
GENODE_RPC(Rpc_exception_handler, void, exception_handler, GENODE_RPC(Rpc_exception_handler, void, exception_handler,
Thread_capability, Signal_context_capability); Thread_capability, Signal_context_capability);
GENODE_RPC(Rpc_single_step, void, single_step, Thread_capability, bool); GENODE_RPC(Rpc_single_step, void, single_step, Thread_capability, bool);
GENODE_RPC(Rpc_num_cpus, unsigned, num_cpus);
GENODE_RPC(Rpc_affinity, void, affinity, Thread_capability, unsigned);
/* /*
* 'GENODE_RPC_INTERFACE' declaration done manually * 'GENODE_RPC_INTERFACE' declaration done manually
@ -233,8 +248,10 @@ namespace Genode {
Meta::Type_tuple<Rpc_state, Meta::Type_tuple<Rpc_state,
Meta::Type_tuple<Rpc_exception_handler, Meta::Type_tuple<Rpc_exception_handler,
Meta::Type_tuple<Rpc_single_step, Meta::Type_tuple<Rpc_single_step,
Meta::Type_tuple<Rpc_num_cpus,
Meta::Type_tuple<Rpc_affinity,
Meta::Empty> Meta::Empty>
> > > > > > > > > > > > Rpc_functions; > > > > > > > > > > > > > > Rpc_functions;
}; };
} }

View File

@ -17,9 +17,10 @@
#include <base/printf.h> #include <base/printf.h>
#include <util/arg_string.h> #include <util/arg_string.h>
/* Core includes */ /* core includes */
#include <cpu_session_component.h> #include <cpu_session_component.h>
#include <rm_session_component.h> #include <rm_session_component.h>
#include <platform_generic.h>
using namespace Genode; using namespace Genode;
@ -162,6 +163,21 @@ void Cpu_session_component::exception_handler(Thread_capability thread_c
} }
unsigned Cpu_session_component::num_cpus() const
{
return platform()->num_cpus();
}
void Cpu_session_component::affinity(Thread_capability thread_cap, unsigned cpu)
{
Cpu_thread_component *thread = _lookup_thread(thread_cap);
if (!thread) return;
thread->platform_thread()->affinity(cpu);
}
Cpu_session_component::Cpu_session_component(Rpc_entrypoint *thread_ep, Cpu_session_component::Cpu_session_component(Rpc_entrypoint *thread_ep,
Pager_entrypoint *pager_ep, Pager_entrypoint *pager_ep,
Allocator *md_alloc, Allocator *md_alloc,

View File

@ -134,6 +134,8 @@ namespace Genode {
int name(Thread_capability, char *, size_t); int name(Thread_capability, char *, size_t);
int state(Thread_capability, Thread_state *); int state(Thread_capability, Thread_state *);
void exception_handler(Thread_capability, Signal_context_capability); void exception_handler(Thread_capability, Signal_context_capability);
unsigned num_cpus() const;
void affinity(Thread_capability, unsigned);
}; };
} }

View File

@ -88,6 +88,11 @@ namespace Genode {
* Return true if platform supports direct unmap (no mapping db) * Return true if platform supports direct unmap (no mapping db)
*/ */
virtual bool supports_direct_unmap() const { return false; } virtual bool supports_direct_unmap() const { return false; }
/**
* Return number of physical CPUs present in the platform
*/
virtual unsigned num_cpus() const { return 1; }
}; };

View File

@ -185,6 +185,18 @@ void Cpu_session_component::single_step(Thread_capability thread_cap, bool enabl
} }
unsigned Cpu_session_component::num_cpus() const
{
return _parent_cpu_session.num_cpus();
}
void Cpu_session_component::affinity(Thread_capability thread_cap, unsigned cpu)
{
_parent_cpu_session.affinity(thread_cap, cpu);
}
Cpu_session_component::Cpu_session_component(Signal_receiver *exception_signal_receiver, const char *args) Cpu_session_component::Cpu_session_component(Signal_receiver *exception_signal_receiver, const char *args)
: _parent_cpu_session(env()->parent()->session<Cpu_session>(args)), : _parent_cpu_session(env()->parent()->session<Cpu_session>(args)),
_exception_signal_receiver(exception_signal_receiver) _exception_signal_receiver(exception_signal_receiver)

View File

@ -69,6 +69,8 @@ class Cpu_session_component : public Rpc_object<Cpu_session>
void exception_handler(Thread_capability thread, void exception_handler(Thread_capability thread,
Signal_context_capability handler); Signal_context_capability handler);
void single_step(Thread_capability thread, bool enable); void single_step(Thread_capability thread, bool enable);
unsigned num_cpus() const;
void affinity(Thread_capability, unsigned);
}; };
#endif /* _CPU_SESSION_COMPONENT_H_ */ #endif /* _CPU_SESSION_COMPONENT_H_ */

View File

@ -131,6 +131,11 @@ namespace Noux {
void single_step(Thread_capability thread, bool enable) { void single_step(Thread_capability thread, bool enable) {
_cpu.single_step(thread, enable); } _cpu.single_step(thread, enable); }
unsigned num_cpus() const {
return _cpu.num_cpus(); }
void affinity(Thread_capability thread, unsigned cpu) {
_cpu.affinity(thread, cpu); }
}; };
} }