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 \
-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 \
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\
--- /dev/null
+/** 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;
+}
--- /dev/null
+
+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)