1 /* This test is designed to test block memory pool 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 
18 static unsigned long   thread_0_counter =  0;
19 static TX_THREAD       thread_0;
20 
21 static unsigned long   thread_1_counter =  0;
22 static TX_THREAD       thread_1;
23 
24 static unsigned long   thread_2_counter =  0;
25 static TX_THREAD       thread_2;
26 
27 static unsigned long   thread_3_counter =  0;
28 static TX_THREAD       thread_3;
29 
30 static unsigned long   thread_4_counter =  0;
31 static TX_THREAD       thread_4;
32 
33 static unsigned long   thread_5_counter =  0;
34 static TX_THREAD       thread_5;
35 
36 static unsigned long   thread_6_counter =  0;
37 static TX_THREAD       thread_6;
38 
39 static TX_BLOCK_POOL   block_pool_0;
40 static TX_BLOCK_POOL   block_pool_1;
41 
42 
43 static int             test_status;
44 
45 
46 /* Define thread prototypes.  */
47 
48 static void    thread_0_entry(ULONG thread_input);
49 static void    thread_1_entry(ULONG thread_input);
50 static void    thread_2_entry(ULONG thread_input);
51 static void    thread_3_entry(ULONG thread_input);
52 static void    thread_4_entry(ULONG thread_input);
53 static void    thread_5_entry(ULONG thread_input);
54 static void    thread_6_entry(ULONG thread_input);
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 (block_pool_0.tx_block_pool_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_block_memory_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             17, 17, 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 Block Memory 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             16, 16, 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 Block Memory Prioritize Test................................ ERROR #2\n");
133         test_control_return(1);
134     }
135 
136     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
137             pointer, TEST_STACK_SIZE_PRINTF,
138             15, 15, 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 Block Memory 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 Block Memory 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 Block Memory 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 Block Memory 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 Block Memory Prioritize Test................................ ERROR #7\n");
198         test_control_return(1);
199     }
200 
201     /* Create the block_pool with one block.  */
202     status =  tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
203     pointer = pointer + 40;
204 
205     /* Check for status.  */
206     if (status != TX_SUCCESS)
207     {
208 
209         printf("Running Block Memory Prioritize Test................................ ERROR #8\n");
210         test_control_return(1);
211     }
212 }
213 
214 
215 
216 /* Define the test threads.  */
217 
thread_0_entry(ULONG thread_input)218 static void    thread_0_entry(ULONG thread_input)
219 {
220 
221 UINT    status;
222 VOID    *pointer;
223 
224 
225     /* Inform user.  */
226     printf("Running Block Memory Prioritize Test................................ ");
227 
228 #ifndef TX_DISABLE_ERROR_CHECKING
229 
230     /* Attempt to prioritize with a NULL pointer.  */
231     status =  tx_block_pool_prioritize(TX_NULL);
232 
233     /* Check for an error condition.   */
234     if (status != TX_POOL_ERROR)
235     {
236 
237         /* Block Pool error.  */
238         printf("ERROR #9\n");
239         test_control_return(1);
240     }
241 
242     /* Attempt to prioritize with a bad pool pointer.  */
243     block_pool_1.tx_block_pool_id =  0;
244     status =  tx_block_pool_prioritize(&block_pool_1);
245 
246     /* Check for an error condition.   */
247     if (status != TX_POOL_ERROR)
248     {
249 
250         /* Block Pool error.  */
251         printf("ERROR #10\n");
252         test_control_return(1);
253     }
254 #endif
255 
256     /* Allocate the one block.  */
257     tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
258 
259     /* Nothing to do here, but check prioritization with no suspended threads.  */
260     status =  tx_block_pool_prioritize(&block_pool_0);
261 
262     /* Check for an error condition.   */
263     if (status != TX_SUCCESS)
264     {
265 
266         /* Block Pool error.  */
267         printf("ERROR #11\n");
268         test_control_return(1);
269     }
270 
271     /* Get both threads suspended.  */
272     tx_thread_resume(&thread_1);
273     tx_thread_resume(&thread_2);
274 
275     /* Increment the thread counter.  */
276     thread_0_counter++;
277 
278     /* Make sure thread 1 and 2 are suspended on the block_pool.  */
279     if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
280         (block_pool_0.tx_block_pool_suspension_list != &thread_1))
281     {
282 
283         /* Block Pool error.  */
284         printf("ERROR #12\n");
285         test_control_return(1);
286     }
287 
288     /* Prioritize the block pool suspension list.  */
289     status =  tx_block_pool_prioritize(&block_pool_0);
290 
291     /* Check status and make sure thread 2 is at the front of the suspension list.  */
292     if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
293     {
294 
295         /* Block Pool error.  */
296         printf("ERROR #13\n");
297         test_control_return(1);
298     }
299 
300     /* Call block pool prioritize again to test the don't-do-anything path in tx_block_pool_prioritize.  */
301     status +=  tx_block_pool_prioritize(&block_pool_0);
302 
303     /* At this point we are going to get more than 2 threads suspended.  */
304     tx_thread_resume(&thread_1);
305     tx_thread_resume(&thread_2);
306     tx_thread_resume(&thread_3);
307     tx_thread_resume(&thread_4);
308     tx_thread_resume(&thread_5);
309     tx_thread_resume(&thread_6);
310 
311     /* Prioritize the block pool suspension list.  */
312     status =  tx_block_pool_prioritize(&block_pool_0);
313 
314     /* Check status and make sure thread 3 is at the front of the suspension list.  */
315     if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
316     {
317 
318         /* Block Pool error.  */
319         printf("ERROR #14\n");
320         test_control_return(1);
321     }
322 
323     /* Now loop to test the interrupt of the prioritize loop logic.  */
324     test_status =  1;
325     test_isr_dispatch =  test_isr;
326     do
327     {
328 
329         /* Prioritize the block pool suspension list.  */
330         status =  tx_block_pool_prioritize(&block_pool_0);
331 
332         /* Check status and make sure thread 1 is terminated.  */
333         if (status != TX_SUCCESS)
334         {
335 
336             /* Block Pool error.  */
337             printf("ERROR #15\n");
338             test_control_return(1);
339         }
340 
341     } while (test_status == 1);
342 
343     /* Now determine if thread 4 is at the front of the list... It should be!  */
344     if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
345     {
346 
347         /* Block Pool error.  */
348         printf("ERROR #16\n");
349         test_control_return(1);
350     }
351     else
352     {
353 
354         /* Successful test.  */
355         printf("SUCCESS!\n");
356         test_control_return(0);
357     }
358 }
359 
360 
thread_1_entry(ULONG thread_input)361 static void    thread_1_entry(ULONG thread_input)
362 {
363 UINT    status;
364 VOID    *pointer;
365 
366     /* Loop forever!  */
367     while(1)
368     {
369 
370 
371         /* Get block from pool.  */
372         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
373 
374         if (status != TX_SUCCESS)
375             break;
376 
377         /* Increment the thread counter.  */
378         thread_1_counter++;
379     }
380 }
381 
382 
thread_2_entry(ULONG thread_input)383 static void    thread_2_entry(ULONG thread_input)
384 {
385 
386 UINT    status;
387 VOID    *pointer;
388 
389 
390     /* Loop forever!  */
391     while(1)
392     {
393 
394 
395         /* Get block from pool.  */
396         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
397 
398         if (status != TX_SUCCESS)
399             break;
400 
401         /* Increment the thread counter.  */
402         thread_2_counter++;
403     }
404 }
405 
406 
thread_3_entry(ULONG thread_input)407 static void    thread_3_entry(ULONG thread_input)
408 {
409 
410 UINT    status;
411 VOID    *pointer;
412 
413 
414     /* Loop forever!  */
415     while(1)
416     {
417 
418 
419         /* Get block from pool.  */
420         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
421 
422         if (status != TX_SUCCESS)
423             break;
424 
425         /* Increment the thread counter.  */
426         thread_3_counter++;
427     }
428 }
429 
430 
thread_4_entry(ULONG thread_input)431 static void    thread_4_entry(ULONG thread_input)
432 {
433 
434 UINT    status;
435 VOID    *pointer;
436 
437 
438     /* Loop forever!  */
439     while(1)
440     {
441 
442 
443         /* Get block from pool.  */
444         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
445 
446         if (status != TX_SUCCESS)
447             break;
448 
449         /* Increment the thread counter.  */
450         thread_4_counter++;
451     }
452 }
453 
454 
thread_5_entry(ULONG thread_input)455 static void    thread_5_entry(ULONG thread_input)
456 {
457 
458 UINT    status;
459 VOID    *pointer;
460 
461 
462     /* Loop forever!  */
463     while(1)
464     {
465 
466 
467         /* Get block from pool.  */
468         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
469 
470         if (status != TX_SUCCESS)
471             break;
472 
473         /* Increment the thread counter.  */
474         thread_5_counter++;
475     }
476 }
477 
478 
thread_6_entry(ULONG thread_input)479 static void    thread_6_entry(ULONG thread_input)
480 {
481 
482 UINT    status;
483 VOID    *pointer;
484 
485 
486     /* Loop forever!  */
487     while(1)
488     {
489 
490 
491         /* Get block from pool.  */
492         status =  tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
493 
494         if (status != TX_SUCCESS)
495             break;
496 
497         /* Increment the thread counter.  */
498         thread_6_counter++;
499     }
500 }
501