What are the SWP and LDREX/STREX instructions? SWP (v3 onwards) and LDREX/STREX (v6 onwards) are instructions designed to support multi-master systems e.g. systems with multiple cores or systems with other bus masters such as a DMA controller. Their primary purpose is to maintain the integrity of shared data structures during inter-master communication by preventing two masters making conflicting accesses at the same time. SWP provides an atomic load and store operation which can be used as the basic building block for mutexes, semaphores etc. LDREX/STREX allow a bus master to detect that another master has written to an address it wanted exclusive access to. Again this can be used to build various higher level locks. The advantage of LDREX/STREX is that it does not prevent other transactions on the bus (a core executing SWP takes over the bus until the instruction is completed, by asserting the HLOCK signal) These instructions are also useful on a single master system to implement mutexes, semaphores, etc. without needing to disable interrupts. In the same way they are also useful for multi-threaded systems. SWP has been deprecated since architecture v6. On a v6 or later core (ARM11 onwards) you should use the LDREX/STREX instructions instead. For more information see the ARM Architecture Reference Manual and the AMBA documentation. C compiler behaviour The C compiler will not generate either SWP or LDREX/STREX when compiling pure C source code; this is because the C (and C++) language specification does not mention these kind of operations and therefore there are no operators in the language that map to these instructions. You can however, use these instructions in the embedded assembler from within the C compiler in which case they will obviously appear in the resulting object e.g. /* Embedded assembler to access the SWP instruction */ __asm atomic_swap(unsigned int read, unsigned int write, unsigned int addr) { SWP r0,r1,[r2] }
The inline assembler also supports SWP and LDREX/STREX. RVCT 3.1 also adds new intrinsics __swp, __ldrex and _strex.
Related:
|