确保一个cpu在另一个cpu读取“double”之前写了一个“double”?

时间:2013-05-23 07:36:22

标签: c linux assembly arm cpu

我将在双核ARM Cortex-A9 CPU上运行一个操作系统(一个核心运行Linux,另一个核心没有操作系统)。

在无操作系统方面,我们向DDR内存写入64位double,然后Linux端读取它。

由于CPU具有到DDR的32位总线,因此该值在两个总线周期内传输,这意味着如果写入和读取在总线上混合,则该值可能会被破坏。

我能做些什么才能让它以安全的方式运作?

2 个答案:

答案 0 :(得分:5)

您没有准确说明您的订购要求是什么或者您打算如何发出变更信号 - 所以我只是按照说明回答问题:

如果在64位对齐位置执行LDREXD / STREXD指令,则保证它们是单拷贝原子(如果位置不是,则它们会中止)。如果你正在做一些无锁的事情,这可能对你有益。如果没有,只需使用互斥锁实现它。

当然,只要满足以下任一条件,LDREXD / STREXD才能正常工作:

  • Linux和您的其他软件都启用了缓存,两个cpus都设置了“SMP”位,并且都将共享区域映射为可写回写的。

  • Linux和您的其他软件都将共享区域视为未缓存,并且您的SoC为内存设备实现全局监视器

答案 1 :(得分:2)

你的问题不够明确,但让我们试一试。

如果对于您来说非常重要的是,无任何部分在读取数据时始终会看到一致的值,您只需要执行原子操作。如果你正在使用gcc或类似的,那么有内置函数(例如__sync_val_compare_and_swap)来实现这种操作。如果没有,这可以用几行汇编程序来实现,你很容易找到它的参考。 (但要注意这个特定的处理器,这不仅仅是一条指令。)

如果你想要某种信号表明Linux方已经编写了这个值,那么最简单的方法就是实现你自己的锁结构。由于您没有一侧的操作系统,因此您必须实施繁忙的等待。这可以通过原子操作再次完成,gcc builtin __sync_lock_test_and_set将是学习如何实现这一目标的良好起点。