Assembly – atomic Int64 on ARM cortex M3_ t
Since my compiler still doesn't support C 11 and STD:: Atomic, I have to implement it manually through ldrex STREX pairs
My question is: read – modify – write Int64 "atomically" with ldrex and STREX_ What is the correct method of T?
Simple solutions like this don't seem to work (one of strexw always returns 1):
volatile int64_t value; int64_t temp; do { int32_t low = __LDREXW( (uint32_t *)&value ); int32_t high = __LDREXW( ((uint32_t *)&value)+1 ); temp = (int64_t)low | ( (int64_t)high<<32); temp++; } while( __STREXW( temp,(uint32_t *)&value) | __STREXW( temp>>32,((uint32_t *)&value)+1) );
I can't find anything about several consecutive ldrex or STREX instructions pointing to different addresses in the manual, but in my opinion, it should be allowed
Otherwise, in some cases, multiple threads will not be able to change two different atomic variables
Solution
This will not work because you cannot nest exclusions in this way In terms of implementation, the Cortex-M3 local dedicated monitor does not even track the address - the exclusive reservation granule is the entire address space - so the assumption of tracking each word separately is invalid However, you don't even need to consider any implementation details because the architecture explicitly excludes back-to-back links:
Since Cortex-M3 (and general armv7-m) does not have ldrexd like armv7-a, you must either use a separate lock to control all access to variables, or just disable read modify interrupt write If possible, it's really better to redesign things that don't need atomic 64 bit types first, because you can still only achieve atomicity relative to other threads on the same core - you can't do any 64 bit operation atoms at all. From the perspective of external agents (such as DMA controllers)