1 /* This test is designed to test the mutex suspension prioritization. */
2
3 #include <stdio.h>
4 #include "tx_api.h"
5
6
7 /* Define the ISR dispatch. */
8
9 extern VOID (*test_isr_dispatch)(void);
10
11
12 /* Define the external reference for the preempt disable flag. */
13
14 extern volatile UINT _tx_thread_preempt_disable;
15
16
17 static unsigned long thread_0_counter = 0;
18 static TX_THREAD thread_0;
19
20 static unsigned long thread_1_counter = 0;
21 static TX_THREAD thread_1;
22
23 static unsigned long thread_2_counter = 0;
24 static TX_THREAD thread_2;
25
26 static unsigned long thread_3_counter = 0;
27 static TX_THREAD thread_3;
28
29 static unsigned long thread_4_counter = 0;
30 static TX_THREAD thread_4;
31
32 static unsigned long thread_5_counter = 0;
33 static TX_THREAD thread_5;
34
35 static unsigned long thread_6_counter = 0;
36 static TX_THREAD thread_6;
37
38
39 static TX_MUTEX mutex_0;
40 static TX_MUTEX mutex_1;
41
42 static int test_status;
43
44
45 /* Define thread prototypes. */
46
47 static void thread_0_entry(ULONG thread_input);
48 static void thread_1_entry(ULONG thread_input);
49 static void thread_2_entry(ULONG thread_input);
50 static void thread_3_entry(ULONG thread_input);
51 static void thread_4_entry(ULONG thread_input);
52 static void thread_5_entry(ULONG thread_input);
53 static void thread_6_entry(ULONG thread_input);
54
55
56 /* Prototype for test control return. */
57
58 void test_control_return(UINT status);
59
60
61 /* Define the ISR dispatch routine. */
62
test_isr(void)63 static void test_isr(void)
64 {
65
66 /* Determine if the test case we are looking for is present. */
67 if ((_tx_thread_preempt_disable) && (test_status == 1))
68 {
69
70 /* Determine if thread 3 is at the front of the suspension list. */
71 if (mutex_0.tx_mutex_suspension_list == &thread_3)
72 {
73
74 /* Abort the wait of thread 3. */
75 tx_thread_wait_abort(&thread_3);
76 }
77 else
78 {
79
80 /* Abort the wait of thread 5. */
81 tx_thread_wait_abort(&thread_5);
82
83 /* End the ISR processing. */
84 test_status = 2;
85 test_isr_dispatch = TX_NULL;
86 }
87 }
88 }
89
90
91 /* Define what the initial system looks like. */
92
93 #ifdef CTEST
test_application_define(void * first_unused_memory)94 void test_application_define(void *first_unused_memory)
95 #else
96 void threadx_mutex_prioritize_application_define(void *first_unused_memory)
97 #endif
98 {
99
100 UINT status;
101 CHAR *pointer;
102
103
104 /* Put first available memory address into a character pointer. */
105 pointer = (CHAR *) first_unused_memory;
106
107 /* Put system definition stuff in here, e.g. thread creates and other assorted
108 create information. */
109
110 status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
111 pointer, TEST_STACK_SIZE_PRINTF,
112 16, 16, 100, TX_AUTO_START);
113 pointer = pointer + TEST_STACK_SIZE_PRINTF;
114
115 /* Check for status. */
116 if (status != TX_SUCCESS)
117 {
118
119 printf("Running Mutex Prioritize Test....................................... ERROR #1\n");
120 test_control_return(1);
121 }
122
123 status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
124 pointer, TEST_STACK_SIZE_PRINTF,
125 15, 15, 100, TX_DONT_START);
126 pointer = pointer + TEST_STACK_SIZE_PRINTF;
127
128 /* Check for status. */
129 if (status != TX_SUCCESS)
130 {
131
132 printf("Running Mutex Prioritize Test....................................... ERROR #2\n");
133 test_control_return(1);
134 }
135
136 status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
137 pointer, TEST_STACK_SIZE_PRINTF,
138 14, 14, 100, TX_DONT_START);
139 pointer = pointer + TEST_STACK_SIZE_PRINTF;
140
141 /* Check for status. */
142 if (status != TX_SUCCESS)
143 {
144
145 printf("Running Mutex Prioritize Test....................................... ERROR #3\n");
146 test_control_return(1);
147 }
148
149 status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
150 pointer, TEST_STACK_SIZE_PRINTF,
151 3, 3, 100, TX_DONT_START);
152 pointer = pointer + TEST_STACK_SIZE_PRINTF;
153
154 /* Check for status. */
155 if (status != TX_SUCCESS)
156 {
157
158 printf("Running Mutex Prioritize Test....................................... ERROR #4\n");
159 test_control_return(1);
160 }
161
162 status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
163 pointer, TEST_STACK_SIZE_PRINTF,
164 4, 4, 100, TX_DONT_START);
165 pointer = pointer + TEST_STACK_SIZE_PRINTF;
166
167 /* Check for status. */
168 if (status != TX_SUCCESS)
169 {
170
171 printf("Running Mutex Prioritize Test....................................... ERROR #5\n");
172 test_control_return(1);
173 }
174
175 status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
176 pointer, TEST_STACK_SIZE_PRINTF,
177 5, 5, 100, TX_DONT_START);
178 pointer = pointer + TEST_STACK_SIZE_PRINTF;
179
180 /* Check for status. */
181 if (status != TX_SUCCESS)
182 {
183
184 printf("Running Mutex Prioritize Test....................................... ERROR #6\n");
185 test_control_return(1);
186 }
187
188 status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
189 pointer, TEST_STACK_SIZE_PRINTF,
190 6, 6, 100, TX_DONT_START);
191 pointer = pointer + TEST_STACK_SIZE_PRINTF;
192
193 /* Check for status. */
194 if (status != TX_SUCCESS)
195 {
196
197 printf("Running Mutex Prioritize Test....................................... ERROR #7\n");
198 test_control_return(1);
199 }
200
201 /* Create a mutex. */
202 status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
203
204 /* Check for status. */
205 if (status != TX_SUCCESS)
206 {
207
208 printf("Running Mutex Prioritize Test....................................... ERROR #8\n");
209 test_control_return(1);
210 }
211 }
212
213
214
215 /* Define the test threads. */
216
thread_0_entry(ULONG thread_input)217 static void thread_0_entry(ULONG thread_input)
218 {
219
220 UINT status;
221
222
223 /* Inform user. */
224 printf("Running Mutex Prioritize Test....................................... ");
225
226 /* Increment thread 0 counter. */
227 thread_0_counter++;
228
229 #ifndef TX_DISABLE_ERROR_CHECKING
230
231 /* Attempt to prioritize a NULL mutex. */
232 status = tx_mutex_prioritize(TX_NULL);
233
234 /* Check status. */
235 if (status != TX_MUTEX_ERROR)
236 {
237
238 /* Mutex error. */
239 printf("ERROR #9\n");
240 test_control_return(1);
241 }
242
243 /* Attempt to prioritize a non-created mutex. */
244 mutex_1.tx_mutex_id = 0;
245 status = tx_mutex_prioritize(&mutex_1);
246
247 /* Check status. */
248 if (status != TX_MUTEX_ERROR)
249 {
250
251 /* Mutex error. */
252 printf("ERROR #10\n");
253 test_control_return(1);
254 }
255 #endif
256
257 /* Prioritize the mutex with no suspended threads! */
258 status = tx_mutex_prioritize(&mutex_0);
259
260 /* Check status. */
261 if (status != TX_SUCCESS)
262 {
263
264 /* Mutex error. */
265 printf("ERROR #11\n");
266 test_control_return(1);
267 }
268
269 /* Grab the mutex so it is owned by this thread. */
270 status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
271
272 /* Check status. */
273 if (status != TX_SUCCESS)
274 {
275
276 /* Mutex error. */
277 printf("ERROR #12\n");
278 test_control_return(1);
279 }
280
281 /* Resume other threads run. */
282 tx_thread_resume(&thread_1);
283 tx_thread_resume(&thread_2);
284
285 /* Other threads should now be suspended on the mutex. Thread 1 should be
286 in front of thread 2 since it was suspended first. */
287 if (mutex_0.tx_mutex_suspension_list != &thread_1)
288 {
289
290 /* Mutex error. */
291 printf("ERROR #13\n");
292 test_control_return(1);
293 }
294
295 /* Prioritize the mutex to test it out! */
296 status = tx_mutex_prioritize(&mutex_0);
297
298 /* Check status and make sure thread 2 is now at the front of the list. */
299 if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
300 {
301
302 /* Mutex error. */
303 printf("ERROR #14\n");
304 test_control_return(1);
305 }
306
307 /* Prioritize the mutex again to make sure nothing has changed! */
308 status = tx_mutex_prioritize(&mutex_0);
309
310 /* Check status and make sure thread 2 is now at the front of the list. */
311 if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
312 {
313
314 /* Mutex error. */
315 printf("ERROR #14a\n");
316 test_control_return(1);
317 }
318
319 /* At this point we are going to get more than 2 threads suspended. */
320 tx_thread_resume(&thread_1);
321 tx_thread_resume(&thread_2);
322 tx_thread_resume(&thread_3);
323 tx_thread_resume(&thread_4);
324 tx_thread_resume(&thread_5);
325 tx_thread_resume(&thread_6);
326
327 /* Prioritize the block pool suspension list. */
328 status = tx_mutex_prioritize(&mutex_0);
329
330 /* Check status and make sure thread 3 is at the front of the suspension list. */
331 if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_3))
332 {
333
334 /* Mutex error. */
335 printf("ERROR #15\n");
336 test_control_return(1);
337 }
338
339 /* Now loop to test the interrupt of the prioritize loop logic. */
340 test_status = 1;
341 test_isr_dispatch = test_isr;
342 do
343 {
344
345 /* Prioritize the mutex suspension list. */
346 status = tx_mutex_prioritize(&mutex_0);
347
348 /* Check status and make sure thread 1 is terminated. */
349 if (status != TX_SUCCESS)
350 {
351
352 /* Mutex error. */
353 printf("ERROR #16\n");
354 test_control_return(1);
355 }
356
357 } while (test_status == 1);
358
359 /* Now determine if thread 4 is at the front of the list... It should be! */
360 if (mutex_0.tx_mutex_suspension_list != &thread_4)
361 {
362
363 /* Mutex error. */
364 printf("ERROR #17\n");
365 test_control_return(1);
366 }
367 else
368 {
369
370 /* Successful test. */
371 printf("SUCCESS!\n");
372 test_control_return(0);
373 }
374 }
375
376
thread_1_entry(ULONG thread_input)377 static void thread_1_entry(ULONG thread_input)
378 {
379
380 UINT status;
381
382
383 while (1)
384 {
385
386 /* Suspend on the mutex. */
387 status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
388
389 /* Release the mutex. */
390 status += tx_mutex_put(&mutex_0);
391
392 /* Did we get the right status? */
393 if (status == TX_SUCCESS)
394 thread_1_counter++;
395
396 /* Self suspend. */
397 tx_thread_suspend(&thread_1);
398 }
399 }
400
401
thread_2_entry(ULONG thread_input)402 static void thread_2_entry(ULONG thread_input)
403 {
404
405 UINT status;
406
407
408 while (1)
409 {
410
411 /* Suspend on the mutex. */
412 status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
413
414 /* Release the mutex. */
415 status += tx_mutex_put(&mutex_0);
416
417 /* Did we get the right status? */
418 if (status == TX_SUCCESS)
419 thread_2_counter++;
420
421 /* Self suspend. */
422 tx_thread_suspend(&thread_2);
423 }
424 }
425
426
thread_3_entry(ULONG thread_input)427 static void thread_3_entry(ULONG thread_input)
428 {
429
430 UINT status;
431
432
433 while (1)
434 {
435
436 /* Suspend on the mutex. */
437 status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
438
439 /* Release the mutex. */
440 status += tx_mutex_put(&mutex_0);
441
442 /* Did we get the right status? */
443 if (status == TX_SUCCESS)
444 thread_3_counter++;
445
446 /* Self suspend. */
447 tx_thread_suspend(&thread_3);
448 }
449 }
450
451
thread_4_entry(ULONG thread_input)452 static void thread_4_entry(ULONG thread_input)
453 {
454
455 UINT status;
456
457
458 while (1)
459 {
460
461 /* Suspend on the mutex. */
462 status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
463
464 /* Release the mutex. */
465 status += tx_mutex_put(&mutex_0);
466
467 /* Did we get the right status? */
468 if (status == TX_SUCCESS)
469 thread_4_counter++;
470
471 /* Self suspend. */
472 tx_thread_suspend(&thread_4);
473 }
474 }
475
476
thread_5_entry(ULONG thread_input)477 static void thread_5_entry(ULONG thread_input)
478 {
479
480 UINT status;
481
482
483 while (1)
484 {
485
486 /* Suspend on the mutex. */
487 status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
488
489 /* Release the mutex. */
490 status += tx_mutex_put(&mutex_0);
491
492 /* Did we get the right status? */
493 if (status == TX_SUCCESS)
494 thread_5_counter++;
495
496 /* Self suspend. */
497 tx_thread_suspend(&thread_5);
498 }
499 }
500
501
thread_6_entry(ULONG thread_input)502 static void thread_6_entry(ULONG thread_input)
503 {
504
505 UINT status;
506
507
508 while (1)
509 {
510
511 /* Suspend on the mutex. */
512 status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
513
514 /* Release the mutex. */
515 status += tx_mutex_put(&mutex_0);
516
517 /* Did we get the right status? */
518 if (status == TX_SUCCESS)
519 thread_6_counter++;
520
521 /* Self suspend. */
522 tx_thread_suspend(&thread_6);
523 }
524 }
525
526