-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrency / Atomic access section contains factual errors #338
Comments
This was #273, but it's not wrong as such: thumbv6 does guarantee that all aligned byte/halfword/word memory accesses will be atomic, and therefore Rust is able to provide On many platforms, certain memory operations are guaranteed to be atomic, which means the entire operation takes place as though at a single moment in time: a partial or intermediate result is never observable. An operation might be a simple write or a more complicated read, modify, write sequence. For example, it is common on 32-bit platforms for an aligned 32-bit write (that is, a write of 4 bytes to an address that's a multiple of 4) to be atomic, so that you can never observe "half" the write - anything reading the address being written either reads the complete old value, or the complete new value. This is referred to as atomic load and store, and on the Arm These However, some platforms - such as |
This is getting lost in the weeds. I think you'd be hard pressed to find a thirty-two bit machine where its possible to observe half of an aligned write. If that's the criteria for an 'Atomic' write then the term has little meaning and begs the question of how an AtomicU32 is different from a U32. The use of the term 'CAS' to refer to V6M/V7M machines is an unfortunate choice, as the SWP instruction is specific to V7A and older devices and was replaced by LDREX/STREX on V7M. if the docs are going to refer to Cortex-M, its preferable to refer to the relevant machine instructions. I think the core problem here is the term 'Instruction'. The v6m devices have atomic behavior with regard to aligned reads and writes, but they do not have atomic load/store 'instructions'. Likewise the V7M architectures offer CAS functionality via LDREX/STREX, but there is no CAS or SWP instruction. I'm deeply familiar with the CPU behavior here, but not so much with Rust's semantics and precisely how that maps onto the underlying CPU. Thanks for the detailed response. |
Ideally we'd avoid being too focussed on a particular hardware platform for this part of the book, so I wanted to introduce the concept fairly generally. There are plenty of 8 and 16 bit platforms that run Rust, where a U32 usually wouldn't be atomic, and U64 is widely used and obviously isn't atomic on 32-bit Cortex-M either, so the We could refer to the machine instructions but I don't think it's really worthwhile here - the point is just that some hardware platforms only provide enough capability for Atomic* to have load/store, while others provide enough capability that Atomic* provide the full complement of methods. Usually the latter is called "CAS" even if it's not fully accurate. How it's implemented (ldrex/strex on thumbv7, other instructions on eg riscv with the atomic extension) seems too much detail for this section. My proposed text above doesn't use the term "instruction" at all for that reason, so I'm not sure what you're suggesting should change in it. Do you think it needs to be more explicit about hardware details or even less? |
This is way too far into philosophy. If you're not going to go into platform - specific detail, than I suggest you boil it down to something concise that doesn't invite technical debate and risk misleading the reader. You've already written it:
The platform-specific details of which methods are supported on which platforms is important and worthy of documentation. Perhaps an appendix would be more appropriate for that. |
I see what you're saying @rbsexton, maybe something like: - Specifically for Cortex-M: thumbv6 (Cortex-M0, Cortex-M0+) only
- provide atomic load and store instructions, while thumbv7
- (Cortex-M3 and above) provide full Compare and Swap
- (CAS) instructions
+ Specifically for Cortex-M: thumbv6 (Cortex-M0, Cortex-M0+)
+ are only capable of atomically loading and storing 8-32 bit
+ integers, while thumbv7 (Cortex-M3 and above) provide full
+ Compare and Swap (CAS) capability, via the `LDREX` and
+ `STREX` atomic instructions for 8-32 bit integers. I agree we don't want to get too into the weeds with theory, but also not be incorrect. We do sort of want to introduce the "CAS" term, as it is used consistently in Rust's core/std documentation, so folks are likely to see it again. |
Actually, I found the elaborate explanation in #338 (comment) instructive, providing that kind of background and overview perspective that is so often not provided and everyone has to recreate on their mind. |
The section on atomic access gets some important things wrong about Cortex-M. Here's the language:
Atomic Access
On some platforms, special atomic instructions are available, which provide
guarantees about read-modify-write operations. Specifically for Cortex-M:
thumbv6
(Cortex-M0, Cortex-M0+) only provide atomic load and store instructions,
while
thumbv7
(Cortex-M3 and above) provide full Compare and Swap (CAS)instructions. These CAS instructions give an alternative to the heavy-handed
disabling of all interrupts: we can attempt the increment, it will succeed most
of the time, but if it was interrupted it will automatically retry the entire
increment operation. These atomic operations are safe even across multiple
cores.
LDREX\STREX
instructions.Proposed language
Some platforms include special atomic instructions to guarantee read-modify-write operations. Within the Cortex-M family,
thumbv6
(Cortex-M0, Cortex-M0+) must make use of critical sections.thumbv7
(Cortex-M3 and above) include atomic load and store (LDREX/STREX) instructions. These instructions are an alternative to the heavy-handed disabling of all interrupts: we can attempt the increment, it will succeed most of the time, but if it was interrupted the firmware can automatically retry the entire increment operation. These atomic may be supported across multiple cores. Check your device reference manual for more details.The text was updated successfully, but these errors were encountered: