I have a question about C/C++ atomic operation on ARM9 and ARM Cortex-M4. I am using ARMCC compiler with C / C++ languages. It interests me if it is possible that an interrupt will be handled in the middle of operations:
Does anything change if you access to these objects indirectly by pointer or reference?
Are there any other basic operations potentially unsafe in multi-thread application?
Thanks for answers.
Access of 64-bit data can be itnerrupted on Cortex-M3/M4:
For 8-bit/16-bit/32-bit data, provided that the memory instruction generated is a single LDR/STR instruction, interrupt cannot happen in between. The external memory controller might convert 16-bit / 32-bit access into multiple transfers on the memory bus, but the processor doesn't know this and will wait until the transfer is done before taking the interrupt.
One more thing to add: there is no 64-bit exclusive access instructions for Cortex-M4.
regards,
Joseph
Joseph Yiu wrote: If the 64-bit data is accessed using LDRD/STRD instructions, the instruction can get abandoned and restart after the ISR.
Joseph Yiu wrote:
Does that mean that the contents of two registers loaded using LDRD can be trusted to be "tied together" ?
Eg; it could actually be used for loading a complete 64-bit value pseudo-atomically ?
(I'm having double-linked lists in mind; preventing the possibility of an interrupt changing one of the pointers in between reads)
It's a little sad that STRD can't be used for this, though.
Since the LDR/LDRH/STR/STRH over boundaries cannot be interrupted, I believe LDR could be used to check two flags, which are 'tied' or set two flags that are "tied".
From the Cortex-M4 documentation: "the value of offset must be a multiple of four in the range 0-1020"
offset
-It does not say whether or not a LDREX / STREX (32-bit) is allowed to be misaligned.
If it's allowed to be misaligned, the same kind of (ab)use could be applied to LDREX/STREX, I believe ?
Hi Jens,
1) LDRD
No, you can end up read the first register, get interrupted, rerun LDRD and got the new version of both 1st and 2nd registers.
2) LDR for two 16-bit data or four 8
Yes, you can use a single LDR instruction to load multiple data in an atomic way.
3) exclusive accesses must be aligned. From memory a fault exception would be triggered otherwise.
Regards,
Sent from my iPad
1) LDRD No, you can end up read the first register, get interrupted, rerun LDRD and got the new version of both 1st and 2nd registers.
This was what I was hoping for.
-Because the final result will be two values that are read at the same time.
It would be OK (in my case) if the first read attempt was interrupted, because I would never see the resulting value of the first read attempt.
2) LDR for two 16-bit data or four 8 Yes, you can use a single LDR instruction to load multiple data in an atomic way.
This opens up a bunch of new valuable possibilities.
All this is really awesome information. Thank you so much for these gems!
Good night.
I'm coincidentally studying the behavior of instructions LDM / STM and its variations, but only for Cortex-M0 at the time, and ended up getting a little confused after reading the answers to this post. According to the text on page 136 of the book "The Definitive Guide to the ARM Cortex-M0 (2011)" on the subsection "Use of Multiple Load and Store Instructions", the instructions LDM / STR when interrupted by some ISR return to resume the process from the start, so if making the reading of a value from an address that represents a port FIFO device such values may be requested as a new reading will restarting the entire process.
Now in response to Joseph Yiu, and earlier by jensbauer as quoted below, instructions LDM / STM interrupted when returning execution where they were:
jyiu: If a 64-bit data is accessed using LDM/STM instructions, as Jens said, the instruction can get interrupted in the middle, the processor execute the ISR and then resume the LDM/STM from where it was interrupted. jensbauer: The LDM/STM instructions will be interrupted, and when the interrupt returns, the LDM or STM instruction will continue from where they left off.
jyiu: If a 64-bit data is accessed using LDM/STM instructions, as Jens said, the instruction can get interrupted in the middle, the processor execute the ISR and then resume the LDM/STM from where it was interrupted.
jensbauer: The LDM/STM instructions will be interrupted, and when the interrupt returns, the LDM or STM instruction will continue from where they left off.
And a line below Joseph Yiu says:
If the 64-bit data is accessed using LDRD/STRD instructions, the instruction can get abandoned and restart after the ISR.
This behavior is specific to the Cortex-M3 / 4 controllers? or just the instructions with modifiers "D" is that it has such a behavior?
Also tried to find more information on the book "ARM Assembly Language: Fundamentals and Techniques", especially in chapter 10, in the subtitle: "10.2.1 - LDM / STM Instructions" but have not found anything concrete, which eliminates my doubt.
Who is right? current information? or contained in the book?
Thanks.
Hi Carlos,
Sorry that I forgot to specify that the LDM/STM resume behavior is for ARMV7-M, where ICI/IT bits present in xPSR. (ie Cortex-M3/M4/M7). For ARMv6-M (Cortex-M0/M0+), the LDM/STM are abandoned and restarted after interrupt service.
There are no LDRD/STRD instructions in ARMv6-M.
Sent from Samsung Mobile