* sync opal_atomic_cmpset_{32,64} for AMD64 with the x86 32 bit version,
as I understand how that one works and don't really understand what was in the amd64 code (which was copied from before I started working on the inline assembly). This fixes the race condition we were seeing on PGI causing test failures * sync non-inline assembly with inline assembly version This needs to go to the v1.0 branch This commit was SVN r9539.
Этот коммит содержится в:
родитель
f6bbe033f0
Коммит
6691e55d30
@ -26,46 +26,19 @@ END_FUNC(opal_atomic_wmb)
|
||||
|
||||
|
||||
START_FUNC(opal_atomic_cmpset_32)
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
movq %rdi, -8(%rbp)
|
||||
movl %esi, -12(%rbp)
|
||||
movl %edx, -16(%rbp)
|
||||
movl -16(%rbp), %ecx
|
||||
movq -8(%rbp), %rdx
|
||||
movl -12(%rbp), %eax
|
||||
cmpxchgl %ecx,(%rdx)
|
||||
movq %rax, -24(%rbp)
|
||||
movl -24(%rbp), %eax
|
||||
movl %eax, -28(%rbp)
|
||||
movl -28(%rbp), %eax
|
||||
cmpl -12(%rbp), %eax
|
||||
sete %al
|
||||
movzbl %al, %eax
|
||||
movl %eax, -28(%rbp)
|
||||
movl -28(%rbp), %eax
|
||||
leave
|
||||
movl %esi, %eax
|
||||
lock; cmpxchgl %edx,(%rdi)
|
||||
sete %dl
|
||||
movzbl %dl, %eax
|
||||
ret
|
||||
END_FUNC(opal_atomic_cmpset_32)
|
||||
|
||||
|
||||
START_FUNC(opal_atomic_cmpset_64)
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
movq %rdi, -8(%rbp)
|
||||
movq %rsi, -16(%rbp)
|
||||
movq %rdx, -24(%rbp)
|
||||
movq -24(%rbp), %rcx
|
||||
movq -8(%rbp), %rdx
|
||||
movq -16(%rbp), %rax
|
||||
cmpxchgq %rcx,(%rdx)
|
||||
|
||||
movq %rax, -32(%rbp)
|
||||
movq -32(%rbp), %rax
|
||||
cmpq -16(%rbp), %rax
|
||||
sete %al
|
||||
movzbl %al, %eax
|
||||
leave
|
||||
movq %rsi, %rax
|
||||
lock; cmpxchgq %rdx,(%rdi)
|
||||
sete %dl
|
||||
movzbl %dl, %eax
|
||||
ret
|
||||
END_FUNC(opal_atomic_cmpset_64)
|
||||
|
||||
|
@ -81,12 +81,15 @@ static inline void opal_atomic_wmb(void)
|
||||
static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
|
||||
int32_t oldval, int32_t newval)
|
||||
{
|
||||
unsigned long prev;
|
||||
__asm__ __volatile__(SMPLOCK "cmpxchgl %1,%2"
|
||||
: "=a"(prev)
|
||||
: "q"(newval), "m"(*addr), "0"(oldval)
|
||||
: "cc", "memory");
|
||||
return ((int32_t)prev == oldval);
|
||||
unsigned char ret;
|
||||
__asm__ __volatile (
|
||||
SMPLOCK "cmpxchgl %1,%2 \n\t"
|
||||
"sete %0 \n\t"
|
||||
: "=qm" (ret)
|
||||
: "q"(newval), "m"(*((volatile long*)addr)), "a"(oldval)
|
||||
: "memory");
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
#endif /* OMPI_GCC_INLINE_ASSEMBLY */
|
||||
@ -99,15 +102,15 @@ static inline int opal_atomic_cmpset_32( volatile int32_t *addr,
|
||||
static inline int opal_atomic_cmpset_64( volatile int64_t *addr,
|
||||
int64_t oldval, int64_t newval)
|
||||
{
|
||||
int64_t prev;
|
||||
|
||||
unsigned char ret;
|
||||
__asm__ __volatile (
|
||||
SMPLOCK "cmpxchgq %1,%2 \n\t"
|
||||
: "=a" (prev)
|
||||
: "q" (newval), "m" (*(addr)), "0"(oldval)
|
||||
: "cc", "memory");
|
||||
"sete %0 \n\t"
|
||||
: "=qm" (ret)
|
||||
: "q"(newval), "m"(*((volatile long*)addr)), "a"(oldval)
|
||||
: "memory");
|
||||
|
||||
return (prev == oldval);
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
#endif /* OMPI_GCC_INLINE_ASSEMBLY */
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user