• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "test.h"
2 #include <sys/timeb.h>
3 
4 /*
5  * Create NUMTHREADS threads in addition to the Main thread.
6  */
7 enum {
8   NUMTHREADS = 5
9 };
10 
11 typedef struct bag_t_ bag_t;
12 struct bag_t_ {
13   int threadnum;
14   int started;
15   /* Add more per-thread state variables here */
16 };
17 
18 static bag_t threadbag[NUMTHREADS + 1];
19 
20 typedef struct cvthing_t_ cvthing_t;
21 
22 struct cvthing_t_ {
23   pthread_cond_t notbusy;
24   pthread_mutex_t lock;
25   int shared;
26 };
27 
28 static cvthing_t cvthing = {
29   PTHREAD_COND_INITIALIZER,
30   PTHREAD_MUTEX_INITIALIZER,
31   0
32 };
33 
34 static pthread_mutex_t start_flag = PTHREAD_MUTEX_INITIALIZER;
35 
36 static struct timespec abstime = { 0, 0 };
37 
38 static int awoken;
39 
40 void *
mythread(void * arg)41 mythread(void * arg)
42 {
43   bag_t * bag = (bag_t *) arg;
44 
45   assert(bag == &threadbag[bag->threadnum]);
46   assert(bag->started == 0);
47   bag->started = 1;
48 
49   /* Wait for the start gun */
50   assert(pthread_mutex_lock(&start_flag) == 0);
51   assert(pthread_mutex_unlock(&start_flag) == 0);
52 
53   assert(pthread_mutex_lock(&cvthing.lock) == 0);
54 
55   while (! (cvthing.shared > 0))
56     assert(pthread_cond_timedwait(&cvthing.notbusy, &cvthing.lock, &abstime) == 0);
57 
58   assert(cvthing.shared > 0);
59 
60   awoken++;
61 
62   assert(pthread_mutex_unlock(&cvthing.lock) == 0);
63 
64   return (void *) 0;
65 }
66 
67 int
main()68 main()
69 {
70   int failed = 0;
71   int i;
72   pthread_t t[NUMTHREADS + 1];
73 
74   struct _timeb currSysTime;
75   const DWORD NANOSEC_PER_MILLISEC = 1000000;
76 
77   cvthing.shared = 0;
78 
79   assert((t[0] = pthread_self()) != 0);
80   assert(pthread_gethandle (t[0]) != NULL);
81 
82   assert(cvthing.notbusy == PTHREAD_COND_INITIALIZER);
83 
84   assert(cvthing.lock == PTHREAD_MUTEX_INITIALIZER);
85 
86   assert(pthread_mutex_lock(&start_flag) == 0);
87 
88   _ftime(&currSysTime);
89 
90   abstime.tv_sec = currSysTime.time;
91   abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
92 
93   abstime.tv_sec += 5;
94 
95   assert((t[0] = pthread_self()) != 0);
96   assert(pthread_gethandle (t[0]) != NULL);
97 
98   awoken = 0;
99 
100   for (i = 1; i <= NUMTHREADS; i++)
101     {
102       threadbag[i].started = 0;
103       threadbag[i].threadnum = i;
104       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
105     }
106 
107   /*
108    * Code to control or munipulate child threads should probably go here.
109    */
110 
111   assert(pthread_mutex_unlock(&start_flag) == 0);
112 
113   /*
114    * Give threads time to start.
115    */
116   Sleep(1000);
117 
118   assert(pthread_mutex_lock(&cvthing.lock) == 0);
119   cvthing.shared++;
120   assert(pthread_mutex_unlock(&cvthing.lock) == 0);
121 
122   assert(pthread_cond_broadcast(&cvthing.notbusy) == 0);
123 
124   /*
125    * Give threads time to complete.
126    */
127   for (i = 1; i <= NUMTHREADS; i++)
128     {
129       assert(pthread_join(t[i], NULL) == 0);
130     }
131 
132   /*
133    * Cleanup the CV.
134    */
135 
136   assert(pthread_mutex_destroy(&cvthing.lock) == 0);
137 
138   assert(cvthing.lock == NULL);
139 
140   assert(pthread_cond_destroy(&cvthing.notbusy) == 0);
141 
142   assert(cvthing.notbusy == NULL);
143 
144   /*
145    * Standard check that all threads started.
146    */
147   for (i = 1; i <= NUMTHREADS; i++)
148     {
149       failed = !threadbag[i].started;
150 
151       if (failed)
152 	{
153 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
154 	}
155     }
156 
157   assert(!failed);
158 
159   /*
160    * Check any results here.
161    */
162 
163   assert(awoken == NUMTHREADS);
164 
165   /*
166    * Success.
167    */
168   return 0;
169 }
170 
171 
172