This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 1/2] Optimize generic spinlock code and use C11 like atomic macros.


On 26/02/17 20:35, Torvald Riegel wrote:
> On Sun, 2017-02-26 at 21:29 +0100, Florian Weimer wrote:
>> * Torvald Riegel:
>>
>>>> … like this, it would change the C++ name mangling of anything related
>>>> to pthread_spinlock_t.  It is defined as a typedef, so the mangling
>>>> uses the definition to refer to the type, not the name, according to
>>>> the language rules, where typedef does not create a new type, and
>>>> typedefs with the same definition can be used interchangeably.
>>>
>>> I'm not saying that we should change the definition to a union.  What
>>> 2.14.2 in the document cited above states is that the pointers to the
>>> union and the individual parts are interchangeable.  So we can use a
>>> pointer to a part (ie, non-volatile) interchangeably with the pointer to
>>> the union that we use internally.
>>
>> The relevant quote from that document (C memory object and value
>> semantics: the space of de facto and ISO standards) is:
>>
>> | The standard says: 6.7.2.1p16 “The size of a union is
>> | sufficient to contain the largest of its members. The value of
>> | at most one of the members can be stored in a union object
>> | at any time. *A pointer to a union object, suitably converted,*
>> | *points to each of its members (or if a member is a bit-field,*
>> | *then to the unit in which it resides), and vice versa.*” (bold
>> | emphasis added).
>>
>> So I think this is only valid if you actually start with a union
>> object.  A plain top-level definition of a volatile int is not a union
>> member, so this rule does not apply (in the “vice versa” part).
> 
> Then we'll have to agree to disagree.  What do others think about this
> question?

i think the standard says that

volatile int x;
*(int*)&x;

is undefined and i think

int r = *p;

can be transformed by the compiler to

int r = *p;
*p = r;

if p has type int* (with a conflicting write the
original code would be undefined, without a
conflicting write the transformed code behaves
the same way on targets where the write is atomic),
but this is not valid if p is volatile int*.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]