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