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