proper fix for stack initialization and threadvar emulation

This commit is contained in:
Araq 2014-11-11 09:55:31 +01:00
commit af84f754b0
3 changed files with 35 additions and 13 deletions

View file

@ -973,7 +973,7 @@ proc genMainProc(m: BModule) =
"\tvoid (*volatile inner)();$N" & "\tvoid (*volatile inner)();$N" &
"\tsystemDatInit();$N" & "\tsystemDatInit();$N" &
"\tinner = PreMainInner;$N" & "\tinner = PreMainInner;$N" &
"$4" & "$4$5" &
"\t(*inner)();$N" & "\t(*inner)();$N" &
"}$N$N" "}$N$N"
@ -1065,7 +1065,12 @@ proc genMainProc(m: BModule) =
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N") else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
inc(m.labels) inc(m.labels)
appcg(m, m.s[cfsProcs], PreMainBody, [ 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)]) appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)])
if optNoMain notin gGlobalOptions: if optNoMain notin gGlobalOptions:

View file

@ -79,12 +79,20 @@ when defined(windows):
type type
TThreadVarSlot = distinct int32 TThreadVarSlot = distinct int32
proc threadVarAlloc(): TThreadVarSlot {. when true:
importc: "TlsAlloc", stdcall, dynlib: "kernel32".} proc threadVarAlloc(): TThreadVarSlot {.
proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. importc: "TlsAlloc", stdcall, header: "<windows.h>".}
importc: "TlsSetValue", stdcall, dynlib: "kernel32".} proc threadVarSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {.
proc threadVarGetValue(dwTlsIndex: TThreadVarSlot): pointer {. importc: "TlsSetValue", stdcall, header: "<windows.h>".}
importc: "TlsGetValue", stdcall, dynlib: "kernel32".} 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: else:
{.passL: "-pthread".} {.passL: "-pthread".}
@ -174,7 +182,18 @@ type
# XXX it'd be more efficient to not use a global variable for the # 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 # thread storage slot, but to rely on the implementation to assign slot X
# for us... ;-) # 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) #const globalsSlot = TThreadVarSlot(0)
#sysAssert checkSlot.int == globalsSlot.int #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 # create for the main thread. Note: do not insert this data into the list
# of all threads; it's not to be stopped etc. # of all threads; it's not to be stopped etc.
when not defined(useNimRtl): when not defined(useNimRtl):
when not useStackMaskHack: when not useStackMaskHack:
var mainThread: TGcThread #when not defined(createNimRtl): initStackBottom()
threadVarSetValue(globalsSlot, addr(mainThread))
when not defined(createNimRtl): initStackBottom()
initGC() initGC()
when emulatedThreadVars: when emulatedThreadVars:

View file

@ -1,6 +1,7 @@
version 0.10 version 0.10
============ ============
showstopper: Nim does not boot with --threads:on!
- make nimble part of the distribution - make nimble part of the distribution
- implement 'procCall' - implement 'procCall'
- split idetools into separate tool - split idetools into separate tool