support for the Genode OS framework (#5560)

This commit is contained in:
Emery Hemingway 2017-03-31 16:13:06 -05:00 • committed by Andreas Rumpf
commit 7e351fc7fa
14 changed files with 348 additions and 33 deletions

View file

@ -46,7 +46,11 @@ const
maxRegisters = 256 # don't think there is an arch with more registers
useStackMaskHack = false ## use the stack mask hack for better performance
StackGuardSize = 4096
ThreadStackMask = 1024*256*sizeof(int)-1
ThreadStackMask =
when defined(genode):
1024*64*sizeof(int)-1
else:
1024*256*sizeof(int)-1
ThreadStackSize = ThreadStackMask+1 - StackGuardSize
when defined(windows):
@ -115,6 +119,49 @@ when defined(windows):
## get the ID of the currently running thread.
result = int(getCurrentThreadId())
elif defined(genode):
const
GenodeHeader = "genode_cpp/threads.h"
type
SysThread* {.importcpp: "Nim::SysThread",
header: GenodeHeader, final, pure.} = object
GenodeThreadProc = proc (x: pointer) {.noconv.}
ThreadVarSlot = int
proc initThread(s: var SysThread,
stackSize: culonglong,
entry: GenodeThreadProc,
arg: pointer) {.
importcpp: "#.initThread(genodeEnv, @)".}
proc threadVarAlloc(): ThreadVarSlot = 0
proc offMainThread(): bool {.
importcpp: "Nim::SysThread::offMainThread",
header: GenodeHeader.}
proc threadVarSetValue(value: pointer) {.
importcpp: "Nim::SysThread::threadVarSetValue(@)",
header: GenodeHeader.}
proc threadVarGetValue(): pointer {.
importcpp: "Nim::SysThread::threadVarGetValue()",
header: GenodeHeader.}
var mainTls: pointer
proc threadVarSetValue(s: ThreadVarSlot, value: pointer) {.inline.} =
if offMainThread():
threadVarSetValue(value);
else:
mainTls = value
proc threadVarGetValue(s: ThreadVarSlot): pointer {.inline.} =
if offMainThread():
threadVarGetValue();
else:
mainTls
else:
when not defined(macosx):
{.passL: "-pthread".}
@ -451,6 +498,9 @@ when defined(windows):
proc threadProcWrapper[TArg](closure: pointer): int32 {.stdcall.} =
threadProcWrapperBody(closure)
# implicitly return 0
elif defined(genode):
proc threadProcWrapper[TArg](closure: pointer) {.noconv.} =
threadProcWrapperBody(closure)
else:
proc threadProcWrapper[TArg](closure: pointer): pointer {.noconv.} =
threadProcWrapperBody(closure)
@ -482,6 +532,14 @@ when hostOS == "windows":
cast[ptr SysThread](addr(a)), 1, -1)
inc(k, MAXIMUM_WAIT_OBJECTS)
elif defined(genode):
proc joinThread*[TArg](t: Thread[TArg]) {.importcpp.}
## waits for the thread `t` to finish.
proc joinThreads*[TArg](t: varargs[Thread[TArg]]) =
## waits for every thread in `t` to finish.
for i in 0..t.high: joinThread(t[i])
else:
proc joinThread*[TArg](t: Thread[TArg]) {.inline.} =
## waits for the thread `t` to finish.
@ -531,6 +589,21 @@ when hostOS == "windows":
## shouldn't use this proc.
setThreadAffinityMask(t.sys, uint(1 shl cpu))
elif defined(genode):
proc createThread*[TArg](t: var Thread[TArg],
tp: proc (arg: TArg) {.thread, nimcall.},
param: TArg) =
when TArg isnot void: t.data = param
t.dataFn = tp
when hasSharedHeap: t.stackSize = ThreadStackSize
t.sys.initThread(
ThreadStackSize.culonglong,
threadProcWrapper[TArg], addr(t))
proc pinToCpu*[Arg](t: var Thread[Arg]; cpu: Natural) =
{.hint: "cannot change Genode thread CPU affinity after initialization".}
discard
else:
proc createThread*[TArg](t: var Thread[TArg],
tp: proc (arg: TArg) {.thread, nimcall.},