[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: