diff options
author | Geoff Norton <grompf@sublimeintervention.com> | 2010-06-29 23:53:51 +0400 |
---|---|---|
committer | Geoff Norton <grompf@sublimeintervention.com> | 2010-06-29 23:53:51 +0400 |
commit | 4f3439fdbb3aa061e598bef42162c682247afa74 (patch) | |
tree | 54c9a39c4ef5860dc8e116ea96b5794e1ca0f6a6 /libgc/include | |
parent | c92f6fd23e77e300744c3e5df0cdcd169379b265 (diff) |
2010-06-29 Geoff Norton <gnorton@novell.com>
* include/private/gc_locks.h: Implement armv6+ variants of
GC_test_and_set
svn path=/trunk/mono/; revision=159690
Diffstat (limited to 'libgc/include')
-rw-r--r-- | libgc/include/private/gc_locks.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/libgc/include/private/gc_locks.h b/libgc/include/private/gc_locks.h index 7b8e6e1bda6..df8736d3d4e 100644 --- a/libgc/include/private/gc_locks.h +++ b/libgc/include/private/gc_locks.h @@ -224,6 +224,19 @@ # endif /* ALPHA */ # ifdef ARM32 inline static int GC_test_and_set(volatile unsigned int *addr) { +#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__) + int ret, tmp; + __asm__ __volatile__ ( + "1:\n" + "ldrex %0, [%3]\n" + "strex %1, %2, [%3]\n" + "teq %1, #0\n" + "bne 1b\n" + : "=&r" (ret), "=&r" (tmp) + : "r" (1), "r" (addr) + : "memory", "cc"); + return ret; +#else int oldval; /* SWP on ARM is very similar to XCHG on x86. Doesn't lock the * bus because there are no SMP ARM machines. If/when there are, @@ -234,6 +247,7 @@ : "r"(1), "r"(addr) : "memory"); return oldval; +#endif } # define GC_TEST_AND_SET_DEFINED # endif /* ARM32 */ |