synchronized class bugs?
IGotD-
nise at nise.com
Tue Apr 7 16:11:12 UTC 2020
On Tuesday, 7 April 2020 at 15:18:41 UTC, Gregor Mückl wrote:
> I've been playing around with synchronized class. My example is
> the following dummy class:
>
> synchronized class Shared {
> public:
> void increment(int value) {
> //(cast(Shared) this).x += value;
> x += value;
> }
>
> void decrement(int value) {
> //(cast(Shared) this).x -= value;
> x -= value;
> }
>
> shared int get() { return x; }
>
> private:
> int x;
> }
>
> Then I'm calling increment and decrement many times in parallel
> threads so that they *should* cancel out in the end and x
> should be back to 0 at the end. With the implicit
> synchronization using d monitors, this should work.
>
> Bug number 1: dmd doesn't translate this without casting away
> shared:
>
> sharedtest.d(14): Error: read-modify-write operations are not
> allowed for shared variables. Use
> core.atomic.atomicOp!"+="(this.x, value) instead.
>
> The += and -= operators are safe as they are inside locked
> monitors. The emitted code contains calls to d_montiorenter and
> d_monitorexit. The compiler should understand this.
>
> Bug number 2: even when casting away shared, the end result is
> wrong when using multiple threads. Thus, the monitor locking
> code in druntime cannot be correct. It does have an effect,
> though. Omitting synchronized on Shared results in values that
> are wide off the mark. Including it results in small
> differences. This suggests that a memory fence might be missing
> somewhere.
>
> The observed reality contradicts the documentation in many ways
> and is inconsistent with itself. What is going on here?
Correct me if I'm wrong, aren't all synchronized classes
protected with a mutex. In this case atomic operations are
pointless as all methods are protected by the mutex anyway.
More information about the Digitalmars-d
mailing list