瀏覽代碼

Note not to use starpu_cmpxchg/xchg, but STARPU_VAL_COMPARE_AND_SWAP instead

Introduce the 64 bit version, needed for fixing the build on win64,
whose unsigned long is *not* 64bit.
Samuel Thibault 5 年之前
父節點
當前提交
eff0c0f1c5
共有 2 個文件被更改,包括 28 次插入4 次删除
  1. 21 1
      include/starpu_util.h
  2. 7 3
      src/common/knobs.h

+ 21 - 1
include/starpu_util.h

@@ -322,8 +322,13 @@ extern "C"
 			STARPU_ABORT(); }}
 #endif
 
-#if defined(__i386__) || defined(__x86_64__)
+/* Note: do not use starpu_cmpxchg / starpu_xchg / starpu_cmpxchgl /
+ * starpu_xchgl / starpu_cmpxchg64 / starpu_xchg64, which only
+ * assembly-hand-written fallbacks used when building with an old gcc.
+ * Rather use STARPU_VAL_COMPARE_AND_SWAP available on all platforms with a
+ * recent-enough gcc */
 
+#if defined(__i386__) || defined(__x86_64__)
 static __starpu_inline unsigned starpu_cmpxchg(unsigned *ptr, unsigned old, unsigned next)
 {
 	__asm__ __volatile__("lock cmpxchgl %2,%1": "+a" (old), "+m" (*ptr) : "q" (next) : "memory");
@@ -367,6 +372,21 @@ static __starpu_inline unsigned long starpu_xchgl(unsigned long *ptr, unsigned l
 #define STARPU_HAVE_XCHGL
 #endif
 
+#if defined(__x86_64__)
+static __starpu_inline uint64_t starpu_cmpxchg64(uint64_t *ptr, uint64_t old, uint64_t next)
+{
+	__asm__ __volatile__("lock cmpxchgq %2,%1": "+a" (old), "+m" (*ptr) : "q" (next) : "memory");
+	return old;
+}
+static __starpu_inline uint64_t starpu_xchg64(uint64_t *ptr, uint64_t next)
+{
+	/* Note: xchg is always locked already */
+	__asm__ __volatile__("xchgq %1,%0": "+m" (*ptr), "+q" (next) : : "memory");
+	return next;
+}
+#define STARPU_HAVE_XCHG64
+#endif
+
 #endif
 
 #define STARPU_ATOMIC_SOMETHING(name,expr) \

+ 7 - 3
src/common/knobs.h

@@ -43,7 +43,7 @@
 struct starpu_perf_counter_sample;
 struct _starpu_worker;
 
-#ifdef STARPU_HAVE_XCHG
+#if defined(STARPU_HAVE_XCHG) && defined(STARPU_HAVE_XCHG64)
 #define __STARPU_PERF_COUNTER_UPDATE_32BIT(OPNAME,OP,TYPENAME,TYPE) \
 static inline void _starpu_perf_counter_update_##OPNAME##_##TYPENAME(TYPE *ptr, TYPE value) \
 { \
@@ -52,6 +52,7 @@ static inline void _starpu_perf_counter_update_##OPNAME##_##TYPENAME(TYPE *ptr,
 	typedef TYPE __attribute__((__may_alias__)) alias_##TYPE; \
 	while(1) \
 	{ \
+		/* FIXME: rather use STARPU_VAL_COMPARE_AND_SWAP, always available */ \
 		uint32_t raw_old = starpu_xchg((uint32_t *)ptr, *(alias_uint32_t*)&value); \
 		if (value OP *(alias_##TYPE*)&raw_old) \
 			break; \
@@ -67,7 +68,8 @@ static inline void _starpu_perf_counter_update_##OPNAME##_##TYPENAME(TYPE *ptr,
 	typedef TYPE __attribute__((__may_alias__)) alias_##TYPE; \
 	while(1) \
 	{ \
-		uint64_t raw_old = starpu_xchgl((uint64_t *)ptr, *(alias_uint64_t*)&value); \
+		/* FIXME: rather use STARPU_VAL_COMPARE_AND_SWAP, always available */ \
+		uint64_t raw_old = starpu_xchg64((uint64_t *)ptr, *(alias_uint64_t*)&value); \
 		if (value OP *(alias_##TYPE*)&raw_old) \
 			break; \
 		value = *(alias_##TYPE*)&raw_old; \
@@ -99,6 +101,7 @@ static inline void _starpu_perf_counter_update_acc_float(float *ptr, float acc_v
 	while(1)
 	{
 		float value = acc_value + *(alias_float*)&raw_old;
+		/* FIXME: rather use STARPU_VAL_COMPARE_AND_SWAP, always available */
 		raw_old = starpu_xchg((alias_uint32_t *)ptr, *(alias_uint32_t*)&value);
 		if (value == acc_value + *(alias_float*)&raw_old)
 			break;
@@ -113,7 +116,8 @@ static inline void _starpu_perf_counter_update_acc_double(double *ptr, double ac
 	while(1)
 	{
 		double value = acc_value + *(alias_double*)&raw_old;
-		raw_old = starpu_xchgl((alias_uint64_t *)ptr, *(alias_uint64_t*)&value);
+		/* FIXME: rather use STARPU_VAL_COMPARE_AND_SWAP, always available */
+		raw_old = starpu_xchg64((alias_uint64_t *)ptr, *(alias_uint64_t*)&value);
 		if (value == acc_value + *(alias_double*)&raw_old)
 			break;
 	}