比较'__libc_multiple_threads'的逻辑在哪里?
Where is the logic of comparing '__libc_multiple_threads'?
在分析iofclose.c文件时,我发现了一些奇怪的部分。
// glibc-2.23.90/libio/iofclose.c:53
if (fp->_IO_file_flags & _IO_IS_FILEBUF)
_IO_un_link ((struct _IO_FILE_plus *) fp);
_IO_acquire_lock (fp); // !!!!! This part !!!!!
...
如您所见,fclose() 在内部调用 _IO_acquire_lock
。
并且_IO_acquire_lock
在此下方调用_IO_lock_lock
。
//glibc-2.23.90/sysdeps/nptl/stdio-lock.h:39
#define _IO_lock_lock(_name) \
do { \
void *__self = THREAD_SELF; \
if ((_name).owner != __self) \
{ \
lll_lock ((_name).lock, LLL_PRIVATE); \
...
在_IO_lock_lock
中,void *__self = THREAD_SELF;
和if ((_name).owner != __self)
的逻辑是这样的。
0x7f9a21eca393 <_IO_new_fclose+291>: mov r8,QWORD PTR fs:0x10
0x7f9a21eca39c <_IO_new_fclose+300>: cmp r8,QWORD PTR [rdx+0x8]
0x7f9a21eca3a0 <_IO_new_fclose+304>: je 0x7f9a21eca3e2 <_IO_new_fclose+370>
0x7f9a21eca3a2 <_IO_new_fclose+306>: mov esi,0x1
...
那么,如果lll_lock((_name).lock, LLL_PRIVATE);
在分支命令之后调用,lll_lock()
就这样进行。
0x7f9a21eca3a2 <_IO_new_fclose+306>: mov esi,0x1
0x7f9a21eca3a7 <_IO_new_fclose+311>: xor eax,eax
0x7f9a21eca3a9 <_IO_new_fclose+313>:
cmp DWORD PTR [rip+0x35c390],0x0 # 0x7f9a22226740 <__libc_multiple_threads>
0x7f9a21eca3b0 <_IO_new_fclose+320>: je 0x7f9a21eca3ba <_IO_new_fclose+330>
...
在这个程序集中,正在比较__libc_multiple_threads
的逻辑。
但是,当我看到 lll_lock()
代码时,我找不到那个逻辑...
//glibc-2.23.90/sysdeps/unix/sysv/linux/sparc/lowlevellock.h:51
static inline void
__attribute__ ((always_inline))
__lll_lock (int *futex, int private)
{
int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
if (__glibc_unlikely (val != 0))
{
if (__builtin_constant_p (private) && private == LLL_PRIVATE)
__lll_lock_wait_private (futex);
else
__lll_lock_wait (futex, private);
}
}
#define lll_lock(futex, private) __lll_lock (&(futex), private)
怎么会出现这种情况?
我在哪里可以找到这个 C 源代码中的这些汇编逻辑?
您正在阅读 SPARC 锁定实现的源代码,但您显示的程序集是 x86。我想你想要的代码是在 sysdeps/unix/sysv/linux/x86/lowlevellock.h. There you'll see it tests if (is_single_thread)
. This expands to SINGLE_THREAD_P
, which is defined in sysdeps/unix/sysv/linux/single-thread.h 扩展到 __glibc_likely (__libc_multiple_threads == 0)
.
在分析iofclose.c文件时,我发现了一些奇怪的部分。
// glibc-2.23.90/libio/iofclose.c:53
if (fp->_IO_file_flags & _IO_IS_FILEBUF)
_IO_un_link ((struct _IO_FILE_plus *) fp);
_IO_acquire_lock (fp); // !!!!! This part !!!!!
...
如您所见,fclose() 在内部调用 _IO_acquire_lock
。
并且_IO_acquire_lock
在此下方调用_IO_lock_lock
。
//glibc-2.23.90/sysdeps/nptl/stdio-lock.h:39
#define _IO_lock_lock(_name) \
do { \
void *__self = THREAD_SELF; \
if ((_name).owner != __self) \
{ \
lll_lock ((_name).lock, LLL_PRIVATE); \
...
在_IO_lock_lock
中,void *__self = THREAD_SELF;
和if ((_name).owner != __self)
的逻辑是这样的。
0x7f9a21eca393 <_IO_new_fclose+291>: mov r8,QWORD PTR fs:0x10
0x7f9a21eca39c <_IO_new_fclose+300>: cmp r8,QWORD PTR [rdx+0x8]
0x7f9a21eca3a0 <_IO_new_fclose+304>: je 0x7f9a21eca3e2 <_IO_new_fclose+370>
0x7f9a21eca3a2 <_IO_new_fclose+306>: mov esi,0x1
...
那么,如果lll_lock((_name).lock, LLL_PRIVATE);
在分支命令之后调用,lll_lock()
就这样进行。
0x7f9a21eca3a2 <_IO_new_fclose+306>: mov esi,0x1
0x7f9a21eca3a7 <_IO_new_fclose+311>: xor eax,eax
0x7f9a21eca3a9 <_IO_new_fclose+313>:
cmp DWORD PTR [rip+0x35c390],0x0 # 0x7f9a22226740 <__libc_multiple_threads>
0x7f9a21eca3b0 <_IO_new_fclose+320>: je 0x7f9a21eca3ba <_IO_new_fclose+330>
...
在这个程序集中,正在比较__libc_multiple_threads
的逻辑。
但是,当我看到 lll_lock()
代码时,我找不到那个逻辑...
//glibc-2.23.90/sysdeps/unix/sysv/linux/sparc/lowlevellock.h:51
static inline void
__attribute__ ((always_inline))
__lll_lock (int *futex, int private)
{
int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
if (__glibc_unlikely (val != 0))
{
if (__builtin_constant_p (private) && private == LLL_PRIVATE)
__lll_lock_wait_private (futex);
else
__lll_lock_wait (futex, private);
}
}
#define lll_lock(futex, private) __lll_lock (&(futex), private)
怎么会出现这种情况?
我在哪里可以找到这个 C 源代码中的这些汇编逻辑?
您正在阅读 SPARC 锁定实现的源代码,但您显示的程序集是 x86。我想你想要的代码是在 sysdeps/unix/sysv/linux/x86/lowlevellock.h. There you'll see it tests if (is_single_thread)
. This expands to SINGLE_THREAD_P
, which is defined in sysdeps/unix/sysv/linux/single-thread.h 扩展到 __glibc_likely (__libc_multiple_threads == 0)
.