ftmemsim-valgrind/drd/tests/atomic_var.c
Bart Van Assche e73284e37f - Added support for most of the ANNOTATE_...() macro's supported by
ThreadSanitizer.                                                              
- Modified DRD's error reporting code such that it does no longer let           
  the Valgrind core print the Valgrind thread ID but that it now prints         
  the DRD thread ID and name. Updated expected output files where               
  necessary.                                                                    
- Modified drd/test/Makefile.am such that the tests using gcc's built-in        
  functions for atomic memory access such that these are only compiled when     
  the gcc version in use supports these built-in functions.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10186
2009-05-31 18:53:54 +00:00

67 lines
1.7 KiB
C

/**
* This test program triggers a single race condition on variable s_y.
* Although another variable (s_x) is also modified by both threads, no race
* condition must be reported on this variable since it is only accessed via
* atomic instructions.
*
* 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 <pthread.h>
#include <stdio.h> /* fprintf() */
#include <stdlib.h> /* atoi() */
#include "../../config.h"
/* Atomic builtins are only supported by gcc 4.1.0 and later. */
#ifndef HAVE_BUILTIN_ATOMIC
#error Sorry, but this test program can only be compiled by a compiler that\
has built-in functions for atomic memory access.
#endif
static __inline__
int sync_add_and_fetch(int* p, int i)
{
return __sync_add_and_fetch(p, i);
}
static int s_x = 0;
/* g_dummy[] ensures that s_x and s_y are not in the same cache line. */
char g_dummy[512];
static int s_y = 0;
static void* thread_func_1(void* arg)
{
s_y = 1;
(void) 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)
{
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");
return 0;
}