| Newsgroups |
gmane.comp.gnome.mono.patches |
| Message-ID |
<00000141dbf7c8ab-929bc190-acc4-4ef4-b29d-fa9970b133e2-000000@email.amazonses.com> |
Branch: refs/heads/master
Home: https://github.com/mono/mono
Compare: https://github.com/mono/mono/compare/17d4130d1b86...e4d2cc49a03b
Commit: 9dd59c1f1381ad7645039e33b7c2120078bfa349
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:24 GMT
URL: https://github.com/mono/mono/commit/9dd59c1f1381ad7645039e33b7c2120078bfa349
Remove unneeded NetBSD code path from atomic.h.
Changed paths:
M mono/utils/atomic.h
Modified: mono/utils/atomic.h
===================================================================
@@ -11,16 +11,6 @@
#ifndef _WAPI_ATOMIC_H_
#define _WAPI_ATOMIC_H_
-#if defined(__NetBSD__)
-#include <sys/param.h>
-
-#if __NetBSD_Version__ > 499004000
-#include <sys/atomic.h>
-#define HAVE_ATOMIC_OPS
-#endif
-
-#endif
-
#include "config.h"
#include <glib.h>
@@ -105,46 +95,6 @@ static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64
#endif
-
-#elif defined(__NetBSD__) && defined(HAVE_ATOMIC_OPS)
-
-static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
- gint32 exch, gint32 comp)
-{
- return atomic_cas_32((uint32_t*)dest, comp, exch);
-}
-
-static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
-{
- return atomic_cas_ptr(dest, comp, exch);
-}
-
-static inline gint32 InterlockedIncrement(volatile gint32 *val)
-{
- return atomic_inc_32_nv((uint32_t*)val);
-}
-
-static inline gint32 InterlockedDecrement(volatile gint32 *val)
-{
- return atomic_dec_32_nv((uint32_t*)val);
-}
-
-static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
-{
- return atomic_swap_32((uint32_t*)val, new_val);
-}
-
-static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
- gpointer new_val)
-{
- return atomic_swap_ptr(val, new_val);
-}
-
-static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
-{
- return atomic_add_32_nv((uint32_t*)val, add) - add;
-}
-
#elif (defined(sparc) || defined (__sparc__)) && defined(__GNUC__)
G_GNUC_UNUSED
Commit: fd6f60245f2f6651bf93da05b9a0b7c60ab9ded3
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:24 GMT
URL: https://github.com/mono/mono/commit/fd6f60245f2f6651bf93da05b9a0b7c60ab9ded3
Simplify the ifdeffery in atomic.c/.h a bit.
Changed paths:
M mono/utils/atomic.c
M mono/utils/atomic.h
Modified: mono/utils/atomic.c
===================================================================
@@ -13,7 +13,7 @@
#include <mono/utils/atomic.h>
-#if defined (WAPI_NO_ATOMIC_ASM) || !defined (HAS_64BITS_ATOMICS)
+#if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
#include <pthread.h>
@@ -197,11 +197,13 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
return(ret);
}
+#define NEED_64BIT_CMPXCHG_FALLBACK
+
#endif
-#ifndef HAS_64BITS_ATOMICS
+#if defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
-#if defined (TARGET_MACH) && defined (TARGET_ARM) && (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__))
+#if defined (TARGET_MACH) && defined (TARGET_ARM) && defined (HAVE_ARMV7)
gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) __attribute__ ((naked));
@@ -240,6 +242,14 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
#else
+#define NEED_64BIT_CMPXCHG_FALLBACK
+
+#endif
+
+#endif
+
+#if defined (NEED_64BIT_CMPXCHG_FALLBACK)
+
gint64
InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
{
@@ -256,4 +266,3 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
}
#endif
-#endif
Modified: mono/utils/atomic.h
===================================================================
@@ -22,7 +22,6 @@
#if defined(__WIN32__) || defined(_WIN32)
#include <windows.h>
-#define HAS_64BITS_ATOMICS 1
/* mingw is missing InterlockedCompareExchange64 () from winbase.h */
#if HAVE_DECL_INTERLOCKEDCOMPAREEXCHANGE64==0
@@ -84,9 +83,7 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
#define BROKEN_64BIT_ATOMICS_INTRINSIC 1
#endif
-
#if !defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
-#define HAS_64BITS_ATOMICS 1
static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
{
@@ -505,8 +502,10 @@ static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
#endif
-#ifndef HAS_64BITS_ATOMICS
+#if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
+
extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
+
#endif
#endif /* _WAPI_ATOMIC_H_ */
Commit: a33ce0c39fe7aa04292eb2fa2d0c89da7ba02c6e
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:24 GMT
URL: https://github.com/mono/mono/commit/a33ce0c39fe7aa04292eb2fa2d0c89da7ba02c6e
Use host preprocessor identifiers in atomic.c, not target.
Here we care about the system we run on, not the kind of
system that Mono is built to compile for.
Changed paths:
M mono/utils/atomic.c
Modified: mono/utils/atomic.c
===================================================================
@@ -203,7 +203,7 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
#if defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
-#if defined (TARGET_MACH) && defined (TARGET_ARM) && defined (HAVE_ARMV7)
+#if defined (TARGET_MACH) && defined (__arm__) && defined (HAVE_ARMV7)
gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) __attribute__ ((naked));
@@ -232,7 +232,7 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
);
}
-#elif defined (TARGET_MACH) && (defined (TARGET_X86) || defined (TARGET_AMD64))
+#elif defined (TARGET_MACH) && (defined (__i386__) || defined (__x86_64__))
gint64
InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
Commit: bf0b8a1d1aa61d5123b2a812cc9c4665d2d97d93
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:24 GMT
URL: https://github.com/mono/mono/commit/bf0b8a1d1aa61d5123b2a812cc9c4665d2d97d93
Remove unneeded ARM code from atomic.c.
Changed paths:
M mono/utils/atomic.c
Modified: mono/utils/atomic.c
===================================================================
@@ -203,36 +203,7 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
#if defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
-#if defined (TARGET_MACH) && defined (__arm__) && defined (HAVE_ARMV7)
-
-gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) __attribute__ ((naked));
-
-gint64
-InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
-{
- __asm__ (
- "push {r4, r5, r6, r7}\n"
- "ldr r4, [sp, #16]\n"
- "dmb\n"
-"1:\n"
- "ldrexd r6, r7, [r0]\n"
- "cmp r7, r4\n"
- "bne 2f\n"
- "cmp r6, r3\n"
- "bne 2f\n"
- "strexd r5, r1, r2, [r0]\n"
- "cmp r5, #0\n"
- "bne 1b\n"
-"2:\n"
- "dmb\n"
- "mov r0, r6\n"
- "mov r1, r7\n"
- "pop {r4, r5, r6, r7}\n"
- "bx lr\n"
- );
-}
-
-#elif defined (TARGET_MACH) && (defined (__i386__) || defined (__x86_64__))
+#if defined (TARGET_OSX)
gint64
InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
Commit: a3632c6274fa78c7de1bcb8eb62c021861a205a9
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:25 GMT
URL: https://github.com/mono/mono/commit/a3632c6274fa78c7de1bcb8eb62c021861a205a9
Use GCC atomics on s390x.
Changed paths:
M configure.in
M mono/utils/atomic.h
Modified: configure.in
===================================================================
@@ -2783,7 +2783,7 @@ esac
dnl Use GCC atomic ops if they work on the target.
if test x$GCC = "xyes"; then
case $TARGET in
- X86 | AMD64 | ARM | POWERPC | POWERPC64 | MIPS)
+ X86 | AMD64 | ARM | POWERPC | POWERPC64 | MIPS | S390X)
AC_DEFINE(USE_GCC_ATOMIC_OPS, 1, [...])
;;
esac
Modified: mono/utils/atomic.h
===================================================================
@@ -252,126 +252,6 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *_dest, gint32 add)
return ret;
}
-#elif __s390x__
-
-static inline gint32
-InterlockedCompareExchange(volatile gint32 *dest,
- gint32 exch, gint32 comp)
-{
- gint32 old;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "\tLR\t%1,%3\n"
- "\tCS\t%1,%2,0(1)\n"
- : "+m" (*dest), "=&r" (old)
- : "r" (exch), "r" (comp)
- : "1", "cc");
- return(old);
-}
-
-static inline gpointer
-InterlockedCompareExchangePointer(volatile gpointer *dest,
- gpointer exch,
- gpointer comp)
-{
- gpointer old;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "\tLGR\t%1,%3\n"
- "\tCSG\t%1,%2,0(1)\n"
- : "+m" (*dest), "=&r" (old)
- : "r" (exch), "r" (comp)
- : "1", "cc");
-
- return(old);
-}
-
-static inline gint32
-InterlockedIncrement(volatile gint32 *val)
-{
- gint32 tmp;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tLGF\t%0,%1\n"
- "\tLGFR\t1,%0\n"
- "\tAGHI\t1,1\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b\n"
- "\tLGFR\t%0,1"
- : "=r" (tmp), "+m" (*val)
- : : "1", "2", "cc");
-
- return(tmp);
-}
-
-static inline gint32
-InterlockedDecrement(volatile gint32 *val)
-{
- gint32 tmp;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tLGF\t%0,%1\n"
- "\tLGFR\t1,%0\n"
- "\tAGHI\t1,-1\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b\n"
- "\tLGFR\t%0,1"
- : "=r" (tmp), "+m" (*val)
- : : "1", "2", "cc");
-
- return(tmp);
-}
-
-static inline gint32
-InterlockedExchange(volatile gint32 *val, gint32 new_val)
-{
- gint32 ret;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "0:\tL\t%1,%0\n"
- "\tCS\t%1,%2,0(1)\n"
- "\tJNZ\t0b"
- : "+m" (*val), "=&r" (ret)
- : "r" (new_val)
- : "1", "cc");
-
- return(ret);
-}
-
-static inline gpointer
-InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
-{
- gpointer ret;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "0:\tLG\t%1,%0\n"
- "\tCSG\t%1,%2,0(1)\n"
- "\tJNZ\t0b"
- : "+m" (*val), "=&r" (ret)
- : "r" (new_val)
- : "1", "cc");
-
- return(ret);
-}
-
-static inline gint32
-InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
-{
- gint32 ret;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tLGF\t%0,%1\n"
- "\tLGFR\t1,%0\n"
- "\tAGR\t1,%2\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b"
- : "=&r" (ret), "+m" (*val)
- : "r" (add)
- : "1", "2", "cc");
-
- return(ret);
-}
-
#elif defined(__ia64__)
#ifdef __INTEL_COMPILER
Commit: 6d2008b01354eb309464eb5ca5650dcef8714f41
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:25 GMT
URL: https://github.com/mono/mono/commit/6d2008b01354eb309464eb5ca5650dcef8714f41
Remove MONO_ARCH_SAVE_REGS from threading icalls.
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1182,8 +1182,6 @@ HANDLE ves_icall_System_Threading_Thread_Thread_internal(MonoThread *this,
void ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThread *this, HANDLE thread)
{
- MONO_ARCH_SAVE_REGS;
-
THREAD_DEBUG (g_message ("%s: Closing thread %p, handle %p", __func__, this, thread));
if (thread)
@@ -1273,8 +1271,6 @@ void ves_icall_System_Threading_Thread_SpinWait_nop (void)
gint32
ves_icall_System_Threading_Thread_GetDomainID (void)
{
- MONO_ARCH_SAVE_REGS;
-
return mono_domain_get()->domain_id;
}
@@ -1640,8 +1636,6 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
guint32 ret;
MonoInternalThread *thread = mono_thread_internal_current ();
- MONO_ARCH_SAVE_REGS;
-
if (ms == -1)
ms = INFINITE;
@@ -1660,8 +1654,6 @@ HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned,
{
HANDLE mutex;
- MONO_ARCH_SAVE_REGS;
-
*created = TRUE;
if (name == NULL) {
@@ -1678,8 +1670,6 @@ HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned,
}
MonoBoolean ves_icall_System_Threading_Mutex_ReleaseMutex_internal (HANDLE handle ) {
- MONO_ARCH_SAVE_REGS;
-
return(ReleaseMutex (handle));
}
@@ -1689,8 +1679,6 @@ HANDLE ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name,
{
HANDLE ret;
- MONO_ARCH_SAVE_REGS;
-
*error = ERROR_SUCCESS;
ret = OpenMutex (rights, FALSE, mono_string_chars (name));
@@ -1706,8 +1694,6 @@ HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 ini
{
HANDLE sem;
- MONO_ARCH_SAVE_REGS;
-
*created = TRUE;
if (name == NULL) {
@@ -1728,8 +1714,6 @@ gint32 ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE ha
{
gint32 prevcount;
- MONO_ARCH_SAVE_REGS;
-
*fail = !ReleaseSemaphore (handle, releaseCount, &prevcount);
return (prevcount);
@@ -1739,8 +1723,6 @@ HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *
{
HANDLE ret;
- MONO_ARCH_SAVE_REGS;
-
*error = ERROR_SUCCESS;
ret = OpenSemaphore (rights, FALSE, mono_string_chars (name));
@@ -1755,8 +1737,6 @@ HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manua
{
HANDLE event;
- MONO_ARCH_SAVE_REGS;
-
*created = TRUE;
if (name == NULL) {
@@ -1774,21 +1754,15 @@ HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manua
}
gboolean ves_icall_System_Threading_Events_SetEvent_internal (HANDLE handle) {
- MONO_ARCH_SAVE_REGS;
-
return (SetEvent(handle));
}
gboolean ves_icall_System_Threading_Events_ResetEvent_internal (HANDLE handle) {
- MONO_ARCH_SAVE_REGS;
-
return (ResetEvent(handle));
}
void
ves_icall_System_Threading_Events_CloseEvent_internal (HANDLE handle) {
- MONO_ARCH_SAVE_REGS;
-
CloseHandle (handle);
}
@@ -1798,8 +1772,6 @@ HANDLE ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name,
{
HANDLE ret;
- MONO_ARCH_SAVE_REGS;
-
*error = ERROR_SUCCESS;
ret = OpenEvent (rights, FALSE, mono_string_chars (name));
@@ -1812,8 +1784,6 @@ HANDLE ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name,
gint32 ves_icall_System_Threading_Interlocked_Increment_Int (gint32 *location)
{
- MONO_ARCH_SAVE_REGS;
-
return InterlockedIncrement (location);
}
@@ -1821,8 +1791,6 @@ gint64 ves_icall_System_Threading_Interlocked_Increment_Long (gint64 *location)
{
gint64 ret;
- MONO_ARCH_SAVE_REGS;
-
mono_interlocked_lock ();
ret = ++ *location;
@@ -1835,8 +1803,6 @@ gint64 ves_icall_System_Threading_Interlocked_Increment_Long (gint64 *location)
gint32 ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 *location)
{
- MONO_ARCH_SAVE_REGS;
-
return InterlockedDecrement(location);
}
@@ -1844,8 +1810,6 @@ gint64 ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
{
gint64 ret;
- MONO_ARCH_SAVE_REGS;
-
mono_interlocked_lock ();
ret = -- *location;
@@ -1857,8 +1821,6 @@ gint64 ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
gint32 ves_icall_System_Threading_Interlocked_Exchange_Int (gint32 *location, gint32 value)
{
- MONO_ARCH_SAVE_REGS;
-
return InterlockedExchange(location, value);
}
@@ -1879,8 +1841,6 @@ gfloat ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat *location,
{
IntFloatUnion val, ret;
- MONO_ARCH_SAVE_REGS;
-
val.fval = value;
ret.ival = InterlockedExchange((gint32 *) location, val.ival);
@@ -1936,8 +1896,6 @@ gfloat ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat *location,
gint32 ves_icall_System_Threading_Interlocked_CompareExchange_Int(gint32 *location, gint32 value, gint32 comparand)
{
- MONO_ARCH_SAVE_REGS;
-
return InterlockedCompareExchange(location, value, comparand);
}
@@ -1958,8 +1916,6 @@ gfloat ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat *lo
{
IntFloatUnion val, ret, cmp;
- MONO_ARCH_SAVE_REGS;
-
val.fval = value;
cmp.fval = comparand;
ret.ival = InterlockedCompareExchange((gint32 *) location, val.ival, cmp.ival);
Commit: 7fae16348a5d801fe8b1a79f534656bf74856a01
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:25 GMT
URL: https://github.com/mono/mono/commit/7fae16348a5d801fe8b1a79f534656bf74856a01
Kill the Cygwin hack in mono-membar.h.
We only support GCC 4.x in Cygwin now.
Changed paths:
M mono/utils/mono-membar.h
Modified: mono/utils/mono-membar.h
===================================================================
@@ -45,34 +45,6 @@ static inline void mono_memory_write_barrier (void)
_WriteBarrier ();
MemoryBarrier ();
}
-#elif defined(__WIN32__) || defined(_WIN32)
-#include <windows.h>
-
-/* Since we only support GCC 3.x in Cygwin for
- some arcane reason, we have to use inline
- assembly to get fences (__sync_synchronize
- is not available). */
-
-static inline void mono_memory_barrier (void)
-{
- __asm__ __volatile__ (
- "lock\n\t"
- "addl\t$0,0(%%esp)\n\t"
- :
- :
- : "memory"
- );
-}
-
-static inline void mono_memory_read_barrier (void)
-{
- mono_memory_barrier ();
-}
-
-static inline void mono_memory_write_barrier (void)
-{
- mono_memory_barrier ();
-}
#elif defined(USE_GCC_ATOMIC_OPS)
static inline void mono_memory_barrier (void)
{
Commit: e601897f3f14145f9ff2d48981f87f8a0c7fef4a
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 13:57:25 GMT
URL: https://github.com/mono/mono/commit/e601897f3f14145f9ff2d48981f87f8a0c7fef4a
Use mono_memory_barrier () for Thread.MemoryBarrier ().
This gets rid of the rather hacky lock-based barrier.
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -2040,8 +2040,7 @@ gfloat ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat *lo
void
ves_icall_System_Threading_Thread_MemoryBarrier (void)
{
- mono_threads_lock ();
- mono_threads_unlock ();
+ mono_memory_barrier ();
}
void
Commit: ec96b2dc2289e00a9c30a8b39b14c3f62ab484ed
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:21 GMT
URL: https://github.com/mono/mono/commit/ec96b2dc2289e00a9c30a8b39b14c3f62ab484ed
Add implementations of various interlocked functions to atomic.c/.h.
Mainly 64-bit variants, but also InterlockedAdd ().
Changed paths:
M mono/utils/atomic.c
M mono/utils/atomic.h
Modified: mono/utils/atomic.c
===================================================================
@@ -82,6 +82,52 @@ gpointer InterlockedCompareExchangePointer(volatile gpointer *dest,
return(old);
}
+gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
+{
+ gint32 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dest += add;
+ ret= *dest;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
+gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+ gint64 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dest += add;
+ ret= *dest;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
gint32 InterlockedIncrement(volatile gint32 *dest)
{
gint32 ret;
@@ -105,6 +151,29 @@ gint32 InterlockedIncrement(volatile gint32 *dest)
return(ret);
}
+gint64 InterlockedIncrement64(volatile gint64 *dest)
+{
+ gint64 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ (*dest)++;
+ ret= *dest;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
gint32 InterlockedDecrement(volatile gint32 *dest)
{
gint32 ret;
@@ -128,6 +197,29 @@ gint32 InterlockedDecrement(volatile gint32 *dest)
return(ret);
}
+gint64 InterlockedDecrement64(volatile gint64 *dest)
+{
+ gint64 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ (*dest)--;
+ ret= *dest;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
{
gint32 ret;
@@ -151,6 +243,29 @@ gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
return(ret);
}
+gint64 InterlockedExchange64(volatile gint64 *dest, gint64 exch)
+{
+ gint64 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret=*dest;
+ *dest=exch;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
{
gpointer ret;
@@ -197,6 +312,29 @@ gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add)
return(ret);
}
+gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
+{
+ gint64 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret= *dest;
+ *dest+=add;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
#define NEED_64BIT_CMPXCHG_FALLBACK
#endif
Modified: mono/utils/atomic.h
===================================================================
@@ -45,6 +45,11 @@ static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest
return __sync_val_compare_and_swap (dest, comp, exch);
}
+static inline gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
+{
+ return __sync_add_and_fetch (dest, add);
+}
+
static inline gint32 InterlockedIncrement(volatile gint32 *val)
{
return __sync_add_and_fetch (val, 1);
@@ -90,8 +95,99 @@ static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64
return __sync_val_compare_and_swap (dest, comp, exch);
}
+static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+ return __sync_add_and_fetch (dest, add);
+}
+
+static inline gint64 InterlockedIncrement64(volatile gint64 *val)
+{
+ return __sync_add_and_fetch (val, 1);
+}
+
+static inline gint64 InterlockedDecrement64(volatile gint64 *val)
+{
+ return __sync_sub_and_fetch (val, 1);
+}
+
+static inline gint64 InterlockedExchangeAdd64(volatile gint64 *val, gint64 add)
+{
+ return __sync_fetch_and_add (val, add);
+}
+
+#else
+
+/* Implement 64-bit cmpxchg by hand or emulate it. */
+extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
+
+/* Implement all other 64-bit atomics in terms of a specialized CAS
+ * in this case, since chances are that the other 64-bit atomic
+ * intrinsics are broken too.
+ */
+
+static inline gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
+{
+ gint64 old_val;
+ do {
+ old_val = *dest;
+ } while (InterlockedCompareExchange64 (dest, old_val + add, old_val) != old_val);
+ return old_val;
+}
+
+static inline gint64 InterlockedIncrement64(volatile gint64 *val)
+{
+ gint64 get, set;
+ do {
+ get = *val;
+ set = get + 1;
+ } while (InterlockedCompareExchange64 (val, set, get) != set);
+ return set;
+}
+
+static inline gint64 InterlockedDecrement64(volatile gint64 *val)
+{
+ gint64 get, set;
+ do {
+ get = *val;
+ set = get - 1;
+ } while (InterlockedCompareExchange64 (val, set, get) != set);
+ return set;
+}
+
+static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+ gint64 get, set;
+ do {
+ get = *dest;
+ set = get + add;
+ } while (InterlockedCompareExchange64 (dest, set, get) != set);
+ return set;
+}
+
+static inline gint64 InterlockedRead64(volatile gint64 *src)
+{
+ return InterlockedCompareExchange64 (src, 0, 0);
+}
+
#endif
+/* We always implement this in terms of a 64-bit cmpxchg since
+ * GCC doesn't have an intrisic to model it anyway. */
+static inline gint64 InterlockedExchange64(volatile gint64 *val, gint64 new_val)
+{
+ gint64 old_val;
+ do {
+ old_val = *val;
+ } while (InterlockedCompareExchange64 (val, new_val, old_val) != old_val);
+ return old_val;
+}
+
+static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
+{
+ /* Nothing useful from GCC at all, so fall back to CAS. */
+ InterlockedExchange64 (dst, val);
+}
+
#elif (defined(sparc) || defined (__sparc__)) && defined(__GNUC__)
G_GNUC_UNUSED
@@ -373,18 +469,19 @@ static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
#define WAPI_NO_ATOMIC_ASM
extern gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp);
+extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
extern gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp);
+extern gint32 InterlockedAdd(volatile gint32 *dest, gint32 add);
+extern gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add);
extern gint32 InterlockedIncrement(volatile gint32 *dest);
+extern gint64 InterlockedIncrement64(volatile gint64 *dest);
extern gint32 InterlockedDecrement(volatile gint32 *dest);
+extern gint64 InterlockedDecrement64(volatile gint64 *dest);
extern gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch);
+extern gint64 InterlockedExchange64(volatile gint64 *dest, gint64 exch);
extern gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch);
extern gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add);
-
-#endif
-
-#if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
-
-extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
+extern gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add);
#endif
Commit: a92cfede81a7d91a699cab0ee325517c2415b6a7
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:25 GMT
URL: https://github.com/mono/mono/commit/a92cfede81a7d91a699cab0ee325517c2415b6a7
Add interlocked read/write functions to atomic.c/.h.
These are guaranteed to have sequential consistency regardless
of the bitness of the machine they run on.
Changed paths:
M mono/utils/atomic.c
M mono/utils/atomic.h
Modified: mono/utils/atomic.c
===================================================================
@@ -335,6 +335,88 @@ gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
return(ret);
}
+gint32 InterlockedRead(volatile gint32 *src)
+{
+ gint32 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret= *src;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
+gint64 InterlockedRead64(volatile gint64 *src)
+{
+ gint64 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret= *src;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
+void InterlockedWrite(volatile gint32 *dst, gint32 val)
+{
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dst=val;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+}
+
+void InterlockedWrite64(volatile gint64 *dst, gint64 val)
+{
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dst=val;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+}
+
#define NEED_64BIT_CMPXCHG_FALLBACK
#endif
Modified: mono/utils/atomic.h
===================================================================
@@ -31,6 +31,30 @@ static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64
}
#endif
+/* And now for some dirty hacks... The Windows API doesn't
+ * provide any useful primitives for this (other than getting
+ * into architecture-specific madness), so use CAS. */
+
+static inline gint32 InterlockedRead(volatile gint32 *src)
+{
+ return InterlockedCompareExchange (src, 0, 0);
+}
+
+static inline gint64 InterlockedRead64(volatile gint64 *src)
+{
+ return InterlockedCompareExchange64 (src, 0, 0);
+}
+
+static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
+{
+ InterlockedExchange (dst, val);
+}
+
+static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
+{
+ InterlockedExchange64 (dst, val);
+}
+
/* Prefer GCC atomic ops if the target supports it (see configure.in). */
#elif defined(USE_GCC_ATOMIC_OPS)
@@ -84,6 +108,19 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
return __sync_fetch_and_add (val, add);
}
+static inline gint32 InterlockedRead(volatile gint32 *src)
+{
+ /* Kind of a hack, but GCC doesn't give us anything better, and it's
+ certainly not as bad as using a CAS loop. */
+ return __sync_fetch_and_add (src, 0);
+}
+
+static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
+{
+ /* Nothing useful from GCC at all, so fall back to CAS. */
+ InterlockedExchange (dst, val);
+}
+
#if defined (TARGET_OSX)
#define BROKEN_64BIT_ATOMICS_INTRINSIC 1
#endif
@@ -115,6 +152,12 @@ static inline gint64 InterlockedExchangeAdd64(volatile gint64 *val, gint64 add)
return __sync_fetch_and_add (val, add);
}
+static inline gint64 InterlockedRead64(volatile gint64 *src)
+{
+ /* Kind of a hack, but GCC doesn't give us anything better. */
+ return __sync_fetch_and_add (src, 0);
+}
+
#else
/* Implement 64-bit cmpxchg by hand or emulate it. */
@@ -482,6 +525,10 @@ static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
extern gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch);
extern gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add);
extern gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add);
+extern gint32 InterlockedRead(volatile gint32 *src);
+extern gint64 InterlockedRead64(volatile gint64 *src);
+extern void InterlockedWrite(volatile gint32 *dst, gint32 val);
+extern void InterlockedWrite64(volatile gint64 *dst, gint64 val);
#endif
Commit: e48f61dc843526bae70b9ff3bd5edae67ce97a77
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:26 GMT
URL: https://github.com/mono/mono/commit/e48f61dc843526bae70b9ff3bd5edae67ce97a77
Move definition of NEED_64BIT_CMPXCHG_FALLBACK to top of atomic.c.
Changed paths:
M mono/utils/atomic.c
Modified: mono/utils/atomic.c
===================================================================
@@ -19,6 +19,8 @@
static pthread_mutex_t spin = PTHREAD_MUTEX_INITIALIZER;
+#define NEED_64BIT_CMPXCHG_FALLBACK
+
#endif
#ifdef WAPI_NO_ATOMIC_ASM
@@ -416,8 +418,6 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
pthread_cleanup_pop (0);
}
-
-#define NEED_64BIT_CMPXCHG_FALLBACK
#endif
@@ -433,8 +433,6 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
#else
-#define NEED_64BIT_CMPXCHG_FALLBACK
-
#endif
#endif
Commit: e02b11b7081a3dcd02d4b6b01e6e0f92d46b7cb6
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:26 GMT
URL: https://github.com/mono/mono/commit/e02b11b7081a3dcd02d4b6b01e6e0f92d46b7cb6
Use __sync_sub_and_fetch () for atomic decrements for clarity.
Changed paths:
M mono/utils/atomic.h
Modified: mono/utils/atomic.h
===================================================================
@@ -81,7 +81,7 @@ static inline gint32 InterlockedIncrement(volatile gint32 *val)
static inline gint32 InterlockedDecrement(volatile gint32 *val)
{
- return __sync_add_and_fetch (val, -1);
+ return __sync_sub_and_fetch (val, 1);
}
static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
Commit: ab90040305d003b6c06c842e788e682495117514
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:27 GMT
URL: https://github.com/mono/mono/commit/ab90040305d003b6c06c842e788e682495117514
Use InterlockedRead64 () for Interlocked.Read (long&).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -2023,18 +2023,7 @@ gfloat ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat *lo
gint64
ves_icall_System_Threading_Interlocked_Read_Long (gint64 *location)
{
-#if SIZEOF_VOID_P == 8
- /* 64 bit reads are already atomic */
- return *location;
-#else
- gint64 res;
-
- mono_interlocked_lock ();
- res = *location;
- mono_interlocked_unlock ();
-
- return res;
-#endif
+ return InterlockedRead64 (location);
}
void
Commit: bb62cced7ef4145ad1feb5c1acdc5c324ce1ec23
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:27 GMT
URL: https://github.com/mono/mono/commit/bb62cced7ef4145ad1feb5c1acdc5c324ce1ec23
Use InterlockedIncrement64 () for Interlocked.Increment (long&).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1789,16 +1789,7 @@ gint32 ves_icall_System_Threading_Interlocked_Increment_Int (gint32 *location)
gint64 ves_icall_System_Threading_Interlocked_Increment_Long (gint64 *location)
{
- gint64 ret;
-
- mono_interlocked_lock ();
-
- ret = ++ *location;
-
- mono_interlocked_unlock ();
-
-
- return ret;
+ return InterlockedIncrement64 (location);
}
gint32 ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 *location)
Commit: 15f9be5d0367b5d5ee168b038878d098ee51d5aa
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:28 GMT
URL: https://github.com/mono/mono/commit/15f9be5d0367b5d5ee168b038878d098ee51d5aa
Use InterlockedDecrement64 () for Interlocked.Decrement (long&).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1799,15 +1799,7 @@ gint32 ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 *location)
gint64 ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
{
- gint64 ret;
-
- mono_interlocked_lock ();
-
- ret = -- *location;
-
- mono_interlocked_unlock ();
-
- return ret;
+ return InterlockedDecrement64 (location);
}
gint32 ves_icall_System_Threading_Interlocked_Exchange_Int (gint32 *location, gint32 value)
Commit: b9db6c2071f2c2cfa36cc32a0150eacdff586376
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:28 GMT
URL: https://github.com/mono/mono/commit/b9db6c2071f2c2cfa36cc32a0150eacdff586376
Use InterlockedExchange64 () for Interlocked.Exchange (long&, long).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1833,22 +1833,7 @@ gfloat ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat *location,
gint64
ves_icall_System_Threading_Interlocked_Exchange_Long (gint64 *location, gint64 value)
{
-#if SIZEOF_VOID_P == 8
- return (gint64) InterlockedExchangePointer((gpointer *) location, (gpointer)value);
-#else
- gint64 res;
-
- /*
- * According to MSDN, this function is only atomic with regards to the
- * other Interlocked functions on 32 bit platforms.
- */
- mono_interlocked_lock ();
- res = *location;
- *location = value;
- mono_interlocked_unlock ();
-
- return res;
-#endif
+ return InterlockedExchange64 (location, value);
}
gdouble
Commit: d785b33891091153ced9e632129badc7262efca9
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:28 GMT
URL: https://github.com/mono/mono/commit/d785b33891091153ced9e632129badc7262efca9
Use InterlockedExchange64 () for Interlocked.Exchange (double&, double).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1839,27 +1839,12 @@ gfloat ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat *location,
gdouble
ves_icall_System_Threading_Interlocked_Exchange_Double (gdouble *location, gdouble value)
{
-#if SIZEOF_VOID_P == 8
LongDoubleUnion val, ret;
val.fval = value;
- ret.ival = (gint64)InterlockedExchangePointer((gpointer *) location, (gpointer)val.ival);
+ ret.ival = (gint64)InterlockedExchange64((gint64 *) location, val.ival);
return ret.fval;
-#else
- gdouble res;
-
- /*
- * According to MSDN, this function is only atomic with regards to the
- * other Interlocked functions on 32 bit platforms.
- */
- mono_interlocked_lock ();
- res = *location;
- *location = value;
- mono_interlocked_unlock ();
-
- return res;
-#endif
}
gint32 ves_icall_System_Threading_Interlocked_CompareExchange_Int(gint32 *location, gint32 value, gint32 comparand)
Commit: 89a99c26341d0c09e30fb263c5a08fe80aa21369
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:29 GMT
URL: https://github.com/mono/mono/commit/89a99c26341d0c09e30fb263c5a08fe80aa21369
Use InterlockedAdd () for Interlocked.Add (int&, int).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1943,14 +1943,7 @@ gfloat ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat *lo
mono_raise_exception (mono_get_exception_not_implemented (NULL));
return 0;
#else
- gint32 orig;
-
- mono_interlocked_lock ();
- orig = *location;
- *location = orig + value;
- mono_interlocked_unlock ();
-
- return orig + value;
+ return InterlockedAdd (location, value);
#endif
}
Commit: 421e1beea55d26d767dbd857e2f2276e3c6c2bee
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:29 GMT
URL: https://github.com/mono/mono/commit/421e1beea55d26d767dbd857e2f2276e3c6c2bee
Use InterlockedAdd64 () for Interlocked.Add (long&, long).
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -1955,14 +1955,7 @@ gfloat ves_icall_System_Threading_Interlocked_CompareExchange_Single (gfloat *lo
mono_raise_exception (mono_get_exception_not_implemented (NULL));
return 0;
#else
- gint64 orig;
-
- mono_interlocked_lock ();
- orig = *location;
- *location = orig + value;
- mono_interlocked_unlock ();
-
- return orig + value;
+ return InterlockedAdd64 (location, value);
#endif
}
Commit: 53398c4641b2dc2f55d577778b13cca8ef223b40
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 15:59:30 GMT
URL: https://github.com/mono/mono/commit/53398c4641b2dc2f55d577778b13cca8ef223b40
Correct our implementation of Thread.VolatileRead ()/VolatileWrite ().
We have various issues:
* All of the functions assumed that doing volatile loads/stores was
enough, when load-acquire, store-release semantics were actually
needed. This may have worked before purely by chance. We now use
proper memory barriers so that we don't have to hope for the
compiler and CPU to do the right thing.
* Removes the hack for 64-bit quantities on 32-bit systems. This is
no longer needed now that we use explicit memory barriers in
these functions. Also, these functions are not supposed to do
atomic reads/writes in the first place - they're purely about the
memory barrier semantics.
* The VolatileWrite (object&, object) overload was not using the
volatile qualifier at all, thus not getting volatile semantics
as per: http://gcc.gnu.org/onlinedocs/gcc/Volatiles.html
Changed paths:
M mono/metadata/threads.c
Modified: mono/metadata/threads.c
===================================================================
@@ -48,6 +48,7 @@
#include <mono/utils/hazard-pointer.h>
#include <mono/utils/mono-tls.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/mono-memory-model.h>
#include <mono/metadata/gc-internal.h>
@@ -2395,114 +2396,120 @@ void mono_thread_stop (MonoThread *thread)
gint8
ves_icall_System_Threading_Thread_VolatileRead1 (void *ptr)
{
- return *((volatile gint8 *) (ptr));
+ gint8 tmp;
+ mono_atomic_load_acquire (tmp, gint8, (volatile gint8 *) ptr);
+ return tmp;
}
gint16
ves_icall_System_Threading_Thread_VolatileRead2 (void *ptr)
{
- return *((volatile gint16 *) (ptr));
+ gint16 tmp;
+ mono_atomic_load_acquire (tmp, gint16, (volatile gint16 *) ptr);
+ return tmp;
}
gint32
ves_icall_System_Threading_Thread_VolatileRead4 (void *ptr)
{
- return *((volatile gint32 *) (ptr));
+ gint32 tmp;
+ mono_atomic_load_acquire (tmp, gint32, (volatile gint32 *) ptr);
+ return tmp;
}
gint64
ves_icall_System_Threading_Thread_VolatileRead8 (void *ptr)
{
-#if SIZEOF_VOID_P == 8
- return *((volatile gint64 *) (ptr));
-#else
- if ((size_t)ptr & 0x7) {
- gint64 value;
- mono_interlocked_lock ();
- value = *(gint64 *)ptr;
- mono_interlocked_unlock ();
- return value;
- }
- return InterlockedCompareExchange64 (ptr, 0, 0); /*Must ensure atomicity of the operation. */
-#endif
+ gint64 tmp;
+ mono_atomic_load_acquire (tmp, gint64, (volatile gint64 *) ptr);
+ return tmp;
}
void *
ves_icall_System_Threading_Thread_VolatileReadIntPtr (void *ptr)
{
- return (void *) *((volatile void **) ptr);
+ volatile void *tmp;
+ mono_atomic_load_acquire (tmp, volatile void *, (volatile void **) ptr);
+ return (void *) tmp;
}
double
ves_icall_System_Threading_Thread_VolatileReadDouble (void *ptr)
{
- return *((volatile double *) (ptr));
+ double tmp;
+ mono_atomic_load_acquire (tmp, double, (volatile double *) ptr);
+ return tmp;
}
float
ves_icall_System_Threading_Thread_VolatileReadFloat (void *ptr)
{
- return *((volatile float *) (ptr));
+ float tmp;
+ mono_atomic_load_acquire (tmp, float, (volatile float *) ptr);
+ return tmp;
}
MonoObject*
ves_icall_System_Threading_Volatile_Read_T (void *ptr)
{
- return (MonoObject*)*((volatile MonoObject**)ptr);
+ volatile MonoObject *tmp;
+ mono_atomic_load_acquire (tmp, volatile MonoObject *, (volatile MonoObject **) ptr);
+ return (MonoObject *) tmp;
}
void
ves_icall_System_Threading_Thread_VolatileWrite1 (void *ptr, gint8 value)
{
- *((volatile gint8 *) ptr) = value;
+ mono_atomic_store_release ((volatile gint8 *) ptr, value);
}
void
ves_icall_System_Threading_Thread_VolatileWrite2 (void *ptr, gint16 value)
{
- *((volatile gint16 *) ptr) = value;
+ mono_atomic_store_release ((volatile gint16 *) ptr, value);
}
void
ves_icall_System_Threading_Thread_VolatileWrite4 (void *ptr, gint32 value)
{
- *((volatile gint32 *) ptr) = value;
+ mono_atomic_store_release ((volatile gint32 *) ptr, value);
}
void
ves_icall_System_Threading_Thread_VolatileWrite8 (void *ptr, gint64 value)
{
- *((volatile gint64 *) ptr) = value;
+ mono_atomic_store_release ((volatile gint64 *) ptr, value);
}
void
ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void *ptr, void *value)
{
- *((volatile void **) ptr) = value;
+ mono_atomic_store_release ((volatile void **) ptr, value);
}
void
ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr, void *value)
{
- mono_gc_wbarrier_generic_store (ptr, value);
+ mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+ mono_gc_wbarrier_generic_nostore (ptr);
}
void
ves_icall_System_Threading_Thread_VolatileWriteDouble (void *ptr, double value)
{
- *((volatile double *) ptr) = value;
+ mono_atomic_store_release ((volatile double *) ptr, value);
}
void
ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr, float value)
{
- *((volatile float *) ptr) = value;
+ mono_atomic_store_release ((volatile float *) ptr, value);
}
void
ves_icall_System_Threading_Volatile_Write_T (void *ptr, MonoObject *value)
{
- *((volatile MonoObject **) ptr) = value;
+ mono_atomic_store_release ((volatile MonoObject **) ptr, value);
mono_gc_wbarrier_generic_nostore (ptr);
}
Commit: 1b9ca03c22742450102f5c9c53eb953365212973
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 16:08:05 GMT
URL: https://github.com/mono/mono/commit/1b9ca03c22742450102f5c9c53eb953365212973
Use slow 64-bit cmpxchg for 32-bit ARM, MIPS, and PowerPC.
GCC doesn't provide a 64-bit __sync_val_compare_and_swap intrinsic
for these architectures.
Changed paths:
M mono/utils/atomic.h
Modified: mono/utils/atomic.h
===================================================================
@@ -121,7 +121,7 @@ static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
InterlockedExchange (dst, val);
}
-#if defined (TARGET_OSX)
+#if defined (TARGET_OSX) || defined (__arm__) || (defined (__mips__) && !defined (__mips64)) || (defined (__powerpc__) && !defined (__powerpc64__))
#define BROKEN_64BIT_ATOMICS_INTRINSIC 1
#endif
Commit: 55d338134d006f070bb533484337e4c9e485be86
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 16:08:15 GMT
URL: https://github.com/mono/mono/commit/55d338134d006f070bb533484337e4c9e485be86
Add an extension point in atomic.c.
Changed paths:
M mono/utils/atomic.c
Modified: mono/utils/atomic.c
===================================================================
@@ -421,7 +421,7 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
#endif
-#if defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
+#if defined (NEED_64BIT_CMPXCHG_FALLBACK)
#if defined (TARGET_OSX)
@@ -431,13 +431,13 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
return __sync_val_compare_and_swap (dest, comp, exch);
}
-#else
-
-#endif
+#elif defined (HAVE_64BIT_CMPXCHG_FALLBACK)
+#ifdef ENABLE_EXTENSION_MODULE
+#include "../../../mono-extensions/mono/utils/atomic.c"
#endif
-#if defined (NEED_64BIT_CMPXCHG_FALLBACK)
+#else
gint64
InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
@@ -455,3 +455,5 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
}
#endif
+
+#endif
Commit: e4d2cc49a03b2cb7b31cddfd630e319bc4d344a1
Author: Alex Rønne Petersen <[email protected]>
Date: 2013-10-21 16:08:16 GMT
URL: https://github.com/mono/mono/commit/e4d2cc49a03b2cb7b31cddfd630e319bc4d344a1
Add mono_gc_wbarrier_generic_store_atomic () function.
This is used in place of mono_gc_wbarrier_generic_store () when
we need the store to be atomic with release semantics.
Changed paths:
M docs/current-api
M docs/public-api
M mono/metadata/boehm-gc.c
M mono/metadata/null-gc.c
M mono/metadata/object.h
M mono/metadata/sgen-gc.c
M mono/metadata/threads.c
M msvc/mono.def
M msvc/monosgen.def
Modified: docs/current-api
===================================================================
@@ -307,6 +307,7 @@ mono_gc_out_of_memory
mono_gc_wbarrier_arrayref_copy
mono_gc_wbarrier_generic_nostore
mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
mono_gc_wbarrier_object_copy
mono_gc_wbarrier_set_arrayref
mono_gc_wbarrier_set_field
Modified: docs/public-api
===================================================================
@@ -307,6 +307,7 @@ mono_gc_out_of_memory
mono_gc_wbarrier_arrayref_copy
mono_gc_wbarrier_generic_nostore
mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
mono_gc_wbarrier_object_copy
mono_gc_wbarrier_set_arrayref
mono_gc_wbarrier_set_field
Modified: mono/metadata/boehm-gc.c
===================================================================
@@ -22,6 +22,7 @@
#include <mono/metadata/marshal.h>
#include <mono/metadata/runtime.h>
#include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-memory-model.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/dtrace.h>
@@ -624,6 +625,12 @@
}
void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+ mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+}
+
+void
mono_gc_wbarrier_generic_nostore (gpointer ptr)
{
}
Modified: mono/metadata/null-gc.c
===================================================================
@@ -193,6 +193,12 @@
}
void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+ mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+}
+
+void
mono_gc_wbarrier_generic_nostore (gpointer ptr)
{
}
Modified: mono/metadata/object.h
===================================================================
@@ -316,6 +316,7 @@
MONO_API void mono_gc_wbarrier_set_arrayref (MonoArray *arr, void* slot_ptr, MonoObject* value);
MONO_API void mono_gc_wbarrier_arrayref_copy (void* dest_ptr, void* src_ptr, int count);
MONO_API void mono_gc_wbarrier_generic_store (void* ptr, MonoObject* value);
+MONO_API void mono_gc_wbarrier_generic_store_atomic (void *ptr, MonoObject *value);
MONO_API void mono_gc_wbarrier_generic_nostore (void* ptr);
MONO_API void mono_gc_wbarrier_value_copy (void* dest, void* src, int count, MonoClass *klass);
MONO_API void mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src);
Modified: mono/metadata/sgen-gc.c
===================================================================
@@ -317,6 +317,7 @@ enum {
static int stat_wbarrier_set_arrayref = 0;
static int stat_wbarrier_arrayref_copy = 0;
static int stat_wbarrier_generic_store = 0;
+static int stat_wbarrier_generic_store_atomic = 0;
static int stat_wbarrier_set_root = 0;
static int stat_wbarrier_value_copy = 0;
static int stat_wbarrier_object_copy = 0;
@@ -2234,6 +2235,7 @@ struct _EphemeronLinkNode {
mono_counters_register ("WBarrier set arrayref", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_set_arrayref);
mono_counters_register ("WBarrier arrayref copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_arrayref_copy);
mono_counters_register ("WBarrier generic store called", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_generic_store);
+ mono_counters_register ("WBarrier generic atomic store called", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_generic_store_atomic);
mono_counters_register ("WBarrier set root", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_set_root);
mono_counters_register ("WBarrier value copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_value_copy);
mono_counters_register ("WBarrier object copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_object_copy);
@@ -4388,6 +4390,24 @@ struct _EphemeronLinkNode {
sgen_dummy_use (value);
}
+/* Same as mono_gc_wbarrier_generic_store () but performs the store
+ * as an atomic operation with release semantics.
+ */
+void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+ HEAVY_STAT (++stat_wbarrier_generic_store_atomic);
+
+ SGEN_LOG (8, "Wbarrier atomic store at %p to %p (%s)", ptr, value, value ? safe_name (value) : "null");
+
+ mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+
+ if (ptr_in_nursery (value))
+ mono_gc_wbarrier_generic_nostore (ptr);
+
+ sgen_dummy_use (value);
+}
+
void mono_gc_wbarrier_value_copy_bitmap (gpointer _dest, gpointer _src, int size, unsigned bitmap)
{
mword *dest = _dest;
Modified: mono/metadata/threads.c
===================================================================
@@ -2490,8 +2490,7 @@ void mono_thread_stop (MonoThread *thread)
void
ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr, void *value)
{
- mono_atomic_store_release ((volatile MonoObject **) ptr, value);
- mono_gc_wbarrier_generic_nostore (ptr);
+ mono_gc_wbarrier_generic_store_atomic (ptr, value);
}
void
@@ -2509,8 +2508,7 @@ void mono_thread_stop (MonoThread *thread)
void
ves_icall_System_Threading_Volatile_Write_T (void *ptr, MonoObject *value)
{
- mono_atomic_store_release ((volatile MonoObject **) ptr, value);
- mono_gc_wbarrier_generic_nostore (ptr);
+ mono_gc_wbarrier_generic_store_atomic (ptr, value);
}
void
Modified: msvc/mono.def
===================================================================
@@ -331,6 +331,7 @@ mono_gc_walk_heap
mono_gc_wbarrier_arrayref_copy
mono_gc_wbarrier_generic_nostore
mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
mono_gc_wbarrier_object_copy
mono_gc_wbarrier_set_arrayref
mono_gc_wbarrier_set_field
Modified: msvc/monosgen.def
===================================================================
@@ -331,6 +331,7 @@ mono_gc_walk_heap
mono_gc_wbarrier_arrayref_copy
mono_gc_wbarrier_generic_nostore
mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
mono_gc_wbarrier_object_copy
mono_gc_wbarrier_set_arrayref
mono_gc_wbarrier_set_field
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches