1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h>
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Simple demonstration of lockset tracking at byte granularity. */
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar bytes[10];
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* child_fn ( void* arg )
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int i;
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 5; i++)
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bytes[2*i + 0] ++; /* child accesses: 0 2 4 6 8 */
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void )
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   const struct timespec delay = { 0, 100 * 1000 * 1000 };
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int i;
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_t child;
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (pthread_create(&child, NULL, child_fn, NULL)) {
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("pthread_create");
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   nanosleep(&delay, 0);
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Unprotected relative to child, but harmless, since different
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bytes accessed */
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 5; i++)
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bytes[2*i + 1] ++; /* accesses: 1 3 5 7 9 */
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Unprotected relative to child, but harmful; same bytes */
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 3; i++)
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bytes[3*i + 1] ++; /* accesses: 1 4(race!) 7 */
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (pthread_join(child, NULL)) {
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("pthread join");
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
43