ARM Cortex M3:原子写入(ARM Cortex M3: Atomic Writes)

我正在ARM Cortex-M3架构(LPC1769)上开发一个共享数据库,我想知道我是否需要互斥锁或锁定写入。

是32位浮点读/写原子?

- 编辑 - 我为uint32_t和float的写函数添加了反汇编:

00000000 <setSharedDataUint>: 0: b480 push {r7} 2: b083 sub sp, #12 4: af00 add r7, sp, #0 6: 4603 mov r3, r0 8: 6039 str r1, [r7, #0] a: 71fb strb r3, [r7, #7] c: 79fb ldrb r3, [r7, #7] e: 4a05 ldr r2, [pc, #20] ; (24 <setSharedDataUint+0x24>) 10: 00db lsls r3, r3, #3 12: 4413 add r3, r2 14: 683a ldr r2, [r7, #0] 16: 605a str r2, [r3, #4] 18: 370c adds r7, #12 1a: 46bd mov sp, r7 1c: f85d 7b04 ldr.w r7, [sp], #4 20: 4770 bx lr 22: bf00 nop 24: 00000000 .word 0x00000000 24: R_ARM_ABS32 .bss.dataArray 00000000 <setSharedDataFloat>: 0: b480 push {r7} 2: b083 sub sp, #12 4: af00 add r7, sp, #0 6: 4603 mov r3, r0 8: 6039 str r1, [r7, #0] a: 71fb strb r3, [r7, #7] c: 79fb ldrb r3, [r7, #7] e: 4a05 ldr r2, [pc, #20] ; (24 <setSharedDataFloat+0x24>) 10: 00db lsls r3, r3, #3 12: 4413 add r3, r2 14: 683a ldr r2, [r7, #0] 16: 605a str r2, [r3, #4] 18: 370c adds r7, #12 1a: 46bd mov sp, r7 1c: f85d 7b04 ldr.w r7, [sp], #4 20: 4770 bx lr 22: bf00 nop 24: 00000000 .word 0x00000000 24: R_ARM_ABS32 .bss.dataArray

它们看起来相同,这使我假设32位浮点写也是原子的

I'm developing a shared data library on a ARM Cortex-M3 architecture (LPC1769) and I'm wondering if I need mutexes or locking around the writes.

Is a 32 bit float read/write atomic?

-- EDIT -- I added the disassembly for a write function for a uint32_t and a float:

00000000 <setSharedDataUint>: 0: b480 push {r7} 2: b083 sub sp, #12 4: af00 add r7, sp, #0 6: 4603 mov r3, r0 8: 6039 str r1, [r7, #0] a: 71fb strb r3, [r7, #7] c: 79fb ldrb r3, [r7, #7] e: 4a05 ldr r2, [pc, #20] ; (24 <setSharedDataUint+0x24>) 10: 00db lsls r3, r3, #3 12: 4413 add r3, r2 14: 683a ldr r2, [r7, #0] 16: 605a str r2, [r3, #4] 18: 370c adds r7, #12 1a: 46bd mov sp, r7 1c: f85d 7b04 ldr.w r7, [sp], #4 20: 4770 bx lr 22: bf00 nop 24: 00000000 .word 0x00000000 24: R_ARM_ABS32 .bss.dataArray 00000000 <setSharedDataFloat>: 0: b480 push {r7} 2: b083 sub sp, #12 4: af00 add r7, sp, #0 6: 4603 mov r3, r0 8: 6039 str r1, [r7, #0] a: 71fb strb r3, [r7, #7] c: 79fb ldrb r3, [r7, #7] e: 4a05 ldr r2, [pc, #20] ; (24 <setSharedDataFloat+0x24>) 10: 00db lsls r3, r3, #3 12: 4413 add r3, r2 14: 683a ldr r2, [r7, #0] 16: 605a str r2, [r3, #4] 18: 370c adds r7, #12 1a: 46bd mov sp, r7 1c: f85d 7b04 ldr.w r7, [sp], #4 20: 4770 bx lr 22: bf00 nop 24: 00000000 .word 0x00000000 24: R_ARM_ABS32 .bss.dataArray

They look identical which makes me assume that the 32-bit float write is also atomic

最满意答案

有关详细信息,请参阅“ 体系结构参考手册 ”:简而言之,任何对齐的 32位内存访问都是原子的,因为结果是旧值的全部4个字节,或新值的所有4个字节,并且从不混合两个。 未对齐的访问没有此保证。

这是纯粹的读取或写入 - 对于任何类型的读取 - 修改 - 写入序列,您需要一个加载/存储专用循环来使指令序列看起来是原子的。 类似地,如果共享数据指针在读取它之间以及读取/写入实际值到它指向的位置之间可能会发生变化,则需要将整个操作包装在一个独特的序列中以确保安全。

See the Architecture Reference Manual for the specifics: In short, any aligned 32-bit memory access is atomic in the sense that the result is either all 4 bytes of the old value, or all 4 bytes of the new value, and never some mix of the two. Unaligned accesses do not have this guarantee.

That's for pure reads or writes - for any kind of read-modify-write sequence, you need a load/store-exclusive loop to make the sequence of instructions appear atomic. Similarly if the shared data pointer is liable to change under your feet between reading it and reading/writing the actual value to the location it points at, you will need to wrap the whole operation in an exclusive sequence for safety.

更多推荐