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
8void alarm_handler ();
9void alarm_handler1 ();
10void alarm_handler2 ();
11void thread1 ();
12void thread2 ();
13
14#define TIME_LIMIT 30
15
16
17int count1 = 0;
18int count2 = 0;
19
20pthread_t tid1, tid2;
21pthread_attr_t attr1, attr2;
22
23pthread_mutex_t mut;
24pthread_mutexattr_t mut_attr;
25
26pthread_condattr_t cv_attr_a, cv_attr_b;
27pthread_cond_t cv_a, cv_b;
28
29struct cv_struct
30  {
31    char a;
32    char b;
33  }
34test_struct;
35
36main ()
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
114void
115thread1 (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
158void
159thread2 (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
203void
204alarm_handler ()
205{
206  printf ("\tcount1 (%d) \n\tcount2 (%d)\n", count1, count2);
207  exit (0);
208}
209
210void
211alarm_handler1 ()
212{
213  printf ("ALARM thread 1\n");
214}
215
216void
217alarm_handler2 ()
218{
219  printf ("ALARM thread 2\n");
220  pthread_exit ((void *) 0);
221}
222