/** * 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; }