We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
; void acquireLock(int* lockAddr)acquireLock LDREX r1, [r0] CMP r1, #0 ; 0 = unlocked WFENE MOVEQ r2, #1 ; 1 = locked STREXEQ r3, r2, [r0] ; r3 = 1, but the store DOES occur! CMPEQ r3, #0 BNE acquireLock DMB MOV pc, lr
More on this...I am trying to implement a lock based on section 7.3 of the barrier cookbook linked to above. Here is my function, called from a C program. ; void acquireLock(int* lockAddr)acquireLock LDREX r1, [r0] CMP r1, #0 ; 0 = unlocked WFENE MOVEQ r2, #1 ; 1 = locked STREXEQ r3, r2, [r0] ; r3 = 1, but the store DOES occur! CMPEQ r3, #0 BNE acquireLock DMB MOV pc, lr On first execution, it reads the value from *lockAddr and it is 0 (i.e. r1=0). So it gets to the STREXEQ instruction, which DOES store value 1 in memory, but the return value r3=1 (failure). So, it branches back to the top, reads that value again and it is 1 (r1=1). So it the does WFENE and enters wait mode (it actually does this twice, the first time it does not go into wait mode but returns just to reach that same WFENE as the logic has not changed and it hangs then). My other process eventually enters the same WFENE loop as the value is still 1. According to the assembler guide there are a couple reasons by the STREX could return 1 in r3, but both involve the store failing as well. I see through the code logic and my environment memory tools that the store did occur. The memory location r0 refers to is cacheable, bufferable and shared.Any ideas?
Just wanted to bump my last question...I have been continuing to look into it and can't make sense of it. Very strange that STREX returns 1 yet the store occurs in memory. Does anyone have an idea?