Dear Support,
We tried to implement an atomic decrement like this:
R3 address (16bit aligned)
R4 temp register
Os_Platform_AtomicDecrementUint16:
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.
For example:
/* Initial value */
atomicValue = 2;
/* Concurrent execution */
Core0: Os_Platform_AtomicDecrementUint16(&atomicValue)
Core1: Os_Platform_AtomicDecrementUint16(&atomicValue)
/*Result */
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 62.1.1.1 PowerISA 2.06 Compatibility
Thanks in advance.
Regards,
Janos Bai
Mentor Graphics
Hi,
I can remember that on other devices like MPC5643L or MPC5668G the reservation instructions work only on single core, not between the cores. The external reservation logic between the cores was not implemented. That means the reservation instructions can be used to implement a semaphore to protect a shared memory region between multiple tasks that are executing on a single CPU.
I did quick test and I can see that it is the same on MPC5748G. It works as expected on single core. But the external reservation logic is obviously not implemented, the reservation has no effect for other cores.
It looks like the only way is to use semaphores (SEMA42 module).
Regards,
Lukas