• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Use a semaphore to implement mutual exclusion. */
2 
3 
4 #include <assert.h>
5 #include <stdio.h>     /* printf() */
6 #include <pthread.h>
7 #include <semaphore.h>
8 #include <unistd.h>    /* sleep() */
9 
10 
11 /* Local functions declarations. */
12 
13 static void* thread_func(void*);
14 
15 
16 /* Local variables. */
17 
18 /* s_sem protects s_d3. */
19 static sem_t s_sem;
20 
21 static double s_d1; /* accessed before thread creation and in the created */
22                     /* thread (not a race). */
23 static double s_d2; /* accessed in the created thread and after the join */
24                     /* (not a race). */
25 static double s_d3; /* accessed simultaneously from both threads (race). */
26 static int    s_debug     = 0;
27 static int    s_do_printf = 0;
28 static int    s_do_mutual_exclusion = 0;
29 
30 
31 /* Function definitions. */
32 
main(int argc,char ** argv)33 int main(int argc, char** argv)
34 {
35   int optchar;
36   pthread_t threadid;
37 
38   while ((optchar = getopt(argc, argv, "dmp")) != EOF)
39   {
40     switch (optchar)
41     {
42     case 'd':
43       s_debug = 1;
44       break;
45     case 'm':
46       s_do_mutual_exclusion = 1;
47       break;
48     case 'p':
49       s_do_printf = 1;
50       break;
51     default:
52       assert(0);
53     }
54   }
55 
56   sem_init(&s_sem, 0, 1);
57 
58   /*
59    * Switch to line-buffered mode, such that timing information can be
60    * obtained for each printf() call with strace.
61    */
62   setlinebuf(stdout);
63 
64   if (s_debug)
65   {
66     printf("&s_d1 = %p; &s_d2 = %p; &s_d3 = %p\n", &s_d1, &s_d2, &s_d3);
67   }
68 
69   s_d1 = 1;
70   s_d3 = 3;
71 
72   pthread_create(&threadid, 0, thread_func, 0);
73 
74   sleep(1); /* Wait until thread_func() finished. */
75 
76   {
77     if (s_do_mutual_exclusion) sem_wait(&s_sem);
78     s_d3++;
79     if (s_do_mutual_exclusion) sem_post(&s_sem);
80   }
81 
82   /* Wait until the thread finished. */
83   pthread_join(threadid, 0);
84   if (s_do_printf) printf("s_d2 = %g (should be 2)\n", s_d2);
85   if (s_do_printf) printf("s_d3 = %g (should be 5)\n", s_d3);
86 
87   sem_destroy(&s_sem);
88 
89   return 0;
90 }
91 
thread_func(void * thread_arg)92 static void* thread_func(void* thread_arg)
93 {
94   if (s_do_printf)
95   {
96     printf("s_d1 = %g (should be 1)\n", s_d1);
97   }
98   s_d2 = 2;
99   {
100     if (s_do_mutual_exclusion) sem_wait(&s_sem);
101     s_d3++;
102     if (s_do_mutual_exclusion) sem_post(&s_sem);
103   }
104   return 0;
105 }
106