DIP 1024--Shared Atomics--Community Review Round 1

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Oct 16 19:04:15 UTC 2019

On Wednesday, October 16, 2019 12:43:30 PM MDT Gregor Mückl via Digitalmars-
d wrote:
> On Tuesday, 15 October 2019 at 11:28:24 UTC, Ola Fosheim Grøstad
> wrote:
> > On Tuesday, 15 October 2019 at 10:25:54 UTC, Gregor Mückl wrote:
> >> generated by at most one of the running threads. So there is
> >> no need to synchronize memory writes when the underlying
> >> hardware architecture provides sufficient cache coherency
> >> guarantees.
> >
> > So what you basically is saying is that a low level language
> > should be careful about assuming a particular hardware model
> > and leave more to intrinsics and libraries. I think that is
> > reasonable, because hardware does change and concurrent
> > programming strategies change.
> I'm not sure if this is quite what I'm saying. I guess I'm fine
> with the compiler telling me that a piece of code tries to access
> shared data without any annotation that this is what is desired.
> In my opinion, it then needs to be up to the developer to deal
> with this. It is *not* OK for the compiler to go and secretly
> insert synchronization mechanisms (memory barriers, atomic
> operations, etc...) behind the developer's back. If such an
> automatism must exist, it also must be invoked by the developer
> explicitly ("Computer, generate automatic synchronization!"). And
> there must be a way to tell the compiler that the developer is a
> responsible adult who knows what he/she is doing and that the
> code is OK for reasons unknown to the compiler.

The DIP is not clear on the matter and needs to be updated, but Walter has
made it clear in his comments that there is no plan to even insert
core.atomic calls for you. Reading and writing to shared data is going to be
illegal, requiring that the programmer either explicitly use core.atomic or
that they cast away shared (rendering that part of the code @system, thereby
segregating the code that the programmer has to verify for thread safety).

It is conceivable that someone will come up with a feature that will allow
the compiler to implicitly remove shared under some set of circumstances,
because it's able to see that only one thread can access that data at that
point (e.g. TDPL's synchronized classes would be able to do this to the
outer layer of shared for the member variables of that class), but that
would just be an improvement on top of what Walter is proposing, and
honestly, I doubt that we'll ever see much along those lines, because making
such compiler guarantees is very difficult with D's type system (e.g. TDPL's
synchronized classes lock the type down quite a lot and yet are still only
able to remove a single layer of shared, making them borderline useless, and
AFAIK, no one has yet proposed anything that could do better). The type
system would likely need a concept of thread ownership to safely reason
about much with regards to shared, and even if the compiler _were_ able to
implicitly remove shared under some set of circumstances, there's no way
that it's going to understand all of the various threading mechanisms that
get used in code. So, at best, you'd be able to use a particular feature to
have a piece of code implicitly remove shared, because the compiler is able
to do it for that particular idiom. There's no question that the programmer
is going to have to cast away shared in many cases in order to actually
operate on shared data.

And once the programmer casts away shared, that code is then @system,
requiring the programmer to vet it and certify that it's actually @safe by
using @trusted. So, all of the code that operates on shared data should then
be in three camps:

1. It uses core.atomic.

2. It casts away shared and is thus @system.

3. It involves shared member functions which then do either #1 or #2

Andrei has talked in the past about inserting magic to make shared "just
work" without casting, but I think that it's pretty clear at this point that
that isn't going to work. The best that we could do would be to make some
operations which are guaranteed to be atomic allowed on shared primitive
types, and that would be a questionable choice for a variety of reasons.
Either way, it's not currently the plan to do so.

- Jonathan M Davis

More information about the Digitalmars-d mailing list