|
From: <sv...@va...> - 2007-09-27 19:09:05
|
Author: sewardj
Date: 2007-09-27 20:09:01 +0100 (Thu, 27 Sep 2007)
New Revision: 6924
Log:
Add a test for correct handling of XCHG on x86/amd64.
Added:
branches/THRCHECK/thrcheck/tests/tc11_XCHG.c
branches/THRCHECK/thrcheck/tests/tc11_XCHG.stderr.exp
branches/THRCHECK/thrcheck/tests/tc11_XCHG.stdout.exp
Modified:
branches/THRCHECK/thrcheck/tests/Makefile.am
Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am 2007-09-27 08:06:03 UTC (rev 6923)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am 2007-09-27 19:09:01 UTC (rev 6924)
@@ -30,7 +30,9 @@
tc09_bad_unlock.vgtest tc09_bad_unlock.stderr.exp \
tc09_bad_unlock.stdout.exp \
tc10_rec_lock.vgtest tc10_rec_lock.stderr.exp \
- tc10_rec_lock.stdout.exp
+ tc10_rec_lock.stdout.exp \
+ tc11_XCHG.vgtest tc11_XCHG.stderr.exp \
+ tc11_XCHG.stdout.exp
check_PROGRAMS = \
hg01_all_ok \
@@ -48,7 +50,8 @@
tc07_hbl1 \
tc08_hbl2 \
tc09_bad_unlock \
- tc10_rec_lock
+ tc10_rec_lock \
+ tc11_XCHG
# is this necessary?
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI)
Added: branches/THRCHECK/thrcheck/tests/tc11_XCHG.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc11_XCHG.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc11_XCHG.c 2007-09-27 19:09:01 UTC (rev 6924)
@@ -0,0 +1,86 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+/* Simple test program, no race. Parent and child both modify x and
+ use the hardware bus lock (implicitly, since XCHG r,m on x86/amd64
+ does not require an explicit LOCK prefix.). */
+
+#undef PLAT_x86_linux
+#undef PLAT_amd64_linux
+#undef PLAT_ppc32_linux
+#undef PLAT_ppc64_linux
+#undef PLAT_ppc32_aix5
+#undef PLAT_ppc64_aix5
+
+#if !defined(_AIX) && defined(__i386__)
+# define PLAT_x86_linux 1
+#elif !defined(_AIX) && defined(__x86_64__)
+# define PLAT_amd64_linux 1
+#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+# define PLAT_ppc32_linux 1
+#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+# define PLAT_ppc64_linux 1
+#elif defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#endif
+
+
+#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux)
+# define XCHG_M_R(_addr,_lval) \
+ __asm__ __volatile__( \
+ "xchgl %0, %1" \
+ : /*out*/ "+r"(_lval) \
+ : /*in*/ "m"(_addr) \
+ : "memory", "cc" \
+ )
+# define XCHG_M_R_with_redundant_LOCK(_addr,_lval) \
+ __asm__ __volatile__( \
+ "lock xchgl %0, %1" \
+ : /*out*/ "+r"(_lval) \
+ : /*in*/ "m"(_addr) \
+ : "memory", "cc" \
+ )
+#else
+# error "Fix Me for this platform"
+#endif
+
+int x = 0;
+
+void* child_fn ( void* arg )
+{
+ int v = 12345;
+ XCHG_M_R_with_redundant_LOCK(x, v);
+ assert(v == 0 || v == 6789);
+ return NULL;
+}
+
+int main ( void )
+{
+ int v = 6789;
+ pthread_t child;
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ XCHG_M_R(x, v);
+ assert(v == 0 || v == 12345);
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ if (v == 0 || v == 12345)
+ printf("success\n");
+ else
+ printf("failure\n");
+
+ return v;
+}
Added: branches/THRCHECK/thrcheck/tests/tc11_XCHG.stderr.exp
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc11_XCHG.stderr.exp (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc11_XCHG.stderr.exp 2007-09-27 19:09:01 UTC (rev 6924)
@@ -0,0 +1,3 @@
+
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Added: branches/THRCHECK/thrcheck/tests/tc11_XCHG.stdout.exp
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc11_XCHG.stdout.exp (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc11_XCHG.stdout.exp 2007-09-27 19:09:01 UTC (rev 6924)
@@ -0,0 +1 @@
+success
|