shared - i need it to be useful
Stanislav Blinov
stanislav.blinov at gmail.com
Thu Oct 18 19:01:20 UTC 2018
On Thursday, 18 October 2018 at 18:24:47 UTC, Manu wrote:
> I have demonstrated these usability considerations in
> production. I am
> confident it's the right balance.
Then convince us. So far you haven't.
> I propose:
> 1. Normal people don't write thread-safety, a very small
> number of
> unusual people do this. I feel very good about biasing 100% of
> the
> cognitive load INSIDE the shared method. This means the expert,
> and
> ONLY the expert, must make decisions about thread-safety
> implementation.
No argument.
> 2. Implicit conversion allows users to safely interact with
> safe
> things without doing unsafe casts. I think it's a complete
> design fail
> if you expect any user anywhere to perform an unsafe cast to
> call a
> perfectly thread-safe function. The user might not properly
> understand
> their obligations.
Disagreed. "Normal" people wouldn't be doing any unsafe casts and
*must not be able to* do something as unsafe as silent promotion
of thread-local mutable data to shared. But it's perfectly fine
for the "expert" user to do such a promotion, explicitly.
> 3. The practical result of the above is, any complexity
> relating to
> safety is completely owned by the threadsafe author, and not
> cascaded
> to the user. You can't expect users to understand, and make
> correct
> decisions about threadsafety. Safety should be default position.
Exactly. And an implicit conversion from mutable to shared isn't
safe at all.
> I recognise the potential loss of an unsafe optimised
> thread-local path.
> 1. This truly isn't a big deal. If this is really hurting you,
> you
> will notice on the profiler, and deploy a thread-exclusive path
> assuming the context supports it.
> 2. I will trade that for confidence in safe interaction every
> day of
> the week. Safety is the right default position here.
Does not compute. Either you're an "expert" from above and live
with that burden, or you're not.
> 2. You just need to make the unsafe thread-exclusive variant
> explicit, eg:
>
>> struct ThreadSafe
>> {
>> private int x;
>> void unsafeIncrement() // <- make it explicit
>> {
>> ++x; // User has asserted that no sharing is possible,
>> no reason to use atomics
>> }
>> void increment() shared
>> {
>> atomicIncrement(&x); // object may be shared
>> }
>> }
No. The above code is not thread-safe at all. The private int
*must* be declared shared. Then it becomes:
struct ThreadSafe {
// These must be *required* if you want to assert any thread
safety. Be nice
// if the compiler did that for us.
@disable this(this);
@disable void opAssign(typeof(this));
private shared int x; // <- *must* be shared
void unsafeIncrement() @system {
x.assumeUnshared += 1;
}
// or deduced:
void unsafeIncrement()() // assumeUnshared must be @system,
thus this unsafeIncrement will also be deduced @system
{
x.assumeUnshared += 1;
}
void increment() shared {
x.atomicOp!"+="(1);
}
}
> I think this is quiet a reasonable and clearly documented
> compromise.
With the fixes above, it is. Without them, it will only be
apparent from documentation, and who writes, or reads, that?..
> I think absolutely-reliably-threadsafe-by-default is the right
> default position.
But it is exactly the opposite of automatic promotions from
mutable to shared!
More information about the Digitalmars-d
mailing list