(no title)
nebulous1 | 11 months ago
If I'm reading this correctly, they are recommending a lock in this situation. However, they are saying the implementations has two options, either raise an error reporting the race (if the implementation is told to do so), or, because the value being read is not larger than a machine word, reply to the read with a correct value from a previous write. If true then it cannot reply with corrupted data.
kiitos|11 months ago
The spec says
> A read r of a memory location x holding a value that is not larger than a machine word must observe some write w such that r does not happen before w and there is no write w' such that w happens before w' and w' happens before r. That is, each read must observe a value written by a preceding or concurrent write.
These rules apply only if the value isn't larger than a machine word. Otherwise,
> Reads of memory locations larger than a single machine word ... can lead to inconsistent values not corresponding to a single write.
The size of a machine word is different depending on how a program is compiled, so whether or not a value is larger than a machine word isn't know-able by the program itself.
And even if you can assert that your program will only be built where a machine word is always at least of size e.g. uint64, the spec only guarantees that unsynchronized reads of a uint64 will return some previous valid write, it doesn't guarantee anything about which value is returned. So `x=1; x=3; x=2;` concurrently with `print(x); print(x); print(x)` can print `1 1 1` or `3 3 3` or `2 1 1` or `3 2 1` and so on. It won't return a corrupted uint64, but it can return any prior uint64, which is still a data race, and almost certainly useless to the application.
nebulous1|11 months ago
> that unsynchronized reads of a uint64 will return some previous valid write, it doesn't guarantee anything about which value is returned
Your the second person saying this, so is my interpretation that this is dissallowed by the part that you quoted incorrect?
> must observe some write w such that r does not happen before w and there is no write w' such that w happens before w' and w' happens before r
edit: somebody is answering this below by the way
fashion-at-cost|11 months ago
Is that the kind of uncertainty you want in your production systems? Or is your only requirement that they don’t serve “corrupt” data?
Don’t be “clever”. Use locks.
nebulous1|11 months ago
> I understand the need for correct lock-free impls: Given OP's description, simply avoiding read mutexes can't be the way to go about it?
I did note that the documentation recommends a lock.
> read the first value ever set to the variable for the entire lifetime of the program
That is not my reading of the current memory model? It seems to specifically prohibit this behaviour in requirement 3:
> 2. w does not happen before any other write w' (to x) that happens before r.
kiitos|11 months ago