我正在研究RTOS的irq_lock()/ irq_unlock()实现,并发现了一个问题.我们希望绝对最小化CPU在中断锁定时花费的时间.现在,我们用于x86的irq_lock()内联函数使用"memory"clobber:
static ALWAYS_INLINE unsigned int _do_irq_lock(void)
{
unsigned int key;
__asm__ volatile (
"pushfl;\n\t"
"cli;\n\t"
"popl %0;\n\t"
: "=g" (key)
:
: "memory"
);
return key;
}
Run Code Online (Sandbox Code Playgroud)
问题是,如果编译器只触及寄存器而不是内存,它仍然会将可能昂贵的操作重新排序到关键部分.我们内核的sleep函数中有一个具体的例子:
void k_sleep(int32_t duration)
{
__ASSERT(!_is_in_isr(), "");
__ASSERT(duration != K_FOREVER, "");
K_DEBUG("thread %p for %d ns\n", _current, duration);
/* wait of 0 ns is treated as a 'yield' */
if (duration == 0) {
k_yield();
return;
}
int32_t ticks = _TICK_ALIGN + _ms_to_ticks(duration);
int key = irq_lock();
_remove_thread_from_ready_q(_current);
_add_thread_timeout(_current, NULL, ticks);
_Swap(key); …Run Code Online (Sandbox Code Playgroud)