I was developing some code using Malebolgia and found an unexpected problem.
This example code crashes crashes about 80% of the time when I run it:
type Svec* = ref array[19,float]
proc subfn( svec:Svec ) = discard 0
proc fn( svec:ptr Svec ) =
let svec = svec[]
subfn(svec)
#the above 2 lines lead to crashes, but this does not:
#subfn(svec[])
import malebolgia
proc test() =
var sv = new Svec
var m = createMaster()
m.awaitAll:
for i in 0..99:
m.spawn fn(sv.addr)
echo "hello"
for i in 0..77:
test()
echo "ok"
But when I replace the lines
let svec = svec[]
subfn(svec)
with
subfn(svec[])
then it runs perfectly.
I guess the problem is that the thread is freeing the memory associated with the local variable?
If this behaviour is unexpected then please confirm and I will report it as a bug.
(Nim v2.0.2 with compiler flags -mm:arc -d:ThreadPoolSize=40 -d:useMalloc were used)
When you create a variable of a ref type, the reference count should increased by one. However, other threads may try to do so at the same time, which is leads to undefined behavior. This multithreading-related problem is called a "data race."
Hint: --mm:atomicArc
You can also use cursor pragma inside the function so that it doesn't mess with the ref counts
let svec {.cursor.} = svec[]