glibc 的 atomic_forced_read 函数的目的是什么?

What is the purpose of glibc's atomic_forced_read function?

我试图理解 atomic_forced_read 定义的目的,它经常出现在 malloc.c 的 GNU libc 实现中。

我不太擅长内联汇编,但看起来 returns 与输入值完全相同的值,具有相同的类型。我在这里错过了什么?

atomic.h

中的原子强制读取定义
523 #ifndef atomic_forced_read
524 # define atomic_forced_read(x) \
525   ({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; })
526 #endif

Link 到 atomic.h

https://code.woboq.org/userspace/glibc/include/atomic.h.html

一种用法是 atomic_forced_read:

#if HAVE_MALLOC_INIT_HOOK
  void (*hook) (void) = atomic_forced_read(__malloc_initialize_hook);
  if (hook != NULL)
    (*hook)();
#endif

看来 __malloc_initialize_hook 可以从另一个线程更改,因此如果 __malloc_initialize_hookNULL 检查后再次从内存中加载,其值可能已更改回 NULL.

atomic_forced_read 确保 __malloc_initialize_hook 由于 =r 输出约束而被加载到寄存器中,因此 __malloc_initialize_hook 不会在 [=] 之后从内存中重新加载14=] 检查。空 asm 打破了 hook__malloc_initialize_hook 的编译器依赖性,因为 hook 现在使用存储在寄存器中的 __x 而不是 __malloc_initialize_hook 进行了初始化。在 hook__x 初始化后,后者就消失了,不可能重新加载。


在 C11 模式下 __malloc_initialize_hook 可以是 atomic_uintptr_t 并且 atomic_load_explicit(&__malloc_initialize_hook, memory_order_relaxed) 可以用来代替 atomic_forced_read 从内存中加载 __malloc_initialize_hook 恰好一次。