1 /* Simple resume from signal handler test. */
2
3 #include "pthread.h"
4
5 #define DEMO_STACK_SIZE 2048
6 #define DEMO_BYTE_POOL_SIZE 9120
7
8
9 /* Define the POSIX pthread object control blocks ... */
10
11 pthread_t pthread_0;
12 pthread_t pthread_1;
13
14
15 /* Define pthread attributes objects */
16
17
18 pthread_attr_t ptattr0;
19 pthread_attr_t ptattr1;
20
21
22 /* Define a semaphore. */
23
24 sem_t *sem;
25
26
27 /* Define the counters used in this test application... */
28
29 ULONG pthread_0_counter;
30 ULONG pthread_0_signal_counter15;
31 ULONG pthread_0_signal_counter14;
32 ULONG pthread_0_signal_counter13;
33
34 ULONG pthread_1_counter;
35
36
37 /* Define pthread function prototypes. */
38
39 VOID *pthread_0_entry(VOID *);
40 VOID *pthread_1_entry(VOID *);
41
42
43 /* Define signal handlers. */
44
45 VOID pthread_0_signal_handler15(int);
46 VOID pthread_0_signal_handler14(int);
47 VOID pthread_0_signal_handler13(int);
48 ULONG free_memory[192*1024 / sizeof(ULONG)];
49
50 /* Define main entry point. */
51
main()52 INT main()
53 {
54
55 /* Enter the ThreadX kernel. */
56 tx_kernel_enter();
57 }
58
59
60 /* Define what the initial system looks like. */
tx_application_define(VOID * first_unused_memory)61 VOID tx_application_define(VOID *first_unused_memory)
62 {
63
64 VOID* storage_ptr;
65
66
67 struct sched_param param;
68
69
70 /* Init POSIX Wrapper */
71 storage_ptr = (VOID*) posix_initialize((VOID*)free_memory);
72
73 /* Put system definition stuff in here, e.g. pthread creates and other assoerted
74 create information. */
75
76 /* Create pthread attributes. */
77 pthread_attr_init(&ptattr0);
78 pthread_attr_init(&ptattr1);
79
80 /* Create a sched_param structure */
81 memset(¶m, 0, sizeof(param));
82
83 /* Now create all pthreads , firstly modify respective ptheread
84 attribute with desired priority and stack start address and then create the pthread */
85
86 /* Create pthread 0. */
87 param.sched_priority = 15;
88 pthread_attr_setschedparam(&ptattr0, ¶m);
89 pthread_attr_setstackaddr(&ptattr0, storage_ptr );
90 storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE;
91 pthread_create (&pthread_0, &ptattr0,pthread_0_entry,NULL);
92
93
94 /* Create pthread 1. */
95 param.sched_priority = 10;
96 pthread_attr_setschedparam(&ptattr1, ¶m);
97 pthread_attr_setstackaddr(&ptattr1, (VOID*) storage_ptr );
98 storage_ptr = (int *) storage_ptr + DEMO_STACK_SIZE;
99 pthread_create (&pthread_1, &ptattr1,pthread_1_entry,NULL);
100
101
102 /* Create a Semaphore. */
103 sem = sem_open("Sem0", O_CREAT | O_EXCL,0,1);
104 }
105
106
error_handler(void)107 VOID error_handler(void)
108 {
109
110 while(1)
111 {
112 }
113 }
114
115
116
117 /* Define the signal handlers. */
118
119
pthread_0_signal_handler13(int signo)120 VOID pthread_0_signal_handler13(int signo)
121 {
122
123 /* Check for pthread self call not pthread 0. The signal handler should appear to be
124 called from pthread 0. */
125 if (pthread_self() != pthread_0)
126 {
127
128 /* Call error handler. */
129 error_handler();
130 }
131
132 /* Check for proper signal. */
133 if (signo != 13)
134 {
135
136 /* Call error handler. */
137 error_handler();
138 }
139
140 /* Just increment the signal counter for this test. */
141 pthread_0_signal_counter13++;
142
143 /* Release the semaphore, which will wakeup pthread 0. */
144 sem_post(sem);
145 }
146
147
pthread_0_signal_handler14(int signo)148 VOID pthread_0_signal_handler14(int signo)
149 {
150
151 /* Check for pthread self call not pthread 0. The signal handler should appear to be
152 called from pthread 0. */
153 if (pthread_self() != pthread_0)
154 {
155
156 /* Call error handler. */
157 error_handler();
158 }
159
160 /* Check for proper signal. */
161 if (signo != 14)
162 {
163
164 /* Call error handler. */
165 error_handler();
166 }
167
168 /* Just increment the signal counter for this test. */
169 pthread_0_signal_counter14++;
170
171 /* Raise another signal for nesting test. */
172 pthread_kill(pthread_0, 13);
173 }
174
175
pthread_0_signal_handler15(int signo)176 VOID pthread_0_signal_handler15(int signo)
177 {
178
179 /* Check for pthread self call not pthread 0. The signal handler should appear to be
180 called from pthread 0. */
181 if (pthread_self() != pthread_0)
182 {
183
184 /* Call error handler. */
185 error_handler();
186 }
187
188 /* Check for proper signal. */
189 if (signo != 15)
190 {
191
192 /* Call error handler. */
193 error_handler();
194 }
195
196 /* Just increment the signal counter for this test. */
197 pthread_0_signal_counter15++;
198
199 /* Raise another signal for nesting test. */
200 pthread_kill(pthread_0, 14);
201 }
202
203
204 /* Define the test pthreads */
205 INT pt0_status=0;
206
207
208 /* Self signal test. */
209
pthread_0_entry(VOID * pthread0_input)210 VOID *pthread_0_entry(VOID *pthread0_input)
211 {
212
213 /* Register the signal handlers. */
214 pt0_status = signal(15, pthread_0_signal_handler15);
215
216 /* Check for error. */
217 if (pt0_status)
218 error_handler();
219
220 pt0_status = signal(14, pthread_0_signal_handler14);
221
222 /* Check for error. */
223 if (pt0_status)
224 error_handler();
225
226 pt0_status = signal(13, pthread_0_signal_handler13);
227
228 /* Check for error. */
229 if (pt0_status)
230 error_handler();
231
232
233 /* Get the semaphore with suspension. */
234 pt0_status = sem_wait(sem);
235
236 /* This pthread simply sits in while-forever-sleep loop */
237 while(1)
238 {
239 /* Increment the pthread counter.*/
240 pthread_0_counter++;
241
242 /* Get the semaphore with suspension. */
243 pt0_status = sem_wait(sem);
244
245 /* Check for errors. */
246 if ((pt0_status) ||
247 (pthread_0_counter != pthread_0_signal_counter15) ||
248 (pthread_0_counter != pthread_0_signal_counter14) ||
249 (pthread_0_counter != pthread_0_signal_counter13))
250 {
251
252 /* In this test, this thread should never resume! */
253 error_handler();
254
255 /* Break out of the loop. */
256 break;
257 }
258 }
259
260 return(&pt0_status);
261 }
262
263
264 INT pt1_status=0;
265
pthread_1_entry(VOID * pthread1_input)266 VOID *pthread_1_entry(VOID *pthread1_input)
267 {
268
269
270 /* This thread simply sends a messages to a queue shared by pthread 2. */
271 while(1)
272 {
273
274 /* Increment the thread counter. */
275 pthread_1_counter++;
276
277 /* Raise the first signal for pthread 0. */
278 pt1_status = pthread_kill(pthread_0, 15);
279
280 /* Check for errors. */
281 if ((pt1_status) ||
282 (pthread_0_counter != (pthread_1_counter+1)) ||
283 (pthread_1_counter != pthread_0_signal_counter15) ||
284 (pthread_1_counter != pthread_0_signal_counter14) ||
285 (pthread_1_counter != pthread_0_signal_counter13))
286 {
287
288 error_handler();
289 break;
290 }
291 }
292
293 return(&pt1_status);
294 }
295
296