1 /* Simple nested-signaling 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
49 ULONG free_memory[192*1024 / sizeof(ULONG)];
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 = (UINT *) 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 = (UINT *) 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 /* Define the signal handlers. */
117
118
pthread_0_signal_handler13(int signo)119 VOID pthread_0_signal_handler13(int signo)
120 {
121
122 /* Check for pthread self call not pthread 0. The signal handler should appear to be
123 called from pthread 0. */
124 if (pthread_self() != pthread_0)
125 {
126
127 /* Call error handler. */
128 error_handler();
129 }
130
131 /* Check for proper signal. */
132 if (signo != 13)
133 {
134
135 /* Call error handler. */
136 error_handler();
137 }
138
139 /* Just increment the signal counter for this test. */
140 pthread_0_signal_counter13++;
141 }
142
143
pthread_0_signal_handler14(int signo)144 VOID pthread_0_signal_handler14(int signo)
145 {
146
147 /* Check for pthread self call not pthread 0. The signal handler should appear to be
148 called from pthread 0. */
149 if (pthread_self() != pthread_0)
150 {
151
152 /* Call error handler. */
153 error_handler();
154 }
155
156 /* Check for proper signal. */
157 if (signo != 14)
158 {
159
160 /* Call error handler. */
161 error_handler();
162 }
163
164 /* Just increment the signal counter for this test. */
165 pthread_0_signal_counter14++;
166
167 /* Raise another signal for nesting test. */
168 pthread_kill(pthread_0, 13);
169 }
170
171
pthread_0_signal_handler15(int signo)172 VOID pthread_0_signal_handler15(int signo)
173 {
174
175 /* Check for pthread self call not pthread 0. The signal handler should appear to be
176 called from pthread 0. */
177 if (pthread_self() != pthread_0)
178 {
179
180 /* Call error handler. */
181 error_handler();
182 }
183
184 /* Check for proper signal. */
185 if (signo != 15)
186 {
187
188 /* Call error handler. */
189 error_handler();
190 }
191
192 /* Just increment the signal counter for this test. */
193 pthread_0_signal_counter15++;
194
195 /* Raise another signal for nesting test. */
196 pthread_kill(pthread_0, 14);
197 }
198
199
200 /* Define the test pthreads */
201 INT pt0_status=0;
202
203
204 /* Self signal test. */
205
pthread_0_entry(VOID * pthread0_input)206 VOID *pthread_0_entry(VOID *pthread0_input)
207 {
208
209 /* Register the signal handlers. */
210 pt0_status = signal(15, pthread_0_signal_handler15);
211
212 /* Check for error. */
213 if (pt0_status)
214 error_handler();
215
216 pt0_status = signal(14, pthread_0_signal_handler14);
217
218 /* Check for error. */
219 if (pt0_status)
220 error_handler();
221
222 pt0_status = signal(13, pthread_0_signal_handler13);
223
224 /* Check for error. */
225 if (pt0_status)
226 error_handler();
227
228
229 /* Get the semaphore with suspension. */
230 pt0_status = sem_wait(sem);
231
232 /* This pthread simply sits in while-forever-sleep loop */
233 while(1)
234 {
235 /* Increment the pthread counter.*/
236 pthread_0_counter++;
237
238 /* Get the semaphore with suspension. */
239 pt0_status = sem_wait(sem);
240
241 /* In this test, this thread should never resume! */
242 error_handler();
243
244 /* Check for error condition. */
245 if (pt0_status)
246 {
247
248 /* Break out of the loop. */
249 break;
250 }
251 }
252
253 return(&pt0_status);
254 }
255
256
257 INT pt1_status=0;
258
pthread_1_entry(VOID * pthread1_input)259 VOID *pthread_1_entry(VOID *pthread1_input)
260 {
261
262
263 /* This thread simply sends a messages to a queue shared by pthread 2. */
264 while(1)
265 {
266
267 /* Increment the thread counter. */
268 pthread_1_counter++;
269
270 /* Raise the first signal for pthread 0. */
271 pt1_status = pthread_kill(pthread_0, 15);
272
273 /* Check for errors. */
274 if ((pt1_status) ||
275 (pthread_0_counter != 1) ||
276 (pthread_1_counter != pthread_0_signal_counter15) ||
277 (pthread_1_counter != pthread_0_signal_counter14) ||
278 (pthread_1_counter != pthread_0_signal_counter13))
279 {
280
281 error_handler();
282 break;
283 }
284 }
285
286 return(&pt1_status);
287 }
288
289