blob: 5a8cb130ba8fa9ec94bc7af75d95586b3e862e5a [file] [log] [blame]
bart55df6e72009-02-16 19:42:17 +00001/* Use a semaphore to implement mutual exclusion. */
sewardj85642922008-01-14 11:54:56 +00002
sewardj85642922008-01-14 11:54:56 +00003
4#include <assert.h>
bart55df6e72009-02-16 19:42:17 +00005#include <stdio.h> /* printf() */
sewardj85642922008-01-14 11:54:56 +00006#include <pthread.h>
7#include <semaphore.h>
bart3ab0baf2009-07-21 11:12:14 +00008#include <unistd.h> /* sleep() */
bart5f57be92008-07-01 08:48:56 +00009
sewardj85642922008-01-14 11:54:56 +000010
bart55df6e72009-02-16 19:42:17 +000011/* Local functions declarations. */
sewardj85642922008-01-14 11:54:56 +000012
13static void* thread_func(void*);
14
sewardj85642922008-01-14 11:54:56 +000015
bart55df6e72009-02-16 19:42:17 +000016/* Local variables. */
17
18/* s_sem protects s_d3. */
sewardj85642922008-01-14 11:54:56 +000019static sem_t s_sem;
20
bart55df6e72009-02-16 19:42:17 +000021static double s_d1; /* accessed before thread creation and in the created */
22 /* thread (not a race). */
23static double s_d2; /* accessed in the created thread and after the join */
24 /* (not a race). */
25static double s_d3; /* accessed simultaneously from both threads (race). */
sewardj85642922008-01-14 11:54:56 +000026static int s_debug = 0;
27static int s_do_printf = 0;
28static int s_do_mutual_exclusion = 0;
29
30
bart55df6e72009-02-16 19:42:17 +000031/* Function definitions. */
sewardj85642922008-01-14 11:54:56 +000032
sewardj85642922008-01-14 11:54:56 +000033int main(int argc, char** argv)
34{
35 int optchar;
36 pthread_t threadid;
37
sewardj85642922008-01-14 11:54:56 +000038 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
bart55df6e72009-02-16 19:42:17 +000058 /*
bart31b983d2010-02-21 14:52:59 +000059 * Switch to line-buffered mode, such that timing information can be
bart55df6e72009-02-16 19:42:17 +000060 * obtained for each printf() call with strace.
61 */
sewardj85642922008-01-14 11:54:56 +000062 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);
sewardj85642922008-01-14 11:54:56 +000073
bart15625cf2009-03-12 17:28:44 +000074 sleep(1); /* Wait until thread_func() finished. */
75
sewardj85642922008-01-14 11:54:56 +000076 {
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
bart55df6e72009-02-16 19:42:17 +000082 /* Wait until the thread finished. */
sewardj85642922008-01-14 11:54:56 +000083 pthread_join(threadid, 0);
sewardj85642922008-01-14 11:54:56 +000084 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
92static void* thread_func(void* thread_arg)
93{
sewardj85642922008-01-14 11:54:56 +000094 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}