[Mono-dev] Patch review request -- MIPS atomic io locking

mason mason at broadcom.com
Thu Jan 11 14:20:57 EST 2007


Hello all,

Please review the following MIPS-specific change to a shared header
file.  This change implements the atomic access primitives as needed
for MIPS.

Barring any objections, I'll check these changes in in the next few
days.

Thanks,
Mark

Index: mono/io-layer/atomic.h
===================================================================
--- mono/io-layer/atomic.h	(revision 70746)
+++ mono/io-layer/atomic.h	(working copy)
@@ -924,6 +924,88 @@
 	return(ret);
 }
 
+#elif defined(__mips__)
+#define WAPI_ATOMIC_ASM
+
+static inline gint32 InterlockedIncrement(volatile gint32 *val)
+{
+	gint32 tmp, result = 0;
+
+	__asm__ __volatile__ ("    .set    mips32\n"
+			      "1:  ll      %0, %2\n"
+			      "    addu    %1, %0, 1\n"
+                              "    sc      %1, %2\n"
+			      "    beqz    %1, 1b\n"
+			      "    .set    mips0\n"
+			      : "=&r" (result), "=&r" (tmp), "=m" (*val)
+			      : "m" (*val));
+	return result + 1;
+}
+
+static inline gint32 InterlockedDecrement(volatile gint32 *val)
+{
+	gint32 tmp, result = 0;
+
+	__asm__ __volatile__ ("    .set    mips32\n"
+			      "1:  ll      %0, %2\n"
+			      "    subu    %1, %0, 1\n"
+                              "    sc      %1, %2\n"
+			      "    beqz    %1, 1b\n"
+			      "    .set    mips0\n"
+			      : "=&r" (result), "=&r" (tmp), "=m" (*val)
+			      : "m" (*val));
+	return result - 1;
+}
+
+#define InterlockedCompareExchangePointer(dest,exch,comp) InterlockedCompareExchange((volatile gint32 *)(dest), (gint32)(exch), (gint32)(comp))
+
+static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
+						gint32 exch, gint32 comp) {
+	gint32 old, tmp;
+
+	__asm__ __volatile__ ("    .set    mips32\n"
+			      "1:  ll      %0, %2\n"
+			      "    bne     %0, %5, 2f\n"
+			      "    move    %1, %4\n"
+                              "    sc      %1, %2\n"
+			      "    beqz    %1, 1b\n"
+			      "2:  .set    mips0\n"
+			      : "=&r" (old), "=&r" (tmp), "=m" (*dest)
+			      : "m" (*dest), "r" (exch), "r" (comp));
+	return(old);
+}
+
+static inline gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
+{
+	gint32 result, tmp;
+
+	__asm__ __volatile__ ("    .set    mips32\n"
+			      "1:  ll      %0, %2\n"
+			      "    move    %1, %4\n"
+                              "    sc      %1, %2\n"
+			      "    beqz    %1, 1b\n"
+			      "    .set    mips0\n"
+			      : "=&r" (result), "=&r" (tmp), "=m" (*dest)
+			      : "m" (*dest), "r" (exch));
+	return(result);
+}
+#define InterlockedExchangePointer(dest,exch) InterlockedExchange((volatile gint32 *)(dest), (gint32)(exch))
+
+static inline gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
+{
+        gint32 result, tmp;
+
+	__asm__ __volatile__ ("    .set    mips32\n"
+			      "1:  ll      %0, %2\n"
+			      "    addu    %1, %0, %4\n"
+                              "    sc      %1, %2\n"
+			      "    beqz    %1, 1b\n"
+			      "    .set    mips0\n"
+			      : "=&r" (result), "=&r" (tmp), "=m" (*dest)
+			      : "m" (*dest), "r" (add));
+        return result;
+}
+
 #else
 
 extern gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp);





More information about the Mono-devel-list mailing list