On Fri, Jul 28, 2023 at 04:53:30PM +0200, Martin Uecker wrote: > > The thing is that user doesn't have much control over those > > padding bits, so whether _Atomic operations on long double (when it is 80 > > bit and stores from hw actually store 10 bytes rather than 12 or 16), or > > _BitInt(37) or _BitInt(195) or struct S { char a; int b; }; then depend > > purely on luck. If the expected value is based on atomic_load on the > > atomic_compare_exchange location or whatever atomic_compare_exchange gave > > back, if in the loop one e.g. adds something to it, then again it might get > > different padding bits from what is originally in memory, so it isn't true > > that it will always succeed at least in the second loop iteration. > > Sorry, somehow I must be missing something here. > > If you add something you would create a new value and this may (in > an object) have random new padding. But the "expected" value should > be updated by a failed atomic_compare_exchange cycle and then have > same padding as the value stored in the atomic. So the next cycle > should succeed. The user would not change the representation of > the "expected" value but create a new value for another object > by adding something.
You're right that it would pass the expected value not something after an operation on it usually. But still, expected type will be something like _BitInt(37) or _BitInt(195) and so neither the atomic_load nor what atomic_compare_exchange copies back on failure is guaranteed to have the padding bits preserved. It is true that if it is larger than 16 bytes the libatomic atomic_compare_exchange will memcpy the value back which copies the padding bits, but is there a guarantee that the user code doesn't actually copy that value further into some other variable? Anyway, for smaller or equal to 16 (or 8) bytes if atomic_compare_exchange is emitted inline I don't see what would preserve the bits. Jakub