mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 10:19:28 +02:00
fix InterlockedCompareExchange on ARM-Linux: kuser_cmpxchg destroys r3, which needs to be restored, if we have to loop
git-svn-id: trunk@32063 -
This commit is contained in:
parent
7e6ba9db2a
commit
c81290bc94
@ -970,8 +970,6 @@ asm
|
||||
{$else}
|
||||
{$ifdef SYSTEM_HAS_KUSER_CMPXCHG}
|
||||
stmfd r13!, {r4, lr}
|
||||
mvn r3, #0x0000f000
|
||||
sub r3, r3, #0x3F
|
||||
|
||||
mov r4, r2 // Swap parameters around
|
||||
mov r2, r0
|
||||
@ -979,9 +977,13 @@ asm
|
||||
|
||||
// r1 and r2 will not be clobbered by kuser_cmpxchg
|
||||
// If we have to loop, r0 will be set to the original Comperand
|
||||
// kuser_cmpxchg is documented to destroy r3, therefore setting
|
||||
// r3 must be in the loop
|
||||
.Linterlocked_compare_exchange_loop:
|
||||
mvn r3, #0x0000f000
|
||||
sub r3, r3, #0x3F
|
||||
{$ifdef CPUARM_HAS_BLX}
|
||||
blx r3 // Call kuser_cmpxchg, sets C-Flag on success
|
||||
blx r3 // Call kuser_cmpxchg, sets C-Flag on success
|
||||
{$else}
|
||||
mov lr, pc
|
||||
{$ifdef CPUARM_HAS_BX}
|
||||
@ -997,11 +999,11 @@ asm
|
||||
// The loop case is HIGHLY unlikely, it would require that we got rescheduled between
|
||||
// calling kuser_cmpxchg and the ldr. While beeing rescheduled another process/thread
|
||||
// would have the set the value to our comperand
|
||||
ldr r0, [r2] // Load the currently set value
|
||||
ldr r0, [r2] // Load the currently set value
|
||||
cmp r0, r4 // Return if Comperand != current value, otherwise loop again
|
||||
ldmnefd r13!, {r4, pc}
|
||||
// If we need to loop here, we have to
|
||||
b .Linterlocked_compare_exchange_loop
|
||||
b .Linterlocked_compare_exchange_loop
|
||||
|
||||
{$else}
|
||||
// lock
|
||||
|
Loading…
Reference in New Issue
Block a user