blob: e0b40a7a134bc1613f2fe2d6aa9358ba6d863bad [file] [log] [blame]
sewardj347eeba2008-01-21 14:19:07 +00001/* Test whether all data races are detected in a multithreaded program with
2 * barriers.
3 */
4
5
6#define _GNU_SOURCE
7
8/***********************/
9/* Include directives. */
10/***********************/
11
12#include <assert.h>
13#include <pthread.h>
14#include <stdio.h>
15#include <stdlib.h>
16
17
18/*********************/
19/* Type definitions. */
20/*********************/
21
22struct threadinfo
23{
24 pthread_barrier_t* b;
25 pthread_t tid;
26 int* array;
27 int iterations;
28};
29
30
31/********************/
32/* Local variables. */
33/********************/
34
35static int s_silent;
36
37
38/*************************/
39/* Function definitions. */
40/*************************/
41
bart546b7712008-02-24 18:18:23 +000042/** Single thread, which touches p->iterations elements of array p->array.
43 * Each modification of an element of p->array is a data race. */
sewardj347eeba2008-01-21 14:19:07 +000044static void* threadfunc(struct threadinfo* p)
45{
46 int i;
47 int* const array = p->array;
48 pthread_barrier_t* const b = p->b;
49 if (! s_silent)
50 printf("thread %lx iteration 0\n", pthread_self());
51 pthread_barrier_wait(b);
52 for (i = 0; i < p->iterations; i++)
53 {
54 if (! s_silent)
55 printf("thread %lx iteration %d; writing to %p\n",
56 pthread_self(), i + 1, &array[i]);
57 array[i] = i;
58 pthread_barrier_wait(b);
59 }
60 return 0;
61}
62
bart546b7712008-02-24 18:18:23 +000063/** Actual test, consisting of nthread threads. */
sewardj347eeba2008-01-21 14:19:07 +000064static void barriers_and_races(const int nthread, const int iterations)
65{
66 int i;
67 struct threadinfo* t;
68 pthread_barrier_t b;
69 int* array;
70
71 t = malloc(nthread * sizeof(struct threadinfo));
72 array = malloc(iterations * sizeof(array[0]));
73
bart546b7712008-02-24 18:18:23 +000074 if (! s_silent)
75 printf("&array[0] = %p\n", array);
76
sewardj347eeba2008-01-21 14:19:07 +000077 pthread_barrier_init(&b, 0, nthread);
78
79 for (i = 0; i < nthread; i++)
80 {
81 t[i].b = &b;
82 t[i].array = array;
83 t[i].iterations = iterations;
84 pthread_create(&t[i].tid, 0, (void*(*)(void*))threadfunc, &t[i]);
85 }
86
87 for (i = 0; i < nthread; i++)
88 {
89 pthread_join(t[i].tid, 0);
90 }
91
92 pthread_barrier_destroy(&b);
93
94 free(array);
95 free(t);
96}
97
98int main(int argc, char** argv)
99{
100 int nthread;
101 int iterations;
102
bart546b7712008-02-24 18:18:23 +0000103 nthread = (argc > 1) ? atoi(argv[1]) : 2;
sewardj347eeba2008-01-21 14:19:07 +0000104 iterations = (argc > 2) ? atoi(argv[2]) : 3;
bart546b7712008-02-24 18:18:23 +0000105 s_silent = (argc > 3) ? atoi(argv[3]) : 0;
sewardj347eeba2008-01-21 14:19:07 +0000106
107 barriers_and_races(nthread, iterations);
108
109 return 0;
110}