Linux 如何实施 'queue spin lock'?
How Linux implement the 'queue spin lock'?
根据文章 http://www.phoronix.com/scan.php?page=news_item&px=queue-spinlocks-linux-4.2,自版本 4.2 起,Linux 内核将具有队列自旋锁。但是在 4.4 版本中,我查看了 spin_lock
的实现,发现他们在 kernel/locking/spinlock.c
:
中实现了这样的自旋锁
void __lockfunc __raw_##op##_lock(locktype##_t *lock) \
{ \
for (;;) { \
preempt_disable(); \
if (likely(do_raw_##op##_trylock(lock))) \
break; \
preempt_enable(); \
\
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
arch_##op##_relax(&lock->raw_lock); \
} \
(lock)->break_lock = 0; \
} \
并且do_raw_spin_trylock
中有一个cmpxchg
,所以基本上它只是一个TATAS自旋锁。
然而,当我深入挖掘时,我发现 do_raw_spin_lock
将进入函数 queued_spin_trylock
并且 lock
变量的类型变为 qspinlock
。那么队列自旋在哪里?它是隐藏在某个地方还是只是等待未来的实施?
在源代码中搜索标识符,这里是工具:http://lxr.free-electrons.com/
您正在查看的代码在#else 情况下:
#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
/*
* The __lock_function inlines are taken from
* include/linux/spinlock_api_smp.h
*/
#else
...
默认情况下,在 x86 上,CONFIG_GENERIC_LOCKBREAK 未定义,因此编译器不会编译该代码(即在 #else
子句中)。在锁定 ifdef
的迷宫中有很多潜在的路径。所采用的确切路径将取决于您的体系结构以及您在 .config
.
中所做的任何自定义选择
根据文章 http://www.phoronix.com/scan.php?page=news_item&px=queue-spinlocks-linux-4.2,自版本 4.2 起,Linux 内核将具有队列自旋锁。但是在 4.4 版本中,我查看了 spin_lock
的实现,发现他们在 kernel/locking/spinlock.c
:
void __lockfunc __raw_##op##_lock(locktype##_t *lock) \
{ \
for (;;) { \
preempt_disable(); \
if (likely(do_raw_##op##_trylock(lock))) \
break; \
preempt_enable(); \
\
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
arch_##op##_relax(&lock->raw_lock); \
} \
(lock)->break_lock = 0; \
} \
并且do_raw_spin_trylock
中有一个cmpxchg
,所以基本上它只是一个TATAS自旋锁。
然而,当我深入挖掘时,我发现 do_raw_spin_lock
将进入函数 queued_spin_trylock
并且 lock
变量的类型变为 qspinlock
。那么队列自旋在哪里?它是隐藏在某个地方还是只是等待未来的实施?
在源代码中搜索标识符,这里是工具:http://lxr.free-electrons.com/
您正在查看的代码在#else 情况下:
#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
/*
* The __lock_function inlines are taken from
* include/linux/spinlock_api_smp.h
*/
#else
...
默认情况下,在 x86 上,CONFIG_GENERIC_LOCKBREAK 未定义,因此编译器不会编译该代码(即在 #else
子句中)。在锁定 ifdef
的迷宫中有很多潜在的路径。所采用的确切路径将取决于您的体系结构以及您在 .config
.