proper fix for stack initialization and threadvar emulation
This commit is contained in:
parent
81353b2dbc
commit
af84f754b0
3 changed files with 35 additions and 13 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue