Hi there,

I have a few questions about what is safe to assume when writing concurrent code in D with data sharing (as opposed to message passing).

After doing a fair amount of reading, I'm still slightly hazy about what shared does and doesn't guarantee. Here is the only assumption I understand to be valid:

* Reads and writes to shared variables with a size equal to or less than the word size of the machine are atomic and are visible to all other threads immediately.

Now, in Andrei's D book he also states that sequential consistency is guaranteed for operations on shared data, however I understand that this is not currently implemented by (any?) compiler and perhaps never will be, what with the discussions about making changes to the semantics of shared and all.

So then this code is not safe, assuming the methods are executed on different threads:

shared int x = 0;
shared bool complete = false;

void foo()
{
    x = 7; // atomic
    complete = true; // atomic
}

void bar()
{
    while (!complete) {}

    writeln(x); // undefined output (0 or 7)
}

But then I understand the core.atomic module incorporates the necessary memory barriers to make this work, so we can replace foo() by:

void foo()
{
    x.atomicStore(7);
    complete.atomicStore(true);
}

and achieve the intended behaviour (maybe only one of those two modifications were actually needed here?). Or possibly:

void foo()
{
    x = 7; // atomic
    atomicFence(); // from core.atomic again
    complete = true; // atomic
}

Do these modifications achieve the desired result? I know there are other ways to go about this. I think one (bad) way is putting a mutex around every read/write (a mutex also acts as a memory barrier, right?), and I suppose in this case, message passing! (But let's pretend the data sharing is more complex)

My other question about shared is: what does the shared qualifier mean when applied to a class definition? e.g.

shared class Cat {...}

Does it just force all references to Cat instances to be shared by default and make all methods of Cat shared? Andrei uses it in his book when talking about lock-free programming with cas, however he seems to make the assumption (well, explicitly states) that sequential consistency is assured within the methods of such a class. I'm quite confused about what it actually means, especially since shared apparently does not currently use memory barriers.

Reply via email to