Since my compiler still does not support C ++ 11 and std :: atomic, I have to implement it manually through a couple of ldrex-strex.
My question is: what is the correct way to atomically read-modify-write int64_t using ldrex and strex?
A simple solution like this does not work (one of STREXW returns 1 all the time):
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 could not find anything about several consecutive LDREX or STREX instructions pointing to different addresses in the manual, but it seemed to me that this should be allowed.
Otherwise, multiple threads will not be able to change two different atomic variables in some scenarios.
source share