Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
确保一个cpu已写入一个;“双”字;在另一个cpu读到“之前”;“双”字;?_C_Linux_Assembly_Arm_Cpu - Fatal编程技术网

确保一个cpu已写入一个;“双”字;在另一个cpu读到“之前”;“双”字;?

确保一个cpu已写入一个;“双”字;在另一个cpu读到“之前”;“双”字;?,c,linux,assembly,arm,cpu,C,Linux,Assembly,Arm,Cpu,我将在双核ARM Cortex-A9 CPU上运行一个操作系统(一个内核运行Linux,另一个没有操作系统) 在无操作系统端,我们向DDR内存写入一个64位double,然后Linux端读取它 由于CPU与DDR之间有一条32位总线,因此该值在两个总线周期内传输,这意味着如果写入和读取在总线上混合,则该值可能会损坏 我能做些什么使它以安全的方式工作?您的问题不够清楚,但让我们试一试 如果无操作系统部分在读取数据时总是看到一致的值这一点对您很重要,那么您只需要执行原子操作。如果您要使用gcc或类似

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

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

由于CPU与DDR之间有一条32位总线,因此该值在两个总线周期内传输,这意味着如果写入和读取在总线上混合,则该值可能会损坏


我能做些什么使它以安全的方式工作?

您的问题不够清楚,但让我们试一试

如果无操作系统部分在读取数据时总是看到一致的值这一点对您很重要,那么您只需要执行原子操作。如果您要使用gcc或类似工具,则有内置函数(例如
\uuu sync\u val\u compare\u和\u swap
)可实现此类操作。如果没有,这可以通过几行汇编程序来实现,您可以很容易地找到相关的参考资料。(但在这个特定处理器上要小心,这不仅仅是一条指令。)


如果您希望得到某种信号,表明Linux端已经编写了值,最简单的方法是实现自己的锁结构。由于一侧没有操作系统,因此必须实现繁忙等待。这同样可以通过原子操作来实现,gcc内置的
\uu sync\u lock\u test\u和\u set
将是学习如何实现这一点的一个很好的起点。

您没有明确说明您的订购要求是什么,或者您打算如何发出更改信号-因此我将简单地回答如下问题:

如果在64位对齐的位置上执行,则LDREXD/STREXD指令保证为单拷贝原子指令(如果该位置未对齐,则它们将中止)。如果你在做一些没有锁的事情,那可能对你有好处。如果没有,就用互斥锁实现它

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

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

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


“一个是Linux,另一个没有操作系统”-那么“两个不同的操作系统”在哪里?@H2CO3我的错误,编辑您必须实现一个跨核心互斥。您可能可以查看Linux互斥锁的实现并复制它。@Mats Peterson是的,Linux可以使用自旋锁,但另一个内核没有它无法感知自旋锁的操作系统。这就是ldrex/strex对的用途,它们不用于锁定资源(在单个内核内,因为它们在Linux和其他地方被错误地使用)但为了保护多核处理器内核之间的内存。