Recently I've encountered an issue with atomics and the cache. When data is in a cacheable region (tested with both DDR and OCRAM), any atomic read-modify-write operation (atomic_compare_exchange_strong, fetch_add, etc.) doesn't operate as expected. I've attached an example that illustrates the problem (as well as a patch that applies to the NXP provided FreeRTOS BSP 1.0.1). The inconsistency appears only with read-modify-write operations, which use Load-Link and Store Conditional instructions. If only atomic loads and stores are used, the program functions as expected.
Here is the output from the example attached. The example was tested on an i.MX7DSabreSD Rev D. Board:
state intial value: 3
state after store 1: 1
CAS failed: Value is 3741011900, expected 1
state after CAS (should = 2): 1
state after invalidate (should = 2): 2
In the output above, you can see that the CAS doesn't see the initial value `3` or the stored value `1` (and instead sees 3741011900). After pushing the cache, the next CAS sees the correct value of '1', and supposedly stores a 2. The next load though, doesn't see a 2, but sees a stale value of 1. If the cache is invalidated, so that the load value is loaded from DDR or OCRAM, the correct value of 2 is read.
Is there some configuration that needs to be done in order to for caching to work with atomics? It seems as if Load-link and Store-Conditionals are going around the cache to either DDR or OCRAM.
Original Attachment has been moved to: 0001-Example-of-Atomic-CAS-not-functioning-with-cache.patch.zip
Original Attachment has been moved to: main.c.zip