summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorEmery Hemingway <githubjunk@spam.works>2017-09-16 01:02:59 -0500
committerAndreas Rumpf <rumpf_a@web.de>2017-09-16 08:02:59 +0200
commit9258672cee32ca82fcf1494447cd9020602df567 (patch)
treef197e714a836d6376557f49b0165af8baf786045 /lib
parent248caaf27eb67556aea23c3ceff204237d4df9c3 (diff)
downloadNim-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.h12
-rw-r--r--lib/system.nim3
-rw-r--r--lib/system/threads.nim9
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".}