1
2#include <pthread.h>
3#include <stdio.h>
4#include <stdlib.h>
5
6/* Simple test program, no race: parent only modifies x after child
7   has modified it and then joined with the parent.  Tests simple
8   thread lifetime segment handling. */
9
10/* A simple function to "use" a value, so that gcc can't
11   possibly optimise it into nothing. */
12static void use ( int x ) {
13   __asm__ __volatile__( "" : : "r"(x) : "cc","memory" );
14}
15
16static void* worker_thread ( void* argV )
17{
18  int* arg = (int*)argV;
19  use(arg[5]); /* read access */
20  return NULL;
21}
22
23int main ( void )
24{
25   pthread_t thread_id;
26   volatile int* x = malloc(10 * sizeof(int));
27   x[5] = 1;
28   /* x[5] is Excl(parent) */
29
30   pthread_create(&thread_id, 0, worker_thread, (void*)x);
31
32   use(x[5]); /* read access */
33
34   /* Just before the threads join, x[5] is ShR (read by both parent
35      and child) */
36   pthread_join(thread_id, 0);
37   /* x[5] is Excl(parent), because only parent and child accessed it
38      and child has merged to parent.  So now it's ok for parent to
39      access it without locking. */
40
41   x[5] = 0; /* write access */
42
43   return x[5];
44}
45