• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "test.h"
2 #ifndef _UWIN
3 #include <process.h>
4 #endif
5 
6 /*
7  * Create NUMTHREADS threads in addition to the Main thread.
8  */
9 enum {
10   NUMTHREADS = 4
11 };
12 
13 typedef struct bag_t_ bag_t;
14 struct bag_t_ {
15   int threadnum;
16   int started;
17   /* Add more per-thread state variables here */
18   int count;
19   pthread_t self;
20 };
21 
22 static bag_t threadbag[NUMTHREADS + 1];
23 
24 pthread_cond_t CV = PTHREAD_COND_INITIALIZER;
25 pthread_mutex_t CVLock = PTHREAD_MUTEX_INITIALIZER;
26 
27 unsigned int __stdcall
Win32thread(void * arg)28 Win32thread(void * arg)
29 {
30   bag_t * bag = (bag_t *) arg;
31 
32   assert(bag == &threadbag[bag->threadnum]);
33   assert(bag->started == 0);
34   bag->started = 1;
35 
36   assert((bag->self = pthread_self()) != 0);
37   assert(pthread_gethandle (bag->self) != NULL);
38 
39   assert(pthread_kill(bag->self, 0) == 0);
40 
41   assert(pthread_mutex_lock(&CVLock) == 0);
42   pthread_cleanup_push(pthread_mutex_unlock, &CVLock);
43   pthread_cond_wait(&CV, &CVLock);
44   pthread_cleanup_pop(1);
45 
46   return 0;
47 }
48 
49 int
main()50 main()
51 {
52   int failed = 0;
53   int i;
54   HANDLE h[NUMTHREADS + 1];
55   unsigned thrAddr; /* Dummy variable to pass a valid location to _beginthreadex (Win98). */
56 
57   for (i = 1; i <= NUMTHREADS; i++)
58     {
59       threadbag[i].started = 0;
60       threadbag[i].threadnum = i;
61       h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, &thrAddr);
62     }
63 
64   /*
65    * Code to control or munipulate child threads should probably go here.
66    */
67   Sleep(500);
68 
69   /*
70    * Cancel all threads.
71    */
72   for (i = 1; i <= NUMTHREADS; i++)
73     {
74       assert(pthread_kill(threadbag[i].self, 0) == 0);
75       assert(pthread_cancel(threadbag[i].self) == 0);
76     }
77 
78   /*
79    * Give threads time to run.
80    */
81   Sleep(NUMTHREADS * 100);
82 
83   /*
84    * Standard check that all threads started.
85    */
86   for (i = 1; i <= NUMTHREADS; i++)
87     {
88       if (!threadbag[i].started)
89 	{
90 	  failed |= !threadbag[i].started;
91 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
92 	}
93     }
94 
95   assert(!failed);
96 
97   /*
98    * Check any results here. Set "failed" and only print output on failure.
99    */
100   failed = 0;
101   for (i = 1; i <= NUMTHREADS; i++)
102     {
103       int fail = 0;
104       int result = 0;
105 
106       assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE);
107 
108       //assert(threadbag[i].self->h != NULL);
109       assert(pthread_kill(threadbag[i].self, 0) == ESRCH);
110 
111       fail = (result != (int) (size_t) PTHREAD_CANCELED);
112 
113       if (fail)
114 	{
115 	  fprintf(stderr, "Thread %d: started %d: count %d\n",
116 		  i,
117 		  threadbag[i].started,
118 		  threadbag[i].count);
119 	}
120       failed = (failed || fail);
121     }
122 
123   assert(!failed);
124 
125   /*
126    * Success.
127    */
128   return 0;
129 }
130 
131