From: Sergey Matveev
Date: 2023-08-28 08:10:07Z
*** kmeaw [2023-08-27 11:37]:
>А как libc у FreeBSD решает эту проблему?
Для pthread-ов используется libthr реализация. В man-говорится:
INTERACTION WITH RUN-TIME LINKER
On load, libthr installs interposing handlers into the hooks exported by
libc. The interposers provide real locking implementation instead of the
stubs for single-threaded processes in libc, cancellation support and
some modifications to the signal operations.
Судя по коду libthr, в __thr_interpose_libc он вызывает
__libc_interposing_slot для переопределения всяких syscall-ов в libc
(accept, ..., pdfork) на свои __thr_* реализации. __thr_interpose_libc
вызывается в _libpthread_init, который:
/*
* Threaded process initialization.
*
* This is only called under two conditions:
*
* 1) Some thread routines have detected that the library hasn't yet
* been initialized (_thr_initial == NULL && curthread == NULL), or
*
* 2) An explicit call to reinitialize after a fork (indicated
* by curthread != NULL)
*/
void
_libpthread_init(struct pthread *curthread)
Кто вызывает всю эту инициализацию с самого начала: с ходу не нашёл в
коде. Но вижу что в (Free)BSD libc много где используется "extern int
__isthreaded", прямо в stdio.h например для использования или threaded
или не-threaded версии функций. Внутри Си-шных функций аналогично
проверкиа на "if (__isthreaded)" есть. А также libc явно знает про
libthr существование. То бишь, судя по всему, функции просто понимаю и
знают в threaded режиме ли они или нет, и если да, то инициализируется
явно libthr, устанавливающий hook-и на функции связанные с pthread. nm
показывает что weak символов нет (только пара отладочных) в libpthread.a.
Насколько понимаю, всё в run-time, а не во время линковки заменяется с
stub reentrant-related вещей на настоящие libthr-овые.