Bug#278379: Atomic stdc++ operations are broken on some MIPS machines
Package: gcc-3.3
Version: 3.3.5-1
Severity: important
While trying to run Debian on a SGI O200 Machine I found out that the
inline assembly to handle atomic operations in libstdc++ is broken.
The effect is very visible: "apt-get update" hangs in an endless loop
on startup, same for every other c++ program I tried. This happens on
machines with R10000 CPU, others may show degraded performance.
R10000 CPUs aren't yet officially supported in Debian, so I used
serverity important for this bugreport.
The problem is caused by inserting normal load operation in the atomic
loop, which isn't guaranteed to work. The load is generated by the
assembler to fulfill the memory reference, so it isn't visible in the
source.
The appended patch fixes it. It also changes the branch to the likely
variant, this works around some breakage in early R10000 silicon.
The patch is against gcc-3.3, newer gccs have the same problem, but
have some apparently bogus changes in that area.
Thiemo
#! /bin/sh -e
# All lines beginning with `# DPATCH:' are a description of the patch.
# DP: Fix libstdc++ atomic ops for mips/mipsel
dir=
if [ $# -eq 3 -a "$2" = '-d' ]; then
pdir="-d $3"
dir="$3/"
elif [ $# -ne 1 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch)
patch $pdir -f --no-backup-if-mismatch -p0 < $0
#cd ${dir}gcc && autoconf
;;
-unpatch)
patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
#rm ${dir}gcc/configure
;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
esac
exit 0
--- libstdc++-v3/config/cpu/mips/atomicity.h.old 2003-06-02 20:04:54.000000000 +0200
+++ libstdc++-v3/config/cpu/mips/atomicity.h 2004-10-23 17:41:38.000000000 +0200
@@ -40,17 +40,19 @@ __exchange_and_add (volatile _Atomic_wor
__asm__ __volatile__
("/* Inline exchange & add */\n\t"
- "1:\n\t"
".set push\n\t"
".set mips2\n\t"
- "ll %0,%3\n\t"
- "addu %1,%4,%0\n\t"
- "sc %1,%2\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n"
+ "1:\tll %0,(%2)\n\t"
+ "addu %1,%3,%0\n\t"
+ "sc %1,(%2)\n\t"
+ ".set reorder\n\t"
+ "beqzl %1,1b\n\t"
".set pop\n\t"
- "beqz %1,1b\n\t"
- "/* End exchange & add */"
- : "=&r"(__result), "=&r"(__tmp), "=m"(*__mem)
- : "m" (*__mem), "r"(__val)
+ "/* End exchange & add */\n"
+ : "=&r"(__result), "=&r"(__tmp), "+r"(__mem)
+ : "r"(__val)
: "memory");
return __result;
@@ -64,17 +66,19 @@ __atomic_add (volatile _Atomic_word *__m
__asm__ __volatile__
("/* Inline atomic add */\n\t"
- "1:\n\t"
".set push\n\t"
".set mips2\n\t"
- "ll %0,%2\n\t"
- "addu %0,%3,%0\n\t"
- "sc %0,%1\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n"
+ "1:\tll %0,(%1)\n\t"
+ "addu %0,%2,%0\n\t"
+ "sc %0,(%1)\n\t"
+ ".set reorder\n\t"
+ "beqzl %0,1b\n\t"
".set pop\n\t"
- "beqz %0,1b\n\t"
- "/* End atomic add */"
- : "=&r"(__result), "=m"(*__mem)
- : "m" (*__mem), "r"(__val)
+ "/* End atomic add */\n"
+ : "=&r"(__result), "+r"(__mem)
+ : "r"(__val)
: "memory");
}
Reply to: