On 28/06/17 17:11, Andrew Haley wrote: > On 28/06/17 15:55, Richard Earnshaw wrote: >> It's a consequence of 'const' on pointers (and references) in C and C++ >> meaning "cannot be modified in this context" but not precluding being >> modifiable in another context. I can have const and non-const pointers >> to the same object in different threads. >> >> If something is marked const I have no idea in general whether the >> program will cause a fault if the object is written to, or if the write >> will succeed anyway (it might be in a page marked as write-disabled, for >> example in the program text). >> >> So pointers to const atomic objects cannot use an LDXP/STXP loop because >> that might cause a fatal memory error but must also deal with the >> underlying object not being really constant and thus might be partially >> modified when accessed. > > I agree, they can't. They can't use compare-and-swap at all, because > CAS writes to the object, and you can't do that with a pointer to const. > >> The only solution to that is to have a secondary lock on the object. >> And, of course, this becomes ABI; so once you start doing it, it's >> pretty much impossible to change it later since that would require a >> complete rebuild of the world. > > I think I get that, but I still don't see how the fact that you can't > atomically read a double-word affects whether double-word CAS should be > supported on its own. Double-word CAS is very useful, regardless of > the other operations. > Because you can't *know* that there isn't another reader that has to use locks to access the same variable. Consider atomic128t a; const atomic128t b; thread 1: void f(const atomic128t *p); // Must use locks to dereference p. while (something) { ... if (some_condition) f(&a); else f(&b); ... } thread 2: while (somethingelse) { ... CAS (a, ....); } thread2 is blissfully unaware of the fact that by using CAS directly on 'a' it has broken the requirement in f() that an object must be locked before it can be dereferenced. R.