1 /* Define the ThreadX SMP preemption-threshold test.  */
2 
3 #include   <stdio.h>
4 #include   "tx_api.h"
5 
6 extern TX_THREAD    *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
7 
8 
9 static TX_THREAD       thread_0;
10 static TX_THREAD       thread_1;
11 static TX_THREAD       thread_5;
12 static TX_THREAD       thread_16;
13 static TX_THREAD       thread_16_pt5;
14 static TX_THREAD       thread_18;
15 static TX_THREAD       thread_23_pt17;
16 static TX_THREAD       thread_25;
17 static TX_THREAD       thread_27_pt24;
18 static TX_THREAD       thread_31;
19 
20 static ULONG           thread_run_counter[10];
21 
22 
23 static unsigned long error =  0;
24 
25 
26 /* Define thread prototypes.  */
27 
28 static void    thread_entry(ULONG thread_input);
29 static void    thread_0_entry(ULONG thread_input);
30 
31 
32 /* Prototype for test control return.  */
33 
34 void  test_control_return(UINT status);
35 
36 
delay(UINT i)37 static void   delay(UINT i)
38 {
39 
40     /* Wait until the thread runs!  */
41     while (thread_run_counter[i] == 0)
42     {
43     }
44 }
45 
46 
47 /* Define what the initial system looks like.  */
48 
49 #ifdef CTEST
test_application_define(void * first_unused_memory)50 void test_application_define(void *first_unused_memory)
51 #else
52 void    threadx_smp_preemption_threshold_test(void *first_unused_memory)
53 #endif
54 {
55 
56 UINT    status;
57 CHAR    *pointer;
58 UINT    i;
59 
60 
61     /* Put first available memory address into a character pointer.  */
62     pointer =  (CHAR *) first_unused_memory;
63 
64     /* Put system definition stuff in here, e.g. thread creates and other assorted
65        create information.  */
66 
67     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
68             pointer, TEST_STACK_SIZE_PRINTF,
69             0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
70     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
71     status +=   tx_thread_smp_core_exclude(&thread_0, 0xE);      /* Core 0 only! */
72 
73     /* Check status.  */
74     if (status != TX_SUCCESS)
75     {
76 
77         printf("Running SMP Preemption-Threshold Test............................... ERROR #1\n");
78         test_control_return(1);
79     }
80 
81     status =  tx_thread_create(&thread_1, "thread 1", thread_entry, 1,
82             pointer, TEST_STACK_SIZE_PRINTF,
83             1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
84     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
85     status +=   tx_thread_smp_core_exclude(&thread_1, 0);      /* Any core! */
86 
87     /* Check status.  */
88     if (status != TX_SUCCESS)
89     {
90 
91         printf("Running SMP Preemption-Threshold Test............................... ERROR #2\n");
92         test_control_return(1);
93     }
94 
95     status =  tx_thread_create(&thread_5, "thread 5", thread_entry, 2,
96             pointer, TEST_STACK_SIZE_PRINTF,
97             5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
98     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
99     status +=   tx_thread_smp_core_exclude(&thread_5, 0);      /* Any core! */
100 
101     /* Check status.  */
102     if (status != TX_SUCCESS)
103     {
104 
105         printf("Running SMP Preemption-Threshold Test............................... ERROR #3\n");
106         test_control_return(1);
107     }
108 
109     status =  tx_thread_create(&thread_16, "thread 16", thread_entry, 3,
110             pointer, TEST_STACK_SIZE_PRINTF,
111             16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
112     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
113     status +=   tx_thread_smp_core_exclude(&thread_16, 0);      /* Any core! */
114 
115     /* Check status.  */
116     if (status != TX_SUCCESS)
117     {
118 
119         printf("Running SMP Preemption-Threshold Test............................... ERROR #4\n");
120         test_control_return(1);
121     }
122 
123     status =  tx_thread_create(&thread_16_pt5, "thread 16 PT5", thread_entry, 4,
124             pointer, TEST_STACK_SIZE_PRINTF,
125             16, 5, TX_NO_TIME_SLICE, TX_DONT_START);
126     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
127     status +=   tx_thread_smp_core_exclude(&thread_16_pt5, 0);      /* Any core! */
128 
129     /* Check status.  */
130     if (status != TX_SUCCESS)
131     {
132 
133         printf("Running SMP Preemption-Threshold Test............................... ERROR #5\n");
134         test_control_return(1);
135     }
136 
137     status =  tx_thread_create(&thread_18, "thread 18", thread_entry, 5,
138             pointer, TEST_STACK_SIZE_PRINTF,
139             18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
140     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
141     status +=   tx_thread_smp_core_exclude(&thread_18, 0);      /* Any core! */
142 
143     /* Check status.  */
144     if (status != TX_SUCCESS)
145     {
146 
147         printf("Running SMP Preemption-Threshold Test............................... ERROR #6\n");
148         test_control_return(1);
149     }
150 
151     status =  tx_thread_create(&thread_23_pt17, "thread 23 PT17", thread_entry, 6,
152             pointer, TEST_STACK_SIZE_PRINTF,
153             23, 17, TX_NO_TIME_SLICE, TX_DONT_START);
154     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
155     status +=   tx_thread_smp_core_exclude(&thread_23_pt17, 0);      /* Any core! */
156 
157     /* Check status.  */
158     if (status != TX_SUCCESS)
159     {
160 
161         printf("Running SMP Preemption-Threshold Test............................... ERROR #7\n");
162         test_control_return(1);
163     }
164 
165     status =  tx_thread_create(&thread_25, "thread 25", thread_entry, 7,
166             pointer, TEST_STACK_SIZE_PRINTF,
167             25, 25, TX_NO_TIME_SLICE, TX_DONT_START);
168     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
169     status +=   tx_thread_smp_core_exclude(&thread_25, 0);      /* Any core! */
170 
171     /* Check status.  */
172     if (status != TX_SUCCESS)
173     {
174 
175         printf("Running SMP Preemption-Threshold Test............................... ERROR #8\n");
176         test_control_return(1);
177     }
178 
179     status =  tx_thread_create(&thread_27_pt24, "thread 27 PT24", thread_entry, 8,
180             pointer, TEST_STACK_SIZE_PRINTF,
181             27, 24, TX_NO_TIME_SLICE, TX_DONT_START);
182     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
183     status +=   tx_thread_smp_core_exclude(&thread_27_pt24, 0);      /* Any core! */
184 
185     /* Check status.  */
186     if (status != TX_SUCCESS)
187     {
188 
189         printf("Running SMP Preemption-Threshold Test............................... ERROR #9\n");
190         test_control_return(1);
191     }
192 
193     status =  tx_thread_create(&thread_31, "thread 31", thread_entry, 9,
194             pointer, TEST_STACK_SIZE_PRINTF,
195             31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
196     pointer =  pointer + TEST_STACK_SIZE_PRINTF;
197     status +=   tx_thread_smp_core_exclude(&thread_31, 0);      /* Any core! */
198 
199     /* Check status.  */
200     if (status != TX_SUCCESS)
201     {
202 
203         printf("Running SMP Preemption-Threshold Test............................... ERROR #10\n");
204         test_control_return(1);
205     }
206 
207     /* Clear the thread run count array.  */
208     for (i = 0; i < 10; i++)
209     {
210         thread_run_counter[i] =  0;
211     }
212 
213 	/* Resume thread 0.  */
214     status =  tx_thread_resume(&thread_0);
215 
216 	/* Check status.  */
217     if (status != TX_SUCCESS)
218     {
219 
220         printf("Running SMP Preemption-Threshold Test............................... ERROR #11\n");
221         test_control_return(1);
222     }
223 }
224 
225 
226 
227 /* Define the test threads.  */
228 
thread_0_entry(ULONG thread_input)229 static void    thread_0_entry(ULONG thread_input)
230 {
231 
232 UINT    status;
233 
234 
235 
236     /* Inform user.  */
237     printf("Running SMP Preemption-Threshold Test............................... ");
238 
239 	/* This test is only useful when preemption-threshold is enabled.  */
240 #ifndef TX_DISABLE_PREEMPTION_THRESHOLD
241 
242 	/* Resume thread.  */
243     status =  tx_thread_resume(&thread_31);
244     delay(9);
245     /* Check for the correct results.  */
246     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
247                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
248     {
249 
250         /* Execution error.  */
251         printf("ERROR #12\n");
252         test_control_return(1);
253     }
254 
255     /* Resume thread.  */
256     status =  tx_thread_resume(&thread_27_pt24);
257     delay(8);
258     /* Check for the correct results.  */
259     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_27_pt24)
260                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
261     {
262 
263         /* Execution error.  */
264         printf("ERROR #13\n");
265         test_control_return(1);
266     }
267 
268     /* Resume thread.  */
269     status =  tx_thread_resume(&thread_23_pt17);
270     delay(6);
271     /* Check for the correct results.  */
272     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_23_pt17)
273                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
274     {
275 
276         /* Execution error.  */
277         printf("ERROR #14\n");
278         test_control_return(1);
279     }
280 
281     /* Resume thread.  */
282     status =  tx_thread_resume(&thread_16_pt5);
283     delay(4);
284     /* Check for the correct results.  */
285     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
286                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
287     {
288 
289         /* Execution error.  */
290         printf("ERROR #15\n");
291         test_control_return(1);
292     }
293 
294     /* Resume thread.  */
295     status =  tx_thread_resume(&thread_16);
296     /* Check for the correct results.  */
297     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
298                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
299     {
300 
301         /* Execution error.  */
302         printf("ERROR #16\n");
303         test_control_return(1);
304     }
305 
306     /* Resume thread.  */
307     status =  tx_thread_resume(&thread_25);
308     /* Check for the correct results.  */
309     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
310                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
311     {
312 
313         /* Execution error.  */
314         printf("ERROR #17\n");
315         test_control_return(1);
316     }
317 
318     /* Resume thread.  */
319     status =  tx_thread_resume(&thread_18);
320     /* Check for the correct results.  */
321     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
322                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
323     {
324 
325         /* Execution error.  */
326         printf("ERROR #18\n");
327         test_control_return(1);
328     }
329 
330     /* Resume thread.  */
331     status =  tx_thread_resume(&thread_5);
332     /* Check for the correct results.  */
333     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
334                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
335     {
336 
337         /* Execution error.  */
338         printf("ERROR #19\n");
339         test_control_return(1);
340     }
341 
342     /* Resume thread.  */
343     status =  tx_thread_resume(&thread_1);
344     /* Check for the correct results.  */
345     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
346                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
347     {
348 
349         /* Execution error.  */
350         printf("ERROR #20\n");
351         test_control_return(1);
352     }
353 
354     /* Suspend Thread 16 pt5.  */
355     status =  tx_thread_suspend(&thread_16_pt5);
356 
357     delay(2);
358     delay(3);
359 
360     /* Check for the correct results.  */
361     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
362                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_16))
363     {
364 
365         /* Execution error.  */
366         printf("ERROR #21\n");
367         test_control_return(1);
368     }
369 
370 
371     /* Suspend Thread 16.  */
372     status =  tx_thread_suspend(&thread_16);
373 
374     delay(6);
375 
376     /* Check for the correct results.  */
377     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
378                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_23_pt17))
379     {
380 
381         /* Execution error.  */
382         printf("ERROR #22\n");
383         test_control_return(1);
384     }
385 
386     /* Suspend Thread 23 pt 17.  */
387     status =  tx_thread_suspend(&thread_23_pt17);
388 
389     delay(5);
390 
391     /* Check for the correct results.  */
392     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
393                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_18))
394     {
395 
396         /* Execution error.  */
397         printf("ERROR #23\n");
398         test_control_return(1);
399     }
400 
401 
402     /* Suspend Thread 18.  */
403     status =  tx_thread_suspend(&thread_18);
404 
405     delay(8);
406 
407     /* Check for the correct results.  */
408     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
409                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_27_pt24))
410     {
411 
412         /* Execution error.  */
413         printf("ERROR #24\n");
414         test_control_return(1);
415     }
416 
417     /* Suspend Thread 27 pt 24.  */
418     status =  tx_thread_suspend(&thread_27_pt24);
419 
420     delay(7);
421 
422     /* Check for the correct results.  */
423     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
424                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_25))
425     {
426 
427         /* Execution error.  */
428         printf("ERROR #25\n");
429         test_control_return(1);
430     }
431 
432     /* Suspend Thread 25.  */
433     status =  tx_thread_suspend(&thread_25);
434 
435     delay(9);
436 
437     /* Check for the correct results.  */
438     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
439                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
440     {
441 
442         /* Execution error.  */
443         printf("ERROR #26\n");
444         test_control_return(1);
445     }
446 
447     /* Resume thread 16 pt 5.  */
448     status =  tx_thread_resume(&thread_16_pt5);
449 
450     /* Check for the correct results.  */
451     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
452                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
453     {
454 
455         /* Execution error.  */
456         printf("ERROR #27\n");
457         test_control_return(1);
458     }
459 
460     /* Suspend thread 16 pt 5.  */
461     status =  tx_thread_suspend(&thread_16_pt5);
462 
463     /* Check for the correct results.  */
464     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
465                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
466     {
467 
468         /* Execution error.  */
469         printf("ERROR #28\n");
470         test_control_return(1);
471     }
472 
473     /* Suspend thread 31.  */
474     status =  tx_thread_suspend(&thread_31);
475 
476     /* Check for the correct results.  */
477     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
478                                || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
479     {
480 
481         /* Execution error.  */
482         printf("ERROR #29\n");
483         test_control_return(1);
484     }
485 
486     /* Suspend thread 1.  */
487     status =  tx_thread_suspend(&thread_1);
488 
489     /* Check for the correct results.  */
490     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
491                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
492     {
493 
494         /* Execution error.  */
495         printf("ERROR #30\n");
496         test_control_return(1);
497     }
498 
499     /* Suspend thread 5.  */
500     status =  tx_thread_suspend(&thread_5);
501 
502     /* Check for the correct results.  */
503     if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
504                                || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
505     {
506 
507         /* Execution error.  */
508         printf("ERROR #31\n");
509         test_control_return(1);
510     }
511 #endif
512 
513     /* Successful test.  */
514     printf("SUCCESS!\n");
515 
516     test_control_return(0);
517 }
518 
519 
thread_entry(ULONG thread_input)520 static void    thread_entry(ULONG thread_input)
521 {
522 
523     /* Increment the run counter.  */
524     thread_run_counter[thread_input]++;
525 
526     while(1)
527     {
528 
529         tx_thread_identify();
530 
531 		/* Indicate the thread is running... */
532         thread_run_counter[thread_input]++;
533     }
534 }
535