1 /*    step.c for step.exp    */
2 #include <ipc.h>
3 #include <pthread.h>
4 #include <st.h>
5 #include <signal.h>
6 #include <stdio.h>
7 
8 void alarm_handler ();
9 void alarm_handler1 ();
10 void alarm_handler2 ();
11 void thread1 ();
12 void thread2 ();
13 
14 #define TIME_LIMIT 30
15 
16 
17 int count1 = 0;
18 int count2 = 0;
19 
20 pthread_t tid1, tid2;
21 pthread_attr_t attr1, attr2;
22 
23 pthread_mutex_t mut;
24 pthread_mutexattr_t mut_attr;
25 
26 pthread_condattr_t cv_attr_a, cv_attr_b;
27 pthread_cond_t cv_a, cv_b;
28 
29 struct cv_struct
30   {
31     char a;
32     char b;
33   }
34 test_struct;
35 
36 main ()
37 {
38   /*init la struct */
39   test_struct.a = 0;
40   test_struct.b = 1;
41 
42   /* create le mutex */
43   if (pthread_mutexattr_create (&mut_attr) == -1)
44     {
45       perror ("mutexattr_create");
46       exit (1);
47     }
48 
49 
50   if (pthread_mutex_init (&mut, mut_attr) == -1)
51     {
52       perror ("mutex_init");
53       exit (1);
54     }
55 
56   /* create 2 cv */
57   if (pthread_condattr_create (&cv_attr_a) == -1)
58     {
59       perror ("condattr_create(1)");
60       exit (1);
61     }
62 
63   if (pthread_cond_init (&cv_a, cv_attr_a) == -1)
64     {
65       perror ("cond_init(1)");
66       exit (1);
67     }
68 
69   if (pthread_condattr_create (&cv_attr_b) == -1)
70     {
71       perror ("condattr_create(2)");
72       exit (1);
73     }
74 
75   if (pthread_cond_init (&cv_b, cv_attr_b) == -1)
76     {
77       perror ("cond_init(2)");
78       exit (1);
79     }
80 
81   /* create 2 threads of execution */
82   if (pthread_attr_create (&attr1) == -1)
83     {
84       perror ("attr_create(1)");
85       exit (1);
86     }
87 
88   if (pthread_create (&tid1, attr1, thread1, &count1) == -1)
89     {
90       perror ("pthread_create(1)");
91       exit (1);
92     }
93 
94   if (pthread_attr_create (&attr2) == -1)
95     {
96       perror ("attr_create(2)");
97       exit (1);
98     }
99 
100   if (pthread_create (&tid2, attr2, thread2, &count2) == -1)
101     {
102       perror ("pthread_create(2)");
103       exit (1);
104     }
105 
106   /* set alarm to print out data and exit */
107   signal (SIGALRM, alarm_handler);
108   alarm (TIME_LIMIT);
109 
110   for (;;)
111     pause ();
112 }
113 
114 void
115 thread1 (count)
116      int *count;
117 {
118   tid_t tid;
119 
120   tid = getstid ();
121   printf ("Thread1 tid 0x%x  (%d) \n", tid, tid);
122   printf ("Thread1 @tid=0x%x \n", &tid);
123   signal (SIGALRM, alarm_handler1);
124 
125   for (;;)
126     {
127       if (pthread_mutex_lock (&mut) == -1)
128 	{
129 	  perror ("pthread_mutex_lock(1)");
130 	  pthread_exit ((void *) 0);
131 	}
132 
133       while (test_struct.a == 0)
134 	{
135 	  if (pthread_cond_wait (&cv_a, &mut) == -1)
136 	    {
137 	      perror ("pthread_cond_wait(1)");
138 	      pthread_exit ((void *) -1);
139 	    }
140 	}
141 
142       (*count)++;
143       printf ("*******thread1 count %d\n", *count);
144 
145       test_struct.a = 0;
146 
147       test_struct.b = 1;
148       pthread_cond_signal (&cv_b);
149 
150       if (pthread_mutex_unlock (&mut) == -1)
151 	{
152 	  perror ("pthread_mutex_unlock(1)");
153 	  pthread_exit ((void *) -1);
154 	}
155     }
156 }
157 
158 void
159 thread2 (count)
160      int *count;
161 {
162   tid_t tid;
163 
164   tid = getstid ();
165   printf ("Thread2 tid 0x%x  (%d) \n", tid, tid);
166   printf ("Thread1 @tid=0x%x \n", &tid);
167   signal (SIGALRM, alarm_handler2);
168 
169   for (;;)
170     {
171       if (pthread_mutex_lock (&mut) == -1)
172 	{
173 	  perror ("pthread_mutex_lock(2)");
174 	  pthread_exit ((void *) 0);
175 	}
176 
177       while (test_struct.b == 0)
178 	{
179 	  if (pthread_cond_wait (&cv_b, &mut) == -1)
180 	    {
181 	      perror ("pthread_cond_wait(2)");
182 	      pthread_exit ((void *) -1);
183 	    }
184 	}
185 
186       (*count)++;
187       printf ("*******thread2 count %d\n", *count);
188 
189       test_struct.b = 0;
190 
191       test_struct.a = 1;
192       pthread_cond_signal (&cv_a);
193 
194       if (pthread_mutex_unlock (&mut) == -1)
195 	{
196 	  perror ("pthread_mutex_unlock(2)");
197 	  pthread_exit ((void *) -1);
198 	}
199     }
200 }
201 
202 
203 void
204 alarm_handler ()
205 {
206   printf ("\tcount1 (%d) \n\tcount2 (%d)\n", count1, count2);
207   exit (0);
208 }
209 
210 void
211 alarm_handler1 ()
212 {
213   printf ("ALARM thread 1\n");
214 }
215 
216 void
217 alarm_handler2 ()
218 {
219   printf ("ALARM thread 2\n");
220   pthread_exit ((void *) 0);
221 }
222