比较'__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).