]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Added a regression test for atomic variables.
authorBart Van Assche <bvanassche@acm.org>
Thu, 10 Jul 2008 11:58:08 +0000 (11:58 +0000)
committerBart Van Assche <bvanassche@acm.org>
Thu, 10 Jul 2008 11:58:08 +0000 (11:58 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8412

drd/tests/Makefile.am
drd/tests/atomic_var.c [new file with mode: 0644]
drd/tests/atomic_var.stderr.exp [new file with mode: 0644]
drd/tests/atomic_var.vgtest [new file with mode: 0644]

index 1d6715dcb313fc97aedd7e6cd0c9cea7c2a920ef..fb1bb22ab155d0f3a9d99996e8b6ee44b3ee1ab1 100644 (file)
@@ -17,6 +17,8 @@ noinst_SCRIPTS =              \
 
 EXTRA_DIST =                                        \
        $(noinst_SCRIPTS)                           \
+       atomic_var.stderr.exp                       \
+       atomic_var.vgtest                           \
        drd_bitmap_test.stderr.exp                  \
        drd_bitmap_test.stdout.exp                  \
        drd_bitmap_test.vgtest                      \
@@ -182,7 +184,8 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include \
               -I$(top_builddir)/include -I$(top_srcdir)/VEX/pub
 AM_CXXFLAGS = $(AM_CFLAGS)
 
-check_PROGRAMS = \
+check_PROGRAMS =      \
+  atomic_var          \
   drd_bitmap_test     \
   fp_race             \
   hg01_all_ok         \
@@ -244,6 +247,9 @@ check_PROGRAMS += omp_matinv omp_prime
 endif
 
 
+atomic_var_SOURCES          = atomic_var.c
+atomic_var_LDADD            = -lpthread
+
 drd_bitmap_test_SOURCES     = drd_bitmap_test.c
 drd_bitmap_test_CFLAGS      = $(AM_CFLAGS) -O2 \
                               -DENABLE_DRD_CONSISTENCY_CHECKS\
diff --git a/drd/tests/atomic_var.c b/drd/tests/atomic_var.c
new file mode 100644 (file)
index 0000000..5e220fa
--- /dev/null
@@ -0,0 +1,72 @@
+/** Race condition around use of atomic variable.
+ *  Note: for the i386 and x86_64 memory models, thread 2 must print y = 1.
+ *  On PPC however, both y = 0 and y = 1 are legal results. This is because
+ *  the PPC memory model allows different CPU's to observe stores to variables
+ *  in different cache lines in a different order.
+ */
+
+
+#define _GNU_SOURCE
+
+#include "config.h"
+#include <pthread.h>
+#include <stdio.h>   /* fprintf() */
+#include <stdlib.h>  /* atoi() */
+
+
+/** Only gcc 4.1.0 and later have atomic builtins. */
+#ifndef HAVE_BUILTIN_ATOMIC
+static __inline__
+int __sync_add_and_fetch(int* p, int i)
+{
+  if (i == 0)
+    return *p;
+  return (*p += i);
+}
+#endif
+
+
+static int s_x = 0;
+/* s_dummy[] ensures that s_x and s_y are not in the same cache line. */
+static char s_dummy[512];
+static int s_y = 0;
+
+static void* thread_func_1(void* arg)
+{
+  s_y = 1;
+  __sync_add_and_fetch(&s_x, 1);
+  return 0;
+}
+
+static void* thread_func_2(void* arg)
+{
+  while (__sync_add_and_fetch(&s_x, 0) == 0)
+    ;
+  fprintf(stderr, "y = %d\n", s_y);
+  return 0;
+}
+
+int main(int argc, char** argv)
+{
+#ifdef HAVE_BUILTIN_ATOMIC
+  int i;
+  const int n_threads = 2;
+  pthread_t tid[n_threads];
+
+  fprintf(stderr, "Start of test.\n");
+  pthread_create(&tid[0], 0, thread_func_1, 0);
+  pthread_create(&tid[1], 0, thread_func_2, 0);
+  for (i = 0; i < n_threads; i++)
+    pthread_join(tid[i], 0);
+  fprintf(stderr, "Test finished.\n");
+#else
+  fprintf(stderr,
+          "Sorry, but your compiler does not have built-in support for atomic"
+          " operations.\n");
+#endif
+
+  /* Suppress the compiler warning about s_dummy not being used. */
+  s_dummy[0]++;
+
+  return 0;
+}
diff --git a/drd/tests/atomic_var.stderr.exp b/drd/tests/atomic_var.stderr.exp
new file mode 100644 (file)
index 0000000..5dc8dc0
--- /dev/null
@@ -0,0 +1,14 @@
+
+Start of test.
+Thread 2:
+Conflicting load by thread 2/3 at 0x........ size 4
+   at 0x........: thread_func_2 (atomic_var.c:?)
+   by 0x........: vg_thread_wrapper (drd_pthread_intercepts.c:?)
+   by 0x........: (within libpthread-?.?.so)
+   by 0x........: clone (in /...libc...)
+Location 0x........ is 0 bytes inside local var "s_y"
+declared at atomic_var.c:30, in frame #? of thread 2
+y = 1
+Test finished.
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
diff --git a/drd/tests/atomic_var.vgtest b/drd/tests/atomic_var.vgtest
new file mode 100644 (file)
index 0000000..0543120
--- /dev/null
@@ -0,0 +1,3 @@
+prereq: ./supported_libpthread
+vgopts: --var-info=yes --check-stack-var=yes --show-confl-seg=no
+prog: atomic_var