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)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>