blob: 40f15669e3d9d6b929c18e9cd2372330017fb682 [file] [log] [blame]
bart48529bc2009-02-15 10:19:35 +00001/**
2 * This test program triggers a single race condition on variable s_y.
3 * Although another variable (s_x) is also modified by both threads, no race
4 * condition must be reported on this variable since it is only accessed via
5 * atomic instructions.
6 *
7 * Note: for the i386 and x86_64 memory models, thread 2 must print y = 1.
8 * On PPC however, both y = 0 and y = 1 are legal results. This is because
9 * the PPC memory model allows different CPU's to observe stores to variables
10 * in different cache lines in a different order.
bartcca440b2008-07-10 11:58:08 +000011 */
12
bartcca440b2008-07-10 11:58:08 +000013#define _GNU_SOURCE
14
bartcca440b2008-07-10 11:58:08 +000015#include <pthread.h>
16#include <stdio.h> /* fprintf() */
17#include <stdlib.h> /* atoi() */
bartd22e8b22008-12-21 16:10:36 +000018#include "../../config.h"
bartcca440b2008-07-10 11:58:08 +000019
bart48529bc2009-02-15 10:19:35 +000020/* Atomic builtins are only supported by gcc 4.1.0 and later. */
bartd45d9952009-05-31 18:53:54 +000021#ifndef HAVE_BUILTIN_ATOMIC
22#error Sorry, but this test program can only be compiled by a compiler that\
23has built-in functions for atomic memory access.
24#endif
bart48529bc2009-02-15 10:19:35 +000025
bartcca440b2008-07-10 11:58:08 +000026static __inline__
bart143eec72008-09-21 11:21:23 +000027int sync_add_and_fetch(int* p, int i)
28{
29 return __sync_add_and_fetch(p, i);
30}
bartcca440b2008-07-10 11:58:08 +000031
bartcca440b2008-07-10 11:58:08 +000032static int s_x = 0;
bart48529bc2009-02-15 10:19:35 +000033/* g_dummy[] ensures that s_x and s_y are not in the same cache line. */
34char g_dummy[512];
bartcca440b2008-07-10 11:58:08 +000035static int s_y = 0;
36
37static void* thread_func_1(void* arg)
38{
39 s_y = 1;
bart143eec72008-09-21 11:21:23 +000040 (void) sync_add_and_fetch(&s_x, 1);
bartcca440b2008-07-10 11:58:08 +000041 return 0;
42}
43
44static void* thread_func_2(void* arg)
45{
bart143eec72008-09-21 11:21:23 +000046 while (sync_add_and_fetch(&s_x, 0) == 0)
bartcca440b2008-07-10 11:58:08 +000047 ;
48 fprintf(stderr, "y = %d\n", s_y);
49 return 0;
50}
51
52int main(int argc, char** argv)
53{
bartcca440b2008-07-10 11:58:08 +000054 int i;
55 const int n_threads = 2;
56 pthread_t tid[n_threads];
57
58 fprintf(stderr, "Start of test.\n");
59 pthread_create(&tid[0], 0, thread_func_1, 0);
60 pthread_create(&tid[1], 0, thread_func_2, 0);
61 for (i = 0; i < n_threads; i++)
62 pthread_join(tid[i], 0);
63 fprintf(stderr, "Test finished.\n");
bart0d84eab2008-09-09 18:11:40 +000064
bart48529bc2009-02-15 10:19:35 +000065 return 0;
66}