We tried to implement an atomic decrement like this:
R3 address (16bit aligned)
R4 temp register
lharx r4, 0, r3 ; Load byte and reserve address
e_subi r4, r4, 0x1 ; Decrement r4 by one
sthcx. r4, 0, r3 ; Try to store r4 to reserved half-word address
e_bne- Os_Platform_AtomicDecrementUint16 ; Loop if reservation has been lost (store has failed)
se_blr ; Return
If two concurrent cores executing this function (Os_Platform_AtomicDecrementUint16) at the same time, we expected that this is atomic operation but it’s not.
So cores separately can reserve the address but cannot detect each other’s store.
/* Initial value */
atomicValue = 2;
/* Concurrent execution */
atomicValue is 1, not 0, as expected.
So basically we thought that this is a limitation due to the lack of compare on physical addresses:
User Manual 18.104.22.168 PowerISA 2.06 Compatibility
Thanks in advance.