diff options
author | Emery Hemingway <githubjunk@spam.works> | 2017-09-16 01:02:59 -0500 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-09-16 08:02:59 +0200 |
commit | 9258672cee32ca82fcf1494447cd9020602df567 (patch) | |
tree | f197e714a836d6376557f49b0165af8baf786045 /lib | |
parent | 248caaf27eb67556aea23c3ceff204237d4df9c3 (diff) | |
download | Nim-9258672cee32ca82fcf1494447cd9020602df567.tar.gz |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/genode_cpp/threads.h | 12 | ||||
-rw-r--r-- | lib/system.nim | 3 | ||||
-rw-r--r-- | lib/system/threads.nim | 9 |
3 files changed, 17 insertions, 7 deletions
diff --git a/lib/genode_cpp/threads.h b/lib/genode_cpp/threads.h index 043f808f1..a7cb2f17b 100644 --- a/lib/genode_cpp/threads.h +++ b/lib/genode_cpp/threads.h @@ -31,8 +31,12 @@ struct Nim::SysThread void entry() override { (_func)(_arg); } - Thread(Genode::Env &env, Genode::size_t stack_size, Entry func, void *arg) - : Genode::Thread(env, "nim-thread", stack_size), _func(func), _arg(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(); } @@ -40,8 +44,8 @@ struct Nim::SysThread Genode::Constructible<Thread> _thread; - void initThread(Genode::Env *env, Genode::size_t stack_size, Entry func, void *arg) { - _thread.construct(*env, stack_size, func, arg); } + 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(); } diff --git a/lib/system.nim b/lib/system.nim index 157f32387..39f65c5a3 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1435,7 +1435,8 @@ when defined(nimdoc): elif defined(genode): proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn, - importcpp: "genodeEnv->parent().exit(@)", header: "<base/env.h>".} + importcpp: "genodeEnv->parent().exit(@); Genode::sleep_forever()", + header: "<base/sleep.h>".} else: proc quit*(errorcode: int = QuitSuccess) {. diff --git a/lib/system/threads.nim b/lib/system/threads.nim index a7a811844..96c045e6b 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -127,7 +127,8 @@ elif defined(genode): proc initThread(s: var SysThread, stackSize: culonglong, entry: GenodeThreadProc, - arg: pointer) {. + arg: pointer, + affinity: cuint) {. importcpp: "#.initThread(genodeEnv, @)".} proc threadVarAlloc(): ThreadVarSlot = 0 @@ -567,6 +568,9 @@ when hostOS == "windows": setThreadAffinityMask(t.sys, uint(1 shl cpu)) elif defined(genode): + var affinityOffset: cuint = 1 + # CPU affinity offset for next thread, safe to roll-over + proc createThread*[TArg](t: var Thread[TArg], tp: proc (arg: TArg) {.thread, nimcall.}, param: TArg) = @@ -577,7 +581,8 @@ elif defined(genode): when hasSharedHeap: t.stackSize = ThreadStackSize t.sys.initThread( ThreadStackSize.culonglong, - threadProcWrapper[TArg], addr(t)) + threadProcWrapper[TArg], addr(t), affinityOffset) + inc affinityOffset proc pinToCpu*[Arg](t: var Thread[Arg]; cpu: Natural) = {.hint: "cannot change Genode thread CPU affinity after initialization".} |