1 /* This test is designed to see if multiple threads can be created and suspended.
2    The order the suspension and resumption occurs makes sure everything is working right.
3    All the counters should increment at the same rate.  This test differs from test 4 in
4    that thread 5 is preemptable.  */
5 
6 #include   <stdio.h>
7 #include   "tx_api.h"
8 
9 static unsigned long   thread_0_counter = 0;
10 static TX_THREAD       thread_0;
11 
12 static unsigned long   thread_1_counter = 0;
13 static TX_THREAD       thread_1;
14 
15 static unsigned long   thread_2_counter = 0;
16 static TX_THREAD       thread_2;
17 
18 static unsigned long   thread_3_counter = 0;
19 static TX_THREAD       thread_3;
20 
21 static unsigned long   thread_4_counter = 0;
22 static TX_THREAD       thread_4;
23 
24 static unsigned long   thread_5_counter = 0;
25 static TX_THREAD       thread_5;
26 
27 
28 /* Define thread prototypes.  */
29 
30 static void    thread_0_entry(ULONG thread_input);
31 static void    thread_1_entry(ULONG thread_input);
32 static void    thread_2_entry(ULONG thread_input);
33 static void    thread_3_entry(ULONG thread_input);
34 static void    thread_4_entry(ULONG thread_input);
35 static void    thread_5_entry(ULONG thread_input);
36 
37 
38 /* Prototype for test control return.  */
39 void  test_control_return(UINT status);
40 
41 
42 /* Define what the initial system looks like.  */
43 
44 #ifdef CTEST
test_application_define(void * first_unused_memory)45 void test_application_define(void *first_unused_memory)
46 #else
47 void    threadx_thread_preemptable_suspension_application_define(void *first_unused_memory)
48 #endif
49 {
50 
51 UINT    status;
52 CHAR    *pointer;
53 
54     /* Put first available memory address into a character pointer.  */
55     pointer =  (CHAR *) first_unused_memory;
56 
57     /* Put system definition stuff in here, e.g. thread creates and other assorted
58        create information.  */
59 
60     /* Create thread 0.  */
61     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
62             pointer, TEST_STACK_SIZE_PRINTF,
63             13, 13, TX_NO_TIME_SLICE, TX_AUTO_START);
64     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
65 
66     /* Check for status.  */
67     if (status != TX_SUCCESS)
68     {
69 
70         printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #1\n");
71         test_control_return(1);
72     }
73 
74     /* Create thread 1.  */
75     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
76             pointer, TEST_STACK_SIZE_PRINTF,
77             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
78     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
79 
80     /* Check for status.  */
81     if (status != TX_SUCCESS)
82     {
83 
84         printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #2\n");
85         test_control_return(1);
86     }
87 
88     /* Create thread 2.  */
89     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
90             pointer, TEST_STACK_SIZE_PRINTF,
91             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
92     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
93 
94     /* Check for status.  */
95     if (status != TX_SUCCESS)
96     {
97 
98         printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #3\n");
99         test_control_return(1);
100     }
101 
102     /* Create thread 3.  */
103     status =  tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
104             pointer, TEST_STACK_SIZE_PRINTF,
105             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
106     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
107 
108     /* Check for status.  */
109     if (status != TX_SUCCESS)
110     {
111 
112         printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #4\n");
113         test_control_return(1);
114     }
115 
116     /* Create thread 4.  */
117     status =  tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
118             pointer, TEST_STACK_SIZE_PRINTF,
119             15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
120     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
121 
122     /* Check for status.  */
123     if (status != TX_SUCCESS)
124     {
125 
126         printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #5\n");
127         test_control_return(1);
128     }
129 
130     /* Create thread 5.  Make this thread fully preemptable...  */
131     status =  tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1,
132             pointer, TEST_STACK_SIZE_PRINTF,
133             17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
134     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
135 
136     /* Check for status.  */
137     if (status != TX_SUCCESS)
138     {
139 
140         printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #6\n");
141         test_control_return(1);
142     }
143 }
144 
145 
146 
147 /* Define the test threads.  */
148 
thread_0_entry(ULONG thread_input)149 static void    thread_0_entry(ULONG thread_input)
150 {
151 
152 
153     /* Enter into a forever loop.  */
154     while(1)
155     {
156 
157         /* Increment thread 0 counter.  */
158         thread_0_counter++;
159 
160         /* Suspend this thread... */
161         tx_thread_suspend(&thread_0);
162 
163         /* Resume thread 5...  */
164         tx_thread_resume(&thread_5);
165     }
166 }
167 
168 
thread_1_entry(ULONG thread_input)169 static void    thread_1_entry(ULONG thread_input)
170 {
171 
172 
173     /* Enter into a forever loop.  */
174     while(1)
175     {
176 
177         /* Increment thread 1 counter.  */
178         thread_1_counter++;
179 
180         /* Suspend this thread.  */
181         tx_thread_suspend(&thread_1);
182     }
183 }
184 
185 
thread_2_entry(ULONG thread_input)186 static void    thread_2_entry(ULONG thread_input)
187 {
188 
189 
190     /* Enter into a forever loop.  */
191     while(1)
192     {
193 
194         /* Increment thread 2 counter.  */
195         thread_2_counter++;
196 
197         /* Suspend this thread.  */
198         tx_thread_suspend(&thread_2);
199     }
200 }
201 
thread_3_entry(ULONG thread_input)202 static void    thread_3_entry(ULONG thread_input)
203 {
204 
205 
206     /* Enter into a forever loop.  */
207     while(1)
208     {
209 
210         /* Increment thread 3 counter.  */
211         thread_3_counter++;
212 
213         /* Suspend this thread.  */
214         tx_thread_suspend(&thread_3);
215     }
216 }
217 
thread_4_entry(ULONG thread_input)218 static void    thread_4_entry(ULONG thread_input)
219 {
220 
221 
222     /* Enter into a forever loop.  */
223     while(1)
224     {
225 
226         /* Increment thread 4 counter.  */
227         thread_4_counter++;
228 
229         /* Suspend this thread.  */
230         tx_thread_suspend(&thread_4);
231     }
232 }
233 
thread_5_entry(ULONG thread_input)234 static void    thread_5_entry(ULONG thread_input)
235 {
236 
237 UINT    status;
238 
239     /* Inform user.  */
240     printf("Running Thread Suspend/Resume W/Preemption Test..................... ");
241 
242     /* Determine if all the other threads are in a suspended state.  */
243     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
244         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
245         (thread_4.tx_thread_state != TX_SUSPENDED))
246     {
247 
248         /* Thread Suspend error.  */
249         printf("ERROR #7\n");
250         test_control_return(1);
251     }
252 
253     /* Make sure that each thread has run once.  */
254     if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
255         (thread_2_counter != 1) || (thread_3_counter != 1) ||
256         (thread_4_counter != 1))
257     {
258 
259         /* Thread Suspend error.  */
260         printf("ERROR #8\n");
261         test_control_return(1);
262     }
263 
264     /* Resume all of the threads.  */
265     status =  tx_thread_resume(&thread_0);
266 
267     /* Determine if all the other threads are in the proper state.  */
268     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
269         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
270         (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
271     {
272 
273         /* Thread Suspend error.  */
274         printf("ERROR #9\n");
275         test_control_return(1);
276     }
277 
278     /* Make sure that each thread has run the proper amount.  */
279     if ((thread_0_counter != 2) || (thread_1_counter != 1) ||
280         (thread_2_counter != 1) || (thread_3_counter != 1) ||
281         (thread_4_counter != 1))
282     {
283 
284         /* Thread Suspend error.  */
285         printf("ERROR #10\n");
286         test_control_return(1);
287     }
288 
289     status =  tx_thread_resume(&thread_1);
290 
291     /* Determine if all the other threads are in the proper state.  */
292     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
293         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
294         (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
295     {
296 
297         /* Thread Suspend error.  */
298         printf("ERROR #11\n");
299         test_control_return(1);
300     }
301 
302     /* Make sure that each thread has run the proper amount.  */
303     if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
304         (thread_2_counter != 1) || (thread_3_counter != 1) ||
305         (thread_4_counter != 1))
306     {
307 
308         /* Thread Suspend error.  */
309         printf("ERROR #12\n");
310         test_control_return(1);
311     }
312 
313     status =  tx_thread_resume(&thread_2);
314 
315     /* Determine if all the other threads are in the proper state.  */
316     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
317         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
318         (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
319     {
320 
321         /* Thread Suspend error.  */
322         printf("ERROR #13\n");
323         test_control_return(1);
324     }
325 
326     /* Make sure that each thread has the proper amount.  */
327     if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
328         (thread_2_counter != 2) || (thread_3_counter != 1) ||
329         (thread_4_counter != 1))
330     {
331 
332         /* Thread Suspend error.  */
333         printf("ERROR #14\n");
334         test_control_return(1);
335     }
336 
337     status =  tx_thread_resume(&thread_3);
338 
339     /* Determine if all the other threads are in the proper state.  */
340     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
341         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
342         (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
343     {
344 
345         /* Thread Suspend error.  */
346         printf("ERROR #15\n");
347         test_control_return(1);
348     }
349 
350     /* Make sure that each thread has run the proper amount.  */
351     if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
352         (thread_2_counter != 2) || (thread_3_counter != 2) ||
353         (thread_4_counter != 1))
354     {
355 
356         /* Thread Suspend error.  */
357         printf("ERROR #16\n");
358         test_control_return(1);
359     }
360 
361     status =  tx_thread_resume(&thread_4);
362 
363     /* Determine if all the other threads are in the proper state.  */
364     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
365         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
366         (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
367     {
368 
369         /* Thread Suspend error.  */
370         printf("ERROR #17\n");
371         test_control_return(1);
372     }
373 
374     /* Make sure that each thread has run once.  */
375     if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
376         (thread_2_counter != 2) || (thread_3_counter != 2) ||
377         (thread_4_counter != 2))
378     {
379 
380         /* Thread Suspend error.  */
381         printf("ERROR #18\n");
382         test_control_return(1);
383     }
384 
385     /* Relinquish - this should not do anything!  */
386     tx_thread_relinquish();
387 
388     /* Determine if all the other threads are in a suspended state.  */
389     if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
390         (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
391         (thread_4.tx_thread_state != TX_SUSPENDED))
392     {
393 
394         /* Thread Suspend error.  */
395         printf("ERROR #19\n");
396         test_control_return(1);
397     }
398 
399     /* Make sure that each thread has run twice.  */
400     if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
401         (thread_2_counter != 2) || (thread_3_counter != 2) ||
402         (thread_4_counter != 2))
403     {
404 
405         /* Thread Suspend error.  */
406         printf("ERROR #20\n");
407         test_control_return(1);
408     }
409 
410     /* Increment thread 5 counter.  */
411     thread_5_counter++;
412 
413     /* Successful Thread Suspend test.  */
414     printf("SUCCESS!\n");
415     test_control_return(0);
416 }
417