1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h>
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Simple test program, has a race.  Parent and child both modify y
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   with no locking.  This is the program shown in Fig 2 of the
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   original Eraser paper by Savage et al. */
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint y = 0, v = 0;
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* child_fn ( void* arg )
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* "Thread 2" in the paper */
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_lock( &mu );
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   v = v + 1;
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock( &mu );
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   y = y + 1;
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void )
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const struct timespec delay = { 0, 100 * 1000 * 1000 };
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_t child;
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (pthread_create(&child, NULL, child_fn, NULL)) {
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("pthread_create");
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   nanosleep(&delay, 0);
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* "Thread 1" in the paper */
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   y = y + 1;
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_lock( &mu );
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   v = v + 1;
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock( &mu );
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (pthread_join(child, NULL)) {
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("pthread join");
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
45