[PATCH 2/2] manual: Document __libc_single_threaded
Adhemerval Zanella
adhemerval.zanella@linaro.org
Thu May 21 14:32:02 GMT 2020
On 21/05/2020 10:14, Florian Weimer wrote:
> * Adhemerval Zanella via Libc-alpha:
>
>> On 20/05/2020 15:12, Florian Weimer via Libc-alpha wrote:
>>
>>> +@smallexample
>>> +if (__libc_single_threaded)
>>> + atomic_fetch_add (&reference_count, 1, memory_order_relaxed);
>>> +else
>>> + atomic_fetch_add (&reference_count, 1, memory_order_acq_rel);
>>> +@end smallexample
>>
>> Shouldn't the access to __libc_single_threaded be atomic itself
>> (at least with relaxed semantic)?
>
> Good question. In the current implementation, it is not needed because
> the variable is never written again once the process is multi-threaded.
>
> We must retain relaxed MO access as a valid use of this variable. A
> future implementation may set __libc_single_threaded to true after
> detecting that the process has become single-threaded again. But I
> think this requires that the last remaining thread synchronizes in some
> way with the exit of the other, second-to-last remaining thread. And
> that in turn means that no explicit MO is needed for the variable read.
>
> I'm going to add this to the manual as an implementation note, after the
> first example:
>
> @c Note: No memory order on __libc_single_threaded. The
> @c implementation must ensure that exit of the critical
> @c (second-to-last) thread happens-before setting
> @c __libc_single_threaded to true. Otherwise, acquire MO might be
> @c needed for reading the variable in some scenarios, and that would
> @c completely defeat its purpose.
The comments is sound, but I still think we should properly document
that this initial version does not attempt to update
__libc_single_threaded on pthread_join or detach exit and maybe also
the brief explanation you added on why this semantic was chose (to
avoid the requirement of more strict MO).
>
> For detached thread exits, this kind of synchronization may not be
> easily obtainable in all cases. I don't think we can do it on the
> on-thread exit path because the kernel will perform certain actions
> afterwards (like robust mutex updates), no matter how late we do it. I
> guess we could perhaps piggy-back on the stack reclamation mechanism.
It seems that robust mutexes updates are indeed a problem, but I am not
sure if CLONE_CHILD_CLEARTID clear helps here. It signals the thread
is done with the memory synchronization, but the stack cache is not
really updated. Maybe an extra clone3 flag ?
More information about the Libc-alpha
mailing list