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

Reply via email to