小编And*_*oie的帖子

有没有办法告诉GCC不要重新排序任何指令,而不仅仅是加载/存储?

我正在研究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)

c interrupt

11
推荐指数
1
解决办法
316
查看次数

标签 统计

c ×1

interrupt ×1