diff options
Diffstat (limited to 'lib/system/threads.nim')
-rw-r--r-- | lib/system/threads.nim | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/lib/system/threads.nim b/lib/system/threads.nim index dc9cc9656..4855a2b93 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -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.}, |