The runtime --gc:arc says that it offers a shared heap. So, is there still a thread-local heap when using this runtime? When using --gc:arc, I found that the memory allocated by alloc0() is not reclaimed when the thread exits. Is the memory allocated by alloc0() in a shared heap?
And this is my code:
import std/os
type
Data = object
val: int
var tag = 0
var data: ptr Data
proc threadAFunc() {.thread.} =
while tag != 0: continue # at A (1)
echo data == nil # Output: true
tag = 1 # to B (1)
while tag != 0: continue # at A (2)
echo data.val # Output: 1
tag = 1 # to B (2)
while tag != 0: continue # at A (3)
echo data.val # Output: 1
sleep(100)
echo data == nil # Output: false
echo data.val # Output (arc): SIGSEGV: Illegal storage access.
# Output (refc): 1
proc threadBFunc() {.thread.} =
while tag != 1: continue # at B (1)
data = cast[ptr Data](alloc0(sizeof(Data)))
data.val = 1
tag = 0 # to A (2)
while tag != 1: continue # at B (2)
tag = 0 # to A (3)
proc main() =
var threadA: Thread[void]
var threadB: Thread[void]
createThread(threadA, threadAFunc)
createThread(threadB, threadBFunc)
joinThread(threadB)
joinThread(threadA)
main()
$ nim c -r --threads:on --gc:refc test.nim
true
1
1
false
Traceback (most recent call last)
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
$ nim c -r --threads:on --gc:arc test.nim
true
1
1
false
1
Ah, good question. One more point to cover in my upcoming ARC article. So when you use --gc:arc --threads:on the allocations done for seqs, closures, refs etc are shared. The distinction between alloc vs allocShared remains. However, alloc is mapped to malloc when you use -d:useMalloc and malloc always uses a global, shared heap.
Btw your test program is completely wrong, reading from freed memory could produce any outcome.