AnsweredAssumed Answered

Are atomic write operations with reservation instructions possible on MPC57xx multicore derivatives to achieve mutual exclusion ?

Question asked by Martin Schultheiss on Oct 26, 2016
Latest reply on Dec 5, 2016 by Lukas Zadrapa

Dear NXP Support,

 

for our PPC OS we want to use reservation instructions (lwarx, stwcx) to implement the spinlock mechanism to achieve mutual exclusion between different cores. We want to solve it in software because of compatibility issues (not all controllers have a semaphore unit) and to evade the restriction of a limited number of configurable spinlocks.

 

Our solution looks as follows (Greenhills assembler macro on MPC5775K):

__asm uint32 AtomicSpinlockWrite(uint32 Addr, uint32 Value)
{
%reg Addr %con Value %lab NoSuccess, Success
  se_li   r5, Value      /* load value in r5 */
  lwarx   r3,0,Addr      /* load and reserve */
  e_cmpwi r3,0           /* if not eq 0 */
  se_bne  NoSuccess      /* spinlock locked, return 0*/
  stwcx.  r5,0,Addr      /* try to store non-0 */
  se_bne  NoSuccess      /* if lost reservation return 0 */
  se_li   r3, 1          /* else load return-value 1 */
  e_b Success            /* and goto Success */
NoSuccess:
   se_li  r3, 0          /* return 0 */
Success:
%error
}

Description:

We expect, that if Core0 executes lwarx and reads the value 0, it will proceed with writing the value 1 to the memory address. This write should work, if the value at address "Addr" has not been changed (e.g. by writing of another core) and it should fail otherwise. But currently this mechanism does not work. We checked it with the Lauterbach Debugger.

  • Core0 executes lwarx --> reads value 0 in r3 and after comparison we stopped before execution of stwcx
  • Core1 executed lwarx --> reads value 0 (because Core0 has not written anything) in r3 and after comparison we stopped before execution of stwcx
  • In both Cores HID1[ATS] is 1, so reservation was done
  • Core0 executes the stwcx command, value 1 is written to addr and EQ is set in CR, so the write succeeds and we return 1
  • Core1 executes the stwcx command and even there it works, EQ is set and we return success, so both cores now have the spinlock - damn ;-)

 

Can you please explain where we did not understand the behavior of lwarx/stwcx or where our mistake is ?

Thanks in advance!

 

Best regards

Martin

Outcomes