Am Freitag, dem 28.07.2023 um 17:10 +0200 schrieb Jakub Jelinek: > 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.
For atomic_load in C a value is returned. A value does not care about padding and when stored into a new object can produce new and different padding. But for atomic_compare_exchange the memory content is copied into an object passed by pointer, so here the C standard requires to that the padding is preserved. It explicitely states that the effect is like: if (memcmp(object, expected, sizeof(*object)) == 0) memcpy(object, &desired, sizeof(*object)); else memcpy(expected, object, sizeof(*object)); > 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? I do not think it would be surprising for C user when the next atomic_compare_exchange fails in this case. > 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. This then seems to be incorrect for C. Martin