From: Bart Van Assche Date: Thu, 10 Jul 2008 11:58:08 +0000 (+0000) Subject: Added a regression test for atomic variables. X-Git-Tag: svn/VALGRIND_3_4_0~335 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=715ab7a2a1ce91706d9849822d52de92309cb442;p=thirdparty%2Fvalgrind.git Added a regression test for atomic variables. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8412 --- diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am index 1d6715dcb3..fb1bb22ab1 100644 --- a/drd/tests/Makefile.am +++ b/drd/tests/Makefile.am @@ -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 index 0000000000..5e220fafd5 --- /dev/null +++ b/drd/tests/atomic_var.c @@ -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 +#include /* fprintf() */ +#include /* 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 index 0000000000..5dc8dc0001 --- /dev/null +++ b/drd/tests/atomic_var.stderr.exp @@ -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 index 0000000000..0543120760 --- /dev/null +++ b/drd/tests/atomic_var.vgtest @@ -0,0 +1,3 @@ +prereq: ./supported_libpthread +vgopts: --var-info=yes --check-stack-var=yes --show-confl-seg=no +prog: atomic_var