shared - no read/write access

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Apr 4 05:08:21 UTC 2019


On Tuesday, April 2, 2019 5:37:20 AM MDT Kagamin via Digitalmars-d wrote:
> On Sunday, 31 March 2019 at 07:12:08 UTC, Jonathan M Davis wrote:
> > If the compiler can guarantee thread-safety, then there
> > shouldn't be a problem, and nothing needs to be made illegal,
> > but that's usually not the case. The primary exception would be
> > stuff like atomics, and that's typed with shared, so you can
> > pass shared variables to them. And it's not a problem, because
> > thread-safety is guaranteed.
>
> False sense of thread safety already? Code is not magically
> thread safe because it uses atomics, they are only a tool. Thread
> safety is a global property and can't be easily provided on low
> level alone. But added churn can increase mistakes because of
> increased cognitive load.

Atomics guarantee that the read/write operations are thread-safe, but no
they obviously can't guarantee things like that a set of interrelated
variables whose values should be kept in sync are actually protected against
multiple threads mucking with them at once. So, maybe a better way to put it
is that the compiler won't allow operations that it can't guarantee are
atomic (or which are marked shared).

> > In the cases where synchronization _is_ needed, then those
> > operations should be illegal, requiring the programmer to
> > protect the object appropriately and then cast away shared to
> > operate on it while it's protected. That way, nothing marked as
> > shared is violating thread-safety, and the code where there is
> > a risk of violating thread-safety is @system. So, it becomes
> > fairly easy to grep for the portions of the code where you need
> > to worry about threading bugs.
>
> @safe code might be disallowed to access shared data, that's
> understandable, but like for @system, it's difficult to provide
> protection for shared code that can pull its weight.
>
> Also greppability implies that casting away shared is not really
> inevitable, it's needed if you want to apply algorithm that was
> written for thread local data, but keeping data and methods as
> shared will help communicate that it's not an ordinary thing
> happening here (a use case for private shared methods).

Greppability just means that you can easily find the code in question, and
between the keywords shared, cast, @trusted, and @system, it should be easy
to quickly narrow down the code that involves casting away shared and thus
find the code that has to be closely examined for threading issues. And code
involving atomics is easily greppable - and thus easily findable - for the
same reason.

And no, it shouldn't be the case that everything using a shared variable has
to constantly cast away shared to do anything with it, because those
operations can be encapsulated in functions - a prime example of that being
an object that has its own mutex to protect its data. Nothing using the
object would need to cast away shared, but internally, that's exactly what
the object would need to do in order to actually mutate the data. That's
already true to an extent, because some read/write operations are illegal on
shared objects and have been for some time. The problem is that they aren't
all illegal. So, instead of the whole thing being set up so that you clearly
have to cast away shared to mutate data, you end up only having to cast it
away some of the time, just increasing the annoyance factor. Either we need
to go all the way and make all non-atomic read/write operations illegal on
shared data or just give up on shared providing any protections at all
beyond ensuring that code not involving casts can't make the type system
treat shared data as thread-local or vice versa.

- Jonathan M Davis





More information about the Digitalmars-d mailing list