Am Freitag, dem 28.07.2023 um 16:26 +0200 schrieb Jakub Jelinek:
> On Fri, Jul 28, 2023 at 04:03:39PM +0200, Martin Uecker wrote:
> > > On Thu, Jul 27, 2023 at 07:06:03PM +0000, Joseph Myers wrote:
> > > > I think there should be tests for _Atomic _BitInt types.  Hopefully 
> > > > atomic 
> > > > compound assignment just works via the logic for compare-and-exchange 
> > > > loops, but does e.g. atomic_fetch_add work with _Atomic _BitInt types?
> > > 
> > > So, there are 2 issues.
> > > 
> > > One is something I haven't seen being handled for C at all so far, but
> > > handled for C++ - padding bits.
> > > 
> > > Already e.g. x86 long double has some padding bits - 16 bits on ia32,
> > > 48 bits on x86_64, when one does
> > >   _Atomic long double l;
> > > ...
> > >   l += 2.0;
> > > it will sometimes work and sometimes hang forever.
> > > Similarly atomic_compare_exchange with structs which contain padding
> > > (unions with padding bits are lost case, there is nothing that can be
> > > reliably done for that, because we don't know at runtime what is the 
> > > active
> > > union member if any).  And _BitInt if it doesn't use all bits in
> > > all containing limbs has padding as well (and psABI doesn't say it is sign
> > > or zero extended).
> > 
> > What is the problem here?  In C, atomic_compare_exchange is defined in terms
> > of the memory content which includes padding.  So it may fail spuriously
> > due to padding differences (but it may fail anyway for arbitrary reasons
> > even without padding differences), but then should work in the second 
> > iterations.
> 
> See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0528r3.html
> for background.  

Thanks. I have seen this at that time, but it seems to refer to 
C++ specific problems. At least at that time, I concluded (maybe
incorrectly) that this is not a serious problem for how things 
work in C.


> 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.


Martin




Reply via email to