Files
Nim/lib/genode_cpp/threads.h
Emery Hemingway 9258672cee balance Genode CPU pinning, deadlock at Genode exit (#6317)
* Genode: balance thread CPU affinities
Genode threads are pinned by defaut to the same CPU as the initial
component entrypoint thread. Thread affinities are also permanent. This
patch pins new threads to CPUs in a round-robin manner. Arbitrary CPU
pinning is not exposed and the 'nimPinToCpu' has no effect.

* Genode: guarantee that 'quit' will not return
On Genode exits are handled by whatever component is acting as parent.
The caller has no guarentee that the parent implementation will halt the
caller's threads, so explicitly deadlock the 'quit' procedure.
2017-09-16 08:02:59 +02:00

73 lines
1.6 KiB
C++

/*
*
* Nim's Runtime Library
* (c) Copyright 2017 Emery Hemingway
*
* See the file "copying.txt", included in this
* distribution, for details about the copyright.
*
*/
#ifndef _GENODE_CPP__THREAD_H_
#define _GENODE_CPP__THREAD_H_
#include <base/thread.h>
#include <util/reconstructible.h>
namespace Nim { struct SysThread; }
struct Nim::SysThread
{
typedef void (Entry)(void*);
struct Thread : Genode::Thread
{
void *_tls;
Entry *_func;
void *_arg;
void entry() override {
(_func)(_arg); }
Thread(Genode::Env &env, Genode::size_t stack_size, Entry func, void *arg, int affinity)
: Genode::Thread(env, "nim-thread", stack_size,
env.cpu().affinity_space().location_of_index(affinity),
Genode::Cpu_session::Weight(Genode::Cpu_session::Weight::DEFAULT_WEIGHT-1),
env.cpu()),
_func(func), _arg(arg)
{
Genode::Thread::start();
}
};
Genode::Constructible<Thread> _thread;
void initThread(Genode::Env *env, Genode::size_t stack_size, Entry func, void *arg, int aff) {
_thread.construct(*env, stack_size, func, arg, aff); }
void joinThread() {
_thread->join(); }
static bool offMainThread() {
return dynamic_cast<SysThread::Thread*>(Genode::Thread::myself()); }
static void *threadVarGetValue()
{
SysThread::Thread *thr =
static_cast<SysThread::Thread*>(Genode::Thread::myself());
return thr->_tls;
}
static void threadVarSetValue(void *value)
{
SysThread::Thread *thr =
static_cast<SysThread::Thread*>(Genode::Thread::myself());
thr->_tls = value;
}
};
#endif