【问题标题】:Are variables updated by signal handlers optimized out when using RTEMS semaphore synchronization?使用 RTEMS 信号量同步时,信号处理程序更新的变量是否已优化?
【发布时间】:2021-04-22 08:26:36
【问题描述】:

假设函数 isr_callback() 在硬件中断上被调用。如果 my_function() 设置变量 data 为 0,并等待 tx_complete_semaphore,那么当 tx_complete_semaphore 被 isr_callback() 释放时,变量 data 是否会在 my_function() 中更新为 1?或者变量数据是否必须被限定为 volatile 才能在 my_function() 中正确更新?

static int data;
static rtems_id tx_complete_semaphore;
void isr_callback(void)
{
  data = 1;
  /* interrupts as disabled here */
  rtems_semaphore_release(tx_complete_semaphore);
}
  
void my_function(void)
{
  data = 0;
  /* data will be 0 here */
  printf("data is %i", data)
  /* Interrupts are enabled here */
  rtems_semaphore_obtain(tx_complete_semaphore,
                         RTEMS_WAIT,
                         RTEMS_NO_TIMEOUT);
  /* what is the value of data here? */
  printf("data is %i", data);
}

【问题讨论】:

    标签: c synchronization semaphore volatile rtems


    【解决方案1】:

    您应该将data 限定为volatile,因为对于编译器而言,无法推断出在my_function 的过程中数据发生了变化。

    使用volatile,您可以确保编译器不依赖先前已知的值0,因为它可以在函数之外随时更改。

    【讨论】:

    • 其实,经过测试,这里似乎'volatile'可以省略,因为RTEMS信号量同步确保变量数据在my_function()中正确更新。
    • 但这并不意味着编译器在到达printf 行时就知道了。为了避免多余的负载,它可以优化它,认为变量在此期间没有改变。这就是使用volatile 的全部意义所在。告诉编译器某个值可以在它不知道的情况下随时更改,因此它不应该应用此类优化。
    • 据我们所知,data 可能已经被更改,即使是在第一行 printf 行,就在 data = 0 之后,因此关于数据为 0 的假设的注释可能是错误的在你分配之后。
    • 对不起,我应该在 my_function() 中将数据设置为 0 后添加中断启用的信息。
    • 是的,我意识到这一点,这就是我删除该评论的原因。 :) 我不知道data 的含义是什么,但是如果您不将其声明为易失性,您的第二个printf 可能会打印错误的值。您始终可以检查生成的 asm 源代码,以查看编译器是否会在优化处于活动状态时重新加载该值。
    【解决方案2】:

    不,这里不需要限定符“volatile”,因为 RTEMS 信号量同步确保变量数据在 my_function() 中正确更新。

    我检查了两种情况下生成的汇编器代码,一种是数据易失性,另一种是数据不是易失性。在这两种情况下,数据都是在获取信号量之后加载的,但只有在第一种情况下,数据是在获取信号量之前加载的。

    【讨论】:

      猜你喜欢
      • 2013-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2018-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多