diff options
-rw-r--r-- | compiler/cgen.nim | 9 | ||||
-rw-r--r-- | lib/system/threads.nim | 38 | ||||
-rw-r--r-- | todo.txt | 1 |
3 files changed, 35 insertions, 13 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 8e20ba654..9e353f0ea 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -973,7 +973,7 @@ proc genMainProc(m: BModule) = "\tvoid (*volatile inner)();$N" & "\tsystemDatInit();$N" & "\tinner = PreMainInner;$N" & - "$4" & + "$4$5" & "\t(*inner)();$N" & "}$N$N" @@ -1065,7 +1065,12 @@ proc genMainProc(m: BModule) = else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") inc(m.labels) appcg(m, m.s[cfsProcs], PreMainBody, [ - mainDatInit, gBreakpoints, otherModsInit, initStackBottomCall]) + mainDatInit, gBreakpoints, otherModsInit, + if emulatedThreadVars() and platform.targetOS != osStandalone: + ropecg(m, "\t#initThreadVarsEmulation();$N") + else: + "".toRope, + initStackBottomCall]) appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)]) if optNoMain notin gGlobalOptions: diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 287c6db95..496c31af1 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -79,12 +79,20 @@ when defined(windows): type TThreadVarSlot = distinct int32 - proc threadVarAlloc(): TThreadVarSlot {. - importc: "TlsAlloc", stdcall, dynlib: "kernel32".} - proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. - importc: "TlsSetValue", stdcall, dynlib: "kernel32".} - proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. - importc: "TlsGetValue", stdcall, dynlib: "kernel32".} + when true: + proc threadVarAlloc(): TThreadVarSlot {. + importc: "TlsAlloc", stdcall, header: "<windows.h>".} + proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + importc: "TlsSetValue", stdcall, header: "<windows.h>".} + proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + importc: "TlsGetValue", stdcall, header: "<windows.h>".} + else: + proc threadVarAlloc(): TThreadVarSlot {. + importc: "TlsAlloc", stdcall, dynlib: "kernel32".} + proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + importc: "TlsSetValue", stdcall, dynlib: "kernel32".} + proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + importc: "TlsGetValue", stdcall, dynlib: "kernel32".} else: {.passL: "-pthread".} @@ -174,7 +182,18 @@ type # XXX it'd be more efficient to not use a global variable for the # thread storage slot, but to rely on the implementation to assign slot X # for us... ;-) -var globalsSlot = threadVarAlloc() +var globalsSlot: TThreadVarSlot + +when not defined(useNimRtl): + when not useStackMaskHack: + var mainThread: TGcThread + +proc initThreadVarsEmulation() {.compilerProc, inline.} = + when not defined(useNimRtl): + globalsSlot = threadVarAlloc() + when declared(mainThread): + threadVarSetValue(globalsSlot, addr(mainThread)) + #const globalsSlot = TThreadVarSlot(0) #sysAssert checkSlot.int == globalsSlot.int @@ -192,11 +211,8 @@ when useStackMaskHack: # create for the main thread. Note: do not insert this data into the list # of all threads; it's not to be stopped etc. when not defined(useNimRtl): - when not useStackMaskHack: - var mainThread: TGcThread - threadVarSetValue(globalsSlot, addr(mainThread)) - when not defined(createNimRtl): initStackBottom() + #when not defined(createNimRtl): initStackBottom() initGC() when emulatedThreadVars: diff --git a/todo.txt b/todo.txt index a6ea31560..e0d6313b3 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 0.10 ============ +showstopper: Nim does not boot with --threads:on! - make nimble part of the distribution - implement 'procCall' - split idetools into separate tool |