1 /* This test is designed to test block memory information services.  */
2 
3 #include   <stdio.h>
4 #include   "tx_api.h"
5 #include   "tx_block_pool.h"
6 
7 
8 /* Define the ISR dispatch.  */
9 
10 extern VOID    (*test_isr_dispatch)(void);
11 
12 
13 /* Define the external reference for the preempt disable flag.  */
14 
15 extern volatile UINT   _tx_thread_preempt_disable;
16 
17 
18 
19 static unsigned long   thread_0_counter =  0;
20 static TX_THREAD       thread_0;
21 
22 static unsigned long   thread_1_counter =  0;
23 static TX_THREAD       thread_1;
24 
25 static unsigned long   thread_2_counter =  0;
26 static TX_THREAD       thread_2;
27 
28 static unsigned long   thread_3_counter =  0;
29 static TX_THREAD       thread_3;
30 
31 static unsigned long   thread_4_counter =  0;
32 static TX_THREAD       thread_4;
33 
34 static unsigned long   thread_5_counter =  0;
35 static TX_THREAD       thread_5;
36 
37 static unsigned long   thread_6_counter =  0;
38 static TX_THREAD       thread_6;
39 
40 static TX_BLOCK_POOL   block_pool_0;
41 static TX_BLOCK_POOL   block_pool_2;
42 #ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
43 static TX_BLOCK_POOL   block_pool_1;
44 #endif
45 
46 static int             test_status;
47 
48 
49 /* Define thread prototypes.  */
50 
51 static void    thread_0_entry(ULONG thread_input);
52 static void    thread_1_entry(ULONG thread_input);
53 static void    thread_2_entry(ULONG thread_input);
54 static void    thread_3_entry(ULONG thread_input);
55 static void    thread_4_entry(ULONG thread_input);
56 static void    thread_5_entry(ULONG thread_input);
57 static void    thread_6_entry(ULONG thread_input);
58 
59 /* Direct core function to bypass the error checking shell.  */
60 UINT  _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks,
61                     ULONG *total_blocks, TX_THREAD **first_suspended,
62                     ULONG *suspended_count, TX_BLOCK_POOL **next_pool);
63 
64 /* Prototype for test control return.  */
65 void  test_control_return(UINT status);
66 
67 
68 /* Define the ISR dispatch routine.  */
69 
test_isr(void)70 static void    test_isr(void)
71 {
72 
73     /* Determine if the test case we are looking for is present.  */
74     if ((_tx_thread_preempt_disable) && (test_status == 1))
75     {
76 
77         /* Abort the wait of thread 3.  */
78         tx_thread_wait_abort(&thread_3);
79 
80         /* End the ISR processing.  */
81         test_status =  2;
82         test_isr_dispatch =  TX_NULL;
83     }
84 }
85 
86 
87 /* Define what the initial system looks like.  */
88 
89 #ifdef CTEST
test_application_define(void * first_unused_memory)90 void test_application_define(void *first_unused_memory)
91 #else
92 void    threadx_block_memory_information_application_define(void *first_unused_memory)
93 #endif
94 {
95 
96 UINT    status;
97 CHAR    *pointer;
98 
99 
100     /* Put first available memory address into a character pointer.  */
101     pointer =  (CHAR *) first_unused_memory;
102 
103     /* Put system definition stuff in here, e.g. thread creates and other assorted
104        create information.  */
105 
106     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
107             pointer, TEST_STACK_SIZE_PRINTF,
108             17, 17, 100, TX_AUTO_START);
109     pointer = pointer + TEST_STACK_SIZE_PRINTF;
110 
111     /* Check for status.  */
112     if (status != TX_SUCCESS)
113     {
114 
115         printf("Running Block Memory Information Test............................... ERROR #1\n");
116         test_control_return(1);
117     }
118 
119     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
120             pointer, TEST_STACK_SIZE_PRINTF,
121             16, 16, 100, TX_DONT_START);
122     pointer = pointer + TEST_STACK_SIZE_PRINTF;
123 
124     /* Check for status.  */
125     if (status != TX_SUCCESS)
126     {
127 
128         printf("Running Block Memory Information Test............................... ERROR #2\n");
129         test_control_return(1);
130     }
131 
132     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
133             pointer, TEST_STACK_SIZE_PRINTF,
134             15, 15, 100, TX_DONT_START);
135     pointer = pointer + TEST_STACK_SIZE_PRINTF;
136 
137     /* Check for status.  */
138     if (status != TX_SUCCESS)
139     {
140 
141         printf("Running Block Memory Information Test............................... ERROR #3\n");
142         test_control_return(1);
143     }
144 
145     status =  tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
146             pointer, TEST_STACK_SIZE_PRINTF,
147             3, 3, 100, TX_DONT_START);
148     pointer = pointer + TEST_STACK_SIZE_PRINTF;
149 
150     /* Check for status.  */
151     if (status != TX_SUCCESS)
152     {
153 
154         printf("Running Block Memory Information Test............................... ERROR #4\n");
155         test_control_return(1);
156     }
157 
158     status =  tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
159             pointer, TEST_STACK_SIZE_PRINTF,
160             4, 4, 100, TX_DONT_START);
161     pointer = pointer + TEST_STACK_SIZE_PRINTF;
162 
163     /* Check for status.  */
164     if (status != TX_SUCCESS)
165     {
166 
167         printf("Running Block Memory Information Test............................... ERROR #5\n");
168         test_control_return(1);
169     }
170 
171     status =  tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
172             pointer, TEST_STACK_SIZE_PRINTF,
173             5, 5, 100, TX_DONT_START);
174     pointer = pointer + TEST_STACK_SIZE_PRINTF;
175 
176     /* Check for status.  */
177     if (status != TX_SUCCESS)
178     {
179 
180         printf("Running Block Memory Information Test............................... ERROR #6\n");
181         test_control_return(1);
182     }
183 
184     status =  tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
185             pointer, TEST_STACK_SIZE_PRINTF,
186             6, 6, 100, TX_DONT_START);
187     pointer = pointer + TEST_STACK_SIZE_PRINTF;
188 
189     /* Check for status.  */
190     if (status != TX_SUCCESS)
191     {
192 
193         printf("Running Block Memory Information Test............................... ERROR #7\n");
194         test_control_return(1);
195     }
196 
197     /* Create the block_pool with one block.  */
198     status =  tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
199     pointer = pointer + 40;
200 
201     /* Check for status.  */
202     if (status != TX_SUCCESS)
203     {
204 
205         printf("Running Block Memory Information Test............................... ERROR #8\n");
206         test_control_return(1);
207     }
208 }
209 
210 
211 
212 /* Define the test threads.  */
213 
thread_0_entry(ULONG thread_input)214 static void    thread_0_entry(ULONG thread_input)
215 {
216 
217 UINT            status;
218 VOID            *pointer;
219 CHAR            *name;
220 ULONG           available;
221 ULONG           total_blocks;
222 TX_THREAD       *first_suspended;
223 ULONG           suspended_count;
224 TX_BLOCK_POOL   *next_pool;
225 ULONG           allocates;
226 ULONG           releases;
227 ULONG           suspensions;
228 ULONG           timeouts;
229 
230 
231     /* Inform user.  */
232     printf("Running Block Memory Information Test............................... ");
233 
234     /* Allocate the one block.  */
235     tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
236 
237     /* Nothing to do here, but check prioritization with no suspended threads.  */
238     status =  tx_block_pool_prioritize(&block_pool_0);
239 
240     /* Check for an error condition.   */
241     if (status != TX_SUCCESS)
242     {
243 
244         /* Block Pool error.  */
245         printf("ERROR #9\n");
246         test_control_return(1);
247     }
248 
249     /* Get both threads suspended.  */
250     tx_thread_resume(&thread_1);
251     tx_thread_resume(&thread_2);
252 
253     /* Increment the thread counter.  */
254     thread_0_counter++;
255 
256     /* Make sure thread 1 and 2 are suspended on the block_pool.  */
257     if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
258         (block_pool_0.tx_block_pool_suspension_list != &thread_1))
259     {
260 
261         /* Block Pool error.  */
262         printf("ERROR #10\n");
263         test_control_return(1);
264     }
265 
266     /* Prioritize the block pool suspension list.  */
267     status =  tx_block_pool_prioritize(&block_pool_0);
268 
269     /* Check status and make sure thread 1 is terminated.  */
270     if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
271     {
272 
273         /* Block Pool error.  */
274         printf("ERROR #11\n");
275         test_control_return(1);
276     }
277 
278     /* At this point we are going to get more than 2 threads suspended.  */
279     tx_thread_resume(&thread_1);
280     tx_thread_resume(&thread_2);
281     tx_thread_resume(&thread_3);
282     tx_thread_resume(&thread_4);
283     tx_thread_resume(&thread_5);
284     tx_thread_resume(&thread_6);
285 
286     /* Prioritize the block pool suspension list.  */
287     status =  tx_block_pool_prioritize(&block_pool_0);
288 
289     /* Check status and make sure thread 3 is at the front of the suspension list.  */
290     if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
291     {
292 
293         /* Block Pool error.  */
294         printf("ERROR #12\n");
295         test_control_return(1);
296     }
297 
298     /* Now loop to test the interrupt of the prioritize loop logic.  */
299     test_status =  1;
300     test_isr_dispatch =  test_isr;
301     do
302     {
303 
304         /* Prioritize the block pool suspension list.  */
305         status =  tx_block_pool_prioritize(&block_pool_0);
306 
307         /* Check status and make sure thread 1 is terminated.  */
308         if (status != TX_SUCCESS)
309         {
310 
311             /* Block Pool error.  */
312             printf("ERROR #13\n");
313             test_control_return(1);
314         }
315 
316     } while (test_status == 1);
317 
318     /* Now determine if thread 4 is at the front of the list... It should be!  */
319     if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
320     {
321 
322         /* Block Pool error.  */
323         printf("ERROR #14\n");
324         test_control_return(1);
325     }
326 
327 #ifndef TX_DISABLE_ERROR_CHECKING
328 
329     /* Test the NULL pointer on the info get call.  */
330     status =  tx_block_pool_info_get(TX_NULL, TX_NULL, TX_NULL,  TX_NULL,       TX_NULL,          TX_NULL,          TX_NULL);
331 
332     /* Check for the proper error code.  */
333     if (status != TX_POOL_ERROR)
334     {
335 
336         /* Block Pool error.  */
337         printf("ERROR #15\n");
338         test_control_return(1);
339     }
340 
341     /* Test the non-thread pointer on the info get call.  */
342     block_pool_2.tx_block_pool_id =  0;
343     status =  tx_block_pool_info_get(&block_pool_2, TX_NULL, TX_NULL,  TX_NULL,       TX_NULL,          TX_NULL,          TX_NULL);
344 
345     /* Check for the proper error code.  */
346     if (status != TX_POOL_ERROR)
347     {
348 
349         /* Block Pool error.  */
350         printf("ERROR #16\n");
351         test_control_return(1);
352     }
353 
354 #endif
355 
356     /* Now use the information services in order to test them.  */
357     status =  tx_block_pool_info_get(&block_pool_0, TX_NULL, TX_NULL,  TX_NULL,       TX_NULL,          TX_NULL,          TX_NULL);
358     status +=  tx_block_pool_info_get(&block_pool_0, &name, &available, &total_blocks, &first_suspended, &suspended_count, &next_pool);
359 
360     /* Check for an error condition.  */
361     if ((status) || (available != block_pool_0.tx_block_pool_available) || (total_blocks != block_pool_0.tx_block_pool_total) ||
362         (first_suspended != &thread_4) || (suspended_count != block_pool_0.tx_block_pool_suspended_count) || (next_pool != &block_pool_0))
363     {
364 
365         /* Block Pool error.  */
366         printf("ERROR #17\n");
367         test_control_return(1);
368     }
369 
370 #ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
371 
372      /* Call the core block pool info get function with a NULL pointer.  */
373     status =  _tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
374 
375     /* Check for the proper error code.  */
376     if (status != TX_PTR_ERROR)
377     {
378 
379         /* Block Pool error.  */
380         printf("ERROR #18\n");
381         test_control_return(1);
382     }
383 
384    /* Call the core block pool info get function with a non-initialized pool.  */
385     status =  _tx_block_pool_performance_info_get(&block_pool_1, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
386 
387     /* Check for the proper error code.  */
388     if (status != TX_PTR_ERROR)
389     {
390 
391         /* Block Pool error.  */
392         printf("ERROR #19\n");
393         test_control_return(1);
394     }
395 
396     /* Now get the pool performance information.   */
397     status =  tx_block_pool_performance_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
398     status += tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
399 
400     /* Check for an error condition.  */
401     if ((status) || (allocates != block_pool_0.tx_block_pool_performance_allocate_count) ||
402         (releases != block_pool_0.tx_block_pool_performance_release_count) ||
403         (suspensions != block_pool_0.tx_block_pool_performance_suspension_count) ||
404         (timeouts != block_pool_0.tx_block_pool_performance_timeout_count))
405     {
406 
407         /* Block Pool error.  */
408         printf("ERROR #20\n");
409         test_control_return(1);
410     }
411 
412     /* Now get the system pool performance information.  */
413     status =  tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
414     status += tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
415 
416     /* Check for an error condition.  */
417     if ((status) || (allocates != _tx_block_pool_performance_allocate_count) || (releases != _tx_block_pool_performance_release_count) ||
418         (suspensions != _tx_block_pool_performance_suspension_count) || (timeouts != _tx_block_pool_performance_timeout_count))
419     {
420 
421         /* Block Pool error.  */
422         printf("ERROR #21\n");
423         test_control_return(1);
424     }
425     else
426     {
427 
428         /* Successful test.  */
429         printf("SUCCESS!\n");
430         test_control_return(0);
431     }
432 #else
433 
434     /* Call the block pool performance info get function.  */
435     status =  tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
436 
437     /* Check for the proper error code.  */
438     if (status != TX_FEATURE_NOT_ENABLED)
439     {
440 
441         /* Block Pool error.  */
442         printf("ERROR #22\n");
443         test_control_return(1);
444     }
445 
446     /* Call the block pool performance info get function.  */
447     status =  tx_block_pool_performance_info_get(TX_NULL, &allocates, &releases, &suspensions, &timeouts);
448 
449     /* Check for the proper error code.  */
450     if (status != TX_FEATURE_NOT_ENABLED)
451     {
452 
453         /* Block Pool error.  */
454         printf("ERROR #23\n");
455         test_control_return(1);
456     }
457 
458     /* Call the block pool performance info get function.  */
459     status =  tx_block_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &suspensions, &timeouts);
460 
461     /* Check for the proper error code.  */
462     if (status != TX_FEATURE_NOT_ENABLED)
463     {
464 
465         /* Block Pool error.  */
466         printf("ERROR #24\n");
467         test_control_return(1);
468     }
469 
470     /* Call the block pool performance info get function.  */
471     status =  tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
472 
473     /* Check for the proper error code.  */
474     if (status != TX_FEATURE_NOT_ENABLED)
475     {
476 
477         /* Block Pool error.  */
478         printf("ERROR #25\n");
479         test_control_return(1);
480     }
481 
482     /* Call the block pool performance info get function.  */
483     status =  tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
484 
485     /* Check for the proper error code.  */
486     if (status != TX_FEATURE_NOT_ENABLED)
487     {
488 
489         /* Block Pool error.  */
490         printf("ERROR #26\n");
491         test_control_return(1);
492     }
493 
494     /* Call the block pool performance info get function.  */
495     status =  tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
496 
497     /* Check for the proper error code.  */
498     if (status != TX_FEATURE_NOT_ENABLED)
499     {
500 
501         /* Block Pool error.  */
502         printf("ERROR #27\n");
503         test_control_return(1);
504     }
505 
506     /* Now get the system pool performance information.  */
507     status =  tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
508 
509     /* Check for the proper error code.  */
510     if (status != TX_FEATURE_NOT_ENABLED)
511     {
512 
513         /* Block Pool error.  */
514         printf("ERROR #28\n");
515         test_control_return(1);
516     }
517 
518     /* Now get the system pool performance information.  */
519     status =  tx_block_pool_performance_system_info_get(TX_NULL, &releases, &suspensions, &timeouts);
520 
521     /* Check for the proper error code.  */
522     if (status != TX_FEATURE_NOT_ENABLED)
523     {
524 
525         /* Block Pool error.  */
526         printf("ERROR #29\n");
527         test_control_return(1);
528     }
529 
530     /* Now get the system pool performance information.  */
531     status =  tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
532 
533     /* Check for the proper error code.  */
534     if (status != TX_FEATURE_NOT_ENABLED)
535     {
536 
537         /* Block Pool error.  */
538         printf("ERROR #30\n");
539         test_control_return(1);
540     }
541 
542     /* Now get the system pool performance information.  */
543     status =  tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
544 
545     /* Check for the proper error code.  */
546     if (status != TX_FEATURE_NOT_ENABLED)
547     {
548 
549         /* Block Pool error.  */
550         printf("ERROR #31\n");
551         test_control_return(1);
552     }
553 
554     /* Now get the system pool performance information.  */
555     status =  tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
556 
557     /* Check for the proper error code.  */
558     if (status != TX_FEATURE_NOT_ENABLED)
559     {
560 
561         /* Block Pool error.  */
562         printf("ERROR #32\n");
563         test_control_return(1);
564     }
565 
566     /* Successful test.  */
567     printf("SUCCESS!\n");
568     test_control_return(0);
569 #endif
570 }
571 
572 
thread_1_entry(ULONG thread_input)573 static void    thread_1_entry(ULONG thread_input)
574 {
575 UINT    status;
576 VOID    *pointer;
577 
578     /* Loop forever!  */
579     while(1)
580     {
581 
582 
583         /* Get block from pool.  */
584         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
585 
586         if (status != TX_SUCCESS)
587             break;
588 
589         /* Increment the thread counter.  */
590         thread_1_counter++;
591     }
592 }
593 
594 
thread_2_entry(ULONG thread_input)595 static void    thread_2_entry(ULONG thread_input)
596 {
597 
598 UINT    status;
599 VOID    *pointer;
600 
601 
602     /* Loop forever!  */
603     while(1)
604     {
605 
606 
607         /* Get block from pool.  */
608         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
609 
610         if (status != TX_SUCCESS)
611             break;
612 
613         /* Increment the thread counter.  */
614         thread_2_counter++;
615     }
616 }
617 
618 
thread_3_entry(ULONG thread_input)619 static void    thread_3_entry(ULONG thread_input)
620 {
621 
622 UINT    status;
623 VOID    *pointer;
624 
625 
626     /* Loop forever!  */
627     while(1)
628     {
629 
630 
631         /* Get block from pool.  */
632         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
633 
634         if (status != TX_SUCCESS)
635             break;
636 
637         /* Increment the thread counter.  */
638         thread_3_counter++;
639     }
640 }
641 
642 
thread_4_entry(ULONG thread_input)643 static void    thread_4_entry(ULONG thread_input)
644 {
645 
646 UINT    status;
647 VOID    *pointer;
648 
649 
650     /* Loop forever!  */
651     while(1)
652     {
653 
654 
655         /* Get block from pool.  */
656         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
657 
658         if (status != TX_SUCCESS)
659             break;
660 
661         /* Increment the thread counter.  */
662         thread_4_counter++;
663     }
664 }
665 
666 
thread_5_entry(ULONG thread_input)667 static void    thread_5_entry(ULONG thread_input)
668 {
669 
670 UINT    status;
671 VOID    *pointer;
672 
673 
674     /* Loop forever!  */
675     while(1)
676     {
677 
678 
679         /* Get block from pool.  */
680         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
681 
682         if (status != TX_SUCCESS)
683             break;
684 
685         /* Increment the thread counter.  */
686         thread_5_counter++;
687     }
688 }
689 
690 
thread_6_entry(ULONG thread_input)691 static void    thread_6_entry(ULONG thread_input)
692 {
693 
694 UINT    status;
695 VOID    *pointer;
696 
697 
698     /* Loop forever!  */
699     while(1)
700     {
701 
702 
703         /* Get block from pool.  */
704         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
705 
706         if (status != TX_SUCCESS)
707             break;
708 
709         /* Increment the thread counter.  */
710         thread_6_counter++;
711     }
712 }
713 
714