jonas at freepascal.org
Mon Aug 24 19:20:37 CEST 2020
On 24/08/2020 02:11, Martin via fpc-devel wrote:
> Assuming the following
> (and not counting on Interlocked... doing any Barriers itself)
> Thread 1
> Foo := val; // normal assign
> WriteBarrier; // make sure above write to Foo is executed, before the
> next write to flag
> InterLockedIncrement(Flag); // needed for the lock, if others do
> write access too.
> Thread 2
> If InterLockedExchangeAdd(Flag, 0) > 0 then begin
> ReadBarrier; // make sure below read is executed only after the
> read of the flag
> myval := Foo;
> That should get the correct value of Foo.
> Even if run a million times, and in all of this the read of Flag
> eventually happens exactly one cpu cycle after it was set.
> Now the Examples I've seen all are showing cases where the re-orderable
> assignment are in close proximity to each other.
> On the other hand compiler and CPU are getting better and better. So
> there is nothing that would in theory stop them to swap read/write order
> over any amount of statements....
Correct. In particular on multi-socket systems, or e.g. Ryzen processors
with multiple core/CPU complexes, this is quite possible.
> So even if (in Thread 1) I returned from a subroutine (which could be
> inlined for all I (don't) know), done some other work, and only then set
> the flag.
> If I want to be sure, any value that was written in the subroutine is
> written before the flag gets set, then I should do a WriteBarrier?
> Or is that paranoid?
It's not paranoid, it is the only correct way to write the code.
More information about the fpc-devel