Question

On ARM architecture, unfortunately I don't know exactly what chip it is, is a 32 bit int read/write atomic?

Is there any sort of guarantees about reads/writes to basic types?

Was it helpful?

Solution

It should be atomic, EXCEPT if that int is stored on a non-aligned address.

OTHER TIPS

This is documented either in the TRM for the core or in the AMBA/AXI spec. You need to look up the core being used from there if you can figure it out what flavor of AMBA/AXI bus and in that spec it spells out the atomic/non-atomic nature of each of the transaction types.

For example the swp and ldrex/strex are atomic. An strd and stm should also be atomic. But on the ARM11 Mpcore that I am most familiar it breaks the writes into single 64 bit bus cycles, do an stm with 8 registers I think it becomes 4 separate length of 1 bus cycles, where an ldm of 8 registers I think is a single transaction with a length of four.

This is a good time to note that ldrex and strex are often not used properly by programmers. Linux has it wrong for example. They are for locking when using a multicore processor on a shared memory system, NOT for locking software threads on a single processor. Use SWP for that. You get lucky if you have the L1 cache on as ldrex/strex happens to work (within that one processor).

Note ARM has always allowed unaligned accesses, sometimes by default (ARM7TDMI) after that the default was to throw a data abort, but you could change the setting so that it didn't. Unaligned on ARM does not do what x86 programmers want for example. if you read 32 bits at address 0x02 you don't necessarily get the collection of bytes 0x02, 0x03, 0x04, 0x05, you can/will get 0x02, 0x03, 0x00, 0x01, using a 32 bit AMBA/AXI bus. You MIGHT get the desired result on a 64 bit AMBA/AXI bus but maybe not, definitely on both 32 and 64 bit if you read 32 bits at address 0x0E you will get 0x0E 0x0F and either 0x08 0x09 or 0x0c 0x0D. Not at all what programmers are expecting (usually, some who know how it works use it as a nice byte swapper), so it is often left as throwing a data abort and the programmer fixing their code.

C compilers very often create unaligned accesses, which is why it is hard for x86 programmers to either port their code or move from that platform to any other system. They do pay a heavy penalty on x86 (horrible performance), but not as heavy a penalty as other processors (memory aborts). SO is loaded with questions on the topic, how do I make my code run on xyz processor.

I'll get off the soap box. ARM does an excellent job of documenting all of this stuff (relative to other chip vendors). The TRM (technical reference manual, each core has one) describes the AMBA/AXI bus or bus choices and will get into the transaction types. Then the AMBA/AXI documents go further to explain what is going on. The hole there might be a map between instructions and the transaction types. When you do an ldm of 6 words at an address of 0x4 on a 64 bit AXI bus you get one 32 bit read at address 4, length of 1. You then get a length of 2 64 bit read (four bytes) at address 0x8 (covering words 0x8, 0xC, 0x10 and 0x14, then a separate 32 bit read at address 0x18. Just because it becomes 3 axi transactions does not mean it is non-atomic; it leaves an opportunity for it to be non-atomic, sure, but you would have to check the ARM docs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top