I'm having a heck of a time trying to get the barrier sync in D to work properly. I'm currently not getting any compiler errors, however every time it reaches the barrier I get a segmentation fault. Here's basically what I have:
import std.stdio;
import std.conv;
import std.concurrency;
import core.thread;
import core.sync.barrier;
//create barrier
Barrier barrier;
void the_thread()
{
barrier.wait(); //I get a segmentation fault here
}
void main(string[] args)
{
int threads = to!int(args[1]); //number of threads
//init barrier
barrier = new Barrier(threads);
//launch threads
foreach(i; 0 .. threads)
{
spawn(&the_thread);
}
thread_joinAll();
}
I've tried defining the barrier completely in the main function, but dmd complains:
static assert "Aliases to mutable thread-local data not allowed."
I've also tried passing it as a shared variable and I get this:
non-shared method core.sync.barrier.Barrier.wait is not callable using a shared object
Global variables are thread-local by default in D. When you set barrier
in your main thread, you only set it in the main thread; for the other threads, barrier
will be null
.
You can mark barrier
as __gshared
to make it thread-global, though it's a bit of a hack:
__gshared Barrier barrier;
The thread spawn function only allows passing data marked as shared
, as you've discovered. However, since the Barrier.wait
function is not marked as shared
, you can't call it with a shared(Barrier)
object, making it mostly useless. As another hack, you can cast it to unshared first before calling wait
:
(cast()barrier).wait();