blob: d45200950f6a990b68e081760f61762cf1157641 [file] [log] [blame]
bart25f9f542009-07-23 16:31:39 +00001/* Use a semaphore to implement mutual exclusion. */
2
3#include <assert.h>
4#include <fcntl.h> /* O_CREAT */
5#include <pthread.h>
6#include <semaphore.h>
7#include <stdio.h> /* printf() */
8#include <stdlib.h> /* exit() */
9#include <unistd.h> /* sleep() */
10
11/* Local functions declarations. */
12
13static void* thread_func(void*);
14
15
16/* Local variables. */
17
18/* s_sem protects s_d3. */
19static sem_t* s_sem;
20
21static 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). */
26static int s_debug = 0;
27static int s_do_printf = 0;
28static int s_do_mutual_exclusion = 0;
29
30
31/* Function definitions. */
32
33int main(int argc, char** argv)
34{
35 int optchar;
36 pthread_t threadid;
37 char semaphore_name[32];
38
39 while ((optchar = getopt(argc, argv, "dmp")) != EOF)
40 {
41 switch (optchar)
42 {
43 case 'd':
44 s_debug = 1;
45 break;
46 case 'm':
47 s_do_mutual_exclusion = 1;
48 break;
49 case 'p':
50 s_do_printf = 1;
51 break;
52 default:
53 assert(0);
54 }
55 }
56
57 /*
58 * Use the ipcs and ipcrm commands to clean up named semaphores left by
59 * aborted instances of this process.
60 */
bart99396662009-07-26 09:16:29 +000061 snprintf(semaphore_name, sizeof(semaphore_name), "drd-sem-open-test");
bart25f9f542009-07-23 16:31:39 +000062 s_sem = sem_open(semaphore_name, O_CREAT, 0600, 1);
63 if (s_sem == SEM_FAILED)
64 {
65 fprintf(stderr, "Failed to create a semaphore with name %s\n",
66 semaphore_name);
67 exit(1);
68 }
69
70 /*
bart31b983d2010-02-21 14:52:59 +000071 * Switch to line-buffered mode, such that timing information can be
bart25f9f542009-07-23 16:31:39 +000072 * obtained for each printf() call with strace.
73 */
74 setlinebuf(stdout);
75
76 if (s_debug)
77 {
78 printf("&s_d1 = %p; &s_d2 = %p; &s_d3 = %p\n", &s_d1, &s_d2, &s_d3);
79 }
80
81 s_d1 = 1;
82 s_d3 = 3;
83
84 pthread_create(&threadid, 0, thread_func, 0);
85
86 sleep(1); /* Wait until thread_func() finished. */
87
88 {
89 if (s_do_mutual_exclusion) sem_wait(s_sem);
90 s_d3++;
91 if (s_do_mutual_exclusion) sem_post(s_sem);
92 }
93
94 /* Wait until the thread finished. */
95 pthread_join(threadid, 0);
96 if (s_do_printf) printf("s_d2 = %g (should be 2)\n", s_d2);
97 if (s_do_printf) printf("s_d3 = %g (should be 5)\n", s_d3);
98
99 sem_close(s_sem);
100 sem_unlink(semaphore_name);
101
102 return 0;
103}
104
105static void* thread_func(void* thread_arg)
106{
107 if (s_do_printf)
108 {
109 printf("s_d1 = %g (should be 1)\n", s_d1);
110 }
111 s_d2 = 2;
112 {
113 if (s_do_mutual_exclusion) sem_wait(s_sem);
114 s_d3++;
115 if (s_do_mutual_exclusion) sem_post(s_sem);
116 }
117 return 0;
118}