Thread-safe attribution

Manu turkeyman at gmail.com
Sun Oct 7 04:16:43 UTC 2018


On Sat, Oct 6, 2018 at 8:10 PM Stanislav Blinov via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> On Sunday, 7 October 2018 at 02:01:17 UTC, Manu wrote:
>
> >> The thing I'm trying to model is an attribute along the lines
> >> of
> >> `shared`, but actually useful ;)
> >> I'll use the attribute `threadsafe` in place of `shared`, and
> >> see
> >> where that goes.
> >>
> >> Consider:
> >> struct Bob
> >> {
> >>   int x;
> >>   threadsafe Atomic!int y;
>
> Storing shared and local data together? Ew, cache poison. Be that
> as it may, given that definition:

I don't think mixing would happen in practise, but the rules need to be defined.

> 1. Can you copy Bob or assign to it? If so, how?
> 2. Can Bob have a destructor? Who calls it if it can?

If they're mutable, sure.
If Bob was threadsafe, then it would have to have a matching
attributed constructor.destructor/copy-ctor, etc.

> >>   x.m1(); // ERROR, method not threadsafe
> >>   x.m2(); // fine
> >>   x.overloaded(); // fine, use the threadsafe overload
>
> I guess these three should be y., not x.?

Yes, sorry.


> >>   threadsafe Bob* p = &x; // can take threadsafe reference to
> >> thread-local object
>
> I'm not sure what's that supposed to accomplish. It looks like a
> silent cast, which is already a red flag. What is the purpose of
> this?

This is the primitive that allows calling a threadsafe method.
You can call a const method because of this same mechanic.

> Give that pointer to another thread while the original
> continues to treat 'x' as thread-local? I.e. if the arguments
> were indeed `ref`, the caller would be blissfully unaware of such
> a "transaction" taking place.

I'm going to move to the position from the most recent post in the
thread (you are responding to the first post).
If shared instances were unable to access their members, then it's
possible that you *could* pass this to another thread (I don't think
you should, but I don't think it's dangerous anymore).
Any shared instance to the object is not able to mutate the object...
they would need to case shared away, which is unsafe... they would
need to do that deliberately by acquiring a lock, or by whatever other
mechanism gives them temporary thread-local access to the object.

> >> This is loosely what `shared` models, but there's a few
> >> differences:
> >> 1. thread-local can NOT promote to shared
> >> 2. shared `this` applies to members
> >>
> >> For `shared` to be useful, it should be that a shared
> >> reference to something inhibits access to it's thread-local
> >> stuff. And in that world, then I believe that thread-local
> >> promotion to shared would work like const does.
> >>
> >> I guess I'm wondering; should `shared` be transitive? Perhaps
> >> that's what's wrong with it...?
>
> IHMO, `shared` should be transitive, but... most uses of `shared`
> should just boil down to primitive types (i.e. atomics) and
> pointers to shared primitives and structs. With dereferencing
> latter requiring to be synchronized, casting away `shared` in the
> process, and I don't see how the language as it is can help with
> that, as accessing different kinds of data requires different
> code. We can't just stuff all the nuances of thread-safety and
> multi-core communication into one keyword, whatever that keyword
> may be.
> What could be the static (compile-time) guarantees of
> `threadsafe` methods?

We're not trying to 'stuff the nuances' into a keyword... what I'm
trying to achieve is a mechanism for attributing that a function has
implemented thread-safety *in some way*, and how that works is a
detail for the function.
What the attribute needs to do, is control the access rights to the
object appropriately, so that if you're in custody of a shared object,
you should exclusively be limited to performing guaranteed thread-safe
operations on the object, OR, you must perform synchronisation and
cast shared away (as is current use of shared).

You need to read the rest of the thread... I've moved on from this initial post.
I agree, shared must be transitive, but I think the effect that it
can't access un-shared members may be the innovation we're looking for
which will make shared useful.


More information about the Digitalmars-d mailing list