4.3.1. Example of using barriers

Consider the case where you have two cores, A and B, and two addresses in Normal memory (Addr1 and Addr2) held in core registers. Each core executes two instructions, as shown in Example 4.3:

Example 4.3. Code example showing memory ordering issues

Core A:

STR R0, [Addr1]
LDR R1, [Addr2]
Core B:

STR R2, [Addr2]
LDR R3, [Addr1]

There is no ordering requirement. The transactions might occur in different orders. The addresses Addr1 and Addr2 are independent. There is no requirement on either core to execute the load and store in the order written in the program, or to care about the activity of the other core.

There are four possible legal outcomes of this piece of code:

If you involve a third core C, there is no requirement that it observes either of the stores in the same order as either of the other cores. It is possible for both A and B to see an old value in Addr1 and Addr2, but for C to see the new values.

Consider the case where the code on B looks for a flag set by A and then reads data from A. You might have code similar to that in Example 4.4:

Example 4.4. Possible ordering hazard with postbox

Core A:

STR R0, [Msg]       @ write some new data into postbox
STR R1, [Flag]      @ new data is ready to read
Core B:

Poll_loop:
      LDR R1, [Flag]
      CMP R1,#0     @ is the flag set yet?
      BEQ Poll_loop
      LDR R0, [Msg] @ read new data. 

This program might not behave in an expected way. It is possible that core B performs the read from [Msg] before the read from [Flag]. This is normal for weakly-ordered memory. The core has no knowledge of a possible dependency between the two.

You must explicitly enforce the dependency by inserting a memory barrier. In this example, you actually require two memory barriers.

Core A requires a DMB between the two store operations, to ensure that they occur in the order you originally specified.

Core B requires a DMB before the LDR R0, [Msg], to ensure that the message is read-only after the flag is set.

You can rewrite the code as Example 4.5.

Example 4.5. Using barriers to ensure the correct order for postbox

Core A:

STR R0, [Msg]       @ write some new data into postbox
DMB
STR R1, [Flag]      @ new data is ready to read
Core B:

Poll_loop:
      LDR R1, [Flag]
      CMP R1,#0     @ is the flag set yet?
      BEQ Poll_loop
      DMB
      LDR R0, [Msg] @ read new data. 

Copyright © 2014 ARM. All rights reserved.ARM DAI0425
Non-ConfidentialID080414