For some reason, it works as intended if I pass a ptr Lock to the function
instead of initializing it inside the function:
proc test(lock: ptr Lock) =
parallelFor i in 0 ..< 10:
captures:{lock}
lock[].acquire()
echo i
lock[].release()
wh
I just noticed that the following code results in unexpected behavior.
Sometimes, the numbers are printed in random order to the console, sometimes
the program is stuck in the call to acquire with all cores close to 100% usage
and no output at all. Not sure if I'm doing something wrong, the only
Thanks for pointing that out, it's a really helpful example for me. I just
started getting into weave and laser recently and I'm pretty sure I would
sooner or later stumble over a similar problem. I'm planning on implementing
some algorithms using weave to compare performance of various programm
Due to the thread procedure trying to access the shared variable res directly.
In Nim thread procedures can't capture variables by closure as it may lead to
unsafe memory access. However, since res is of type Atomic[int], which is safe
for concurrent access, you can work around this by-passing r
In the future it would be nice for closures to auto-capture addresses and do
escape analysis / lifetime analysis.
Currently it's tedious to pass `var` parameters and `seq` buffers to closures
for compute.
For example this is a parallel "max" computation using Weave, and you need to
capture the
Thanks for your answers, I ended up doing what both of you suggested. I was
hoping to find a way to not use raw pointers explicitly but I guess it makes no
difference in the end.
Atomics means you can update them concurrently (solving race conditions) but
that's orthogonal to ownership (solving data races). You need to capture its
address
I'd say just turn it into a `Thread[a, b: int, c: ptr Atomic[int]]` you already
want to refer to the stack of the spawning thread. Threading does not allow
closure procedures, so you have to pass the 'environment' explicitly.
proc main() =
var threads: array[0..4, Thread[tuple[a, b: int]]]
var res: Atomic[int]
proc worker(interval: tuple[a, b: int]) {.gcsafe, nimcall, thread.} =
# loop over interval and compute some value
res += value
for i in 0..high(threads):