Add `tearDownForeignThreadGc` function (#5369)
This commit is contained in:
parent
279e4b0451
commit
6fa1dba515
5 changed files with 132 additions and 10 deletions
|
|
@ -128,13 +128,7 @@ iterator items(stack: ptr GcStack): ptr GcStack =
|
|||
yield s
|
||||
s = s.next
|
||||
|
||||
# There will be problems with GC in foreign threads if `threads` option is off or TLS emulation is enabled
|
||||
const allowForeignThreadGc = compileOption("threads") and not compileOption("tlsEmulation")
|
||||
|
||||
when allowForeignThreadGc:
|
||||
var
|
||||
localGcInitialized {.rtlThreadVar.}: bool
|
||||
|
||||
when declared(threadType):
|
||||
proc setupForeignThreadGc*() {.gcsafe.} =
|
||||
## Call this if you registered a callback that will be run from a thread not
|
||||
## under your control. This has a cheap thread-local guard, so the GC for
|
||||
|
|
@ -143,16 +137,33 @@ when allowForeignThreadGc:
|
|||
##
|
||||
## This function is available only when ``--threads:on`` and ``--tlsEmulation:off``
|
||||
## switches are used
|
||||
if not localGcInitialized:
|
||||
localGcInitialized = true
|
||||
if threadType == ThreadType.None:
|
||||
initAllocator()
|
||||
var stackTop {.volatile.}: pointer
|
||||
setStackBottom(addr(stackTop))
|
||||
initGC()
|
||||
threadType = ThreadType.ForeignThread
|
||||
|
||||
proc tearDownForeignThreadGc*() {.gcsafe.} =
|
||||
## Call this to tear down the GC, previously initialized by ``setupForeignThreadGc``.
|
||||
## If GC has not been previously initialized, or has already been torn down, the
|
||||
## call does nothing.
|
||||
##
|
||||
## This function is available only when ``--threads:on`` and ``--tlsEmulation:off``
|
||||
## switches are used
|
||||
if threadType != ThreadType.ForeignThread:
|
||||
return
|
||||
when declared(deallocOsPages): deallocOsPages()
|
||||
threadType = ThreadType.None
|
||||
when declared(gch): zeroMem(addr gch, sizeof(gch))
|
||||
|
||||
else:
|
||||
template setupForeignThreadGc*() =
|
||||
{.error: "setupForeignThreadGc is available only when ``--threads:on`` and ``--tlsEmulation:off`` are used".}
|
||||
|
||||
template tearDownForeignThreadGc*() =
|
||||
{.error: "tearDownForeignThreadGc is available only when ``--threads:on`` and ``--tlsEmulation:off`` are used".}
|
||||
|
||||
# ----------------- stack management --------------------------------------
|
||||
# inspired from Smart Eiffel
|
||||
|
||||
|
|
|
|||
|
|
@ -285,7 +285,19 @@ when useStackMaskHack:
|
|||
when not defined(useNimRtl):
|
||||
when not useStackMaskHack:
|
||||
#when not defined(createNimRtl): initStackBottom()
|
||||
when declared(initGC): initGC()
|
||||
when declared(initGC):
|
||||
initGC()
|
||||
when not emulatedThreadVars:
|
||||
type ThreadType {.pure.} = enum
|
||||
None = 0,
|
||||
NimThread = 1,
|
||||
ForeignThread = 2
|
||||
var
|
||||
threadType {.rtlThreadVar.}: ThreadType
|
||||
|
||||
threadType = ThreadType.NimThread
|
||||
|
||||
|
||||
|
||||
when emulatedThreadVars:
|
||||
if nimThreadVarsSize() > sizeof(ThreadLocalStorage):
|
||||
|
|
@ -442,6 +454,8 @@ proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) =
|
|||
# init the GC for refc/markandsweep
|
||||
setStackBottom(addr(p))
|
||||
initGC()
|
||||
when declared(threadType):
|
||||
threadType = ThreadType.NimThread
|
||||
when declared(registerThread):
|
||||
thrd.stackBottom = addr(thrd)
|
||||
registerThread(thrd)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue