Fix atomic operations on PA-RISC 2.0 processors.
PA-RISC 2.0 supports out-of-order execution for loads and stores. Thus, we need to synchonize memory accesses. This change revises the lock releases in __exchange_and_add and __atomic_add to use an ordered store with release semantics. We also use an ordered load in the inner spin loop. We use the "ldcw,co" instruction instead of "ldcw" when compiled for PA 2.0. Most PA 2.0 processors are coherent and can execute the ldcw instruction in cache for improved performance. Finally, the inner spin loop is revised to immediately branch to the ldcw instruction when it detects the lock is free. 2023-01-05 John David Anglin <danglin@gcc.gnu.org> libstdc++-v3/ChangeLog: * config/cpu/hppa/atomicity.h (_PA_LDCW_INSN): Define. (__exchange_and_add): Use _PA_LDCW_INSN. Use ordered store for lock release. Revise loop. (__atomic_add): Likewise.
This commit is contained in:
parent
4413365616
commit
9807c31af9
1 changed files with 19 additions and 10 deletions
|
@ -25,6 +25,15 @@
|
|||
#include <bits/c++config.h>
|
||||
#include <ext/atomicity.h>
|
||||
|
||||
/* Perform ldcw operation in cache when possible. */
|
||||
#ifndef _PA_LDCW_INSN
|
||||
# ifdef _PA_RISC2_0
|
||||
# define _PA_LDCW_INSN "ldcw,co"
|
||||
# else
|
||||
# define _PA_LDCW_INSN "ldcw"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
@ -51,19 +60,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
int tmp;
|
||||
volatile int& lock = _Atomicity_lock<0>::_S_atomicity_lock;
|
||||
|
||||
__asm__ __volatile__ ("ldcw 0(%1),%0\n\t"
|
||||
__asm__ __volatile__ (_PA_LDCW_INSN " 0(%1),%0\n\t"
|
||||
"cmpib,<>,n 0,%0,.+20\n\t"
|
||||
"ldw 0(%1),%0\n\t"
|
||||
"cmpib,= 0,%0,.-4\n\t"
|
||||
"ldw,ma 0(%1),%0\n\t"
|
||||
"cmpib,<> 0,%0,.-12\n\t"
|
||||
"nop\n\t"
|
||||
"b,n .-20"
|
||||
"b,n .-12"
|
||||
: "=&r" (tmp)
|
||||
: "r" (&lock)
|
||||
: "memory");
|
||||
|
||||
result = *__mem;
|
||||
*__mem = result + __val;
|
||||
__asm__ __volatile__ ("stw %1,0(%0)"
|
||||
__asm__ __volatile__ ("stw,ma %1,0(%0)"
|
||||
: : "r" (&lock), "r" (tmp) : "memory");
|
||||
return result;
|
||||
}
|
||||
|
@ -75,18 +84,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
int tmp;
|
||||
volatile int& lock = _Atomicity_lock<0>::_S_atomicity_lock;
|
||||
|
||||
__asm__ __volatile__ ("ldcw 0(%1),%0\n\t"
|
||||
__asm__ __volatile__ (_PA_LDCW_INSN " 0(%1),%0\n\t"
|
||||
"cmpib,<>,n 0,%0,.+20\n\t"
|
||||
"ldw 0(%1),%0\n\t"
|
||||
"cmpib,= 0,%0,.-4\n\t"
|
||||
"ldw,ma 0(%1),%0\n\t"
|
||||
"cmpib,<> 0,%0,.-12\n\t"
|
||||
"nop\n\t"
|
||||
"b,n .-20"
|
||||
"b,n .-12"
|
||||
: "=&r" (tmp)
|
||||
: "r" (&lock)
|
||||
: "memory");
|
||||
|
||||
*__mem += __val;
|
||||
__asm__ __volatile__ ("stw %1,0(%0)"
|
||||
__asm__ __volatile__ ("stw,ma %1,0(%0)"
|
||||
: : "r" (&lock), "r" (tmp) : "memory");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue