summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/cgen.nim9
-rw-r--r--lib/system/threads.nim38
-rw-r--r--todo.txt1
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