1 /* This test is designed to test simple memory block pool creation, deletion, and
2    allocates and releases.  */
3 
4 #include   <stdio.h>
5 #include   "tx_api.h"
6 
7 typedef struct BLOCK_MEMORY_TEST_STRUCT
8 {
9     ULONG           first;
10     ULONG           second;
11     TX_BLOCK_POOL   pool;
12     ULONG           first_middle;
13     ULONG           second_middle;
14     ULONG           pool_area[2048/sizeof(ULONG)];
15     ULONG           next_to_last;
16     ULONG           last;
17 
18 } BLOCK_MEMORY_TEST;
19 
20 static  BLOCK_MEMORY_TEST   block_memory;
21 
22 
23 /* Define external reference for status of block pool create from initialization.  */
24 
25 extern UINT            test_block_pool_create_init;
26 
27 
28 /* Define the ISR dispatch.  */
29 
30 extern VOID    (*test_isr_dispatch)(void);
31 
32 
33 static TX_THREAD       thread_0;
34 static TX_THREAD       thread_1;
35 
36 
37 static TX_BLOCK_POOL   pool_0;
38 static TX_BLOCK_POOL   pool_1;
39 static TX_BLOCK_POOL   pool_2;
40 static TX_BLOCK_POOL   pool_3;
41 
42 static TX_TIMER        timer_0;
43 
44 
45 static unsigned long error =  0;
46 static unsigned long timer_executed =  0;
47 static unsigned long isr_executed =  0;
48 
49 
50 /* Define thread prototypes.  */
51 
52 static void    thread_0_entry(ULONG thread_input);
53 static void    thread_1_entry(ULONG thread_input);
54 
55 
56 /* Prototype for test control return.  */
57 
58 void  test_control_return(UINT status);
59 
60 
61 /* Prototype direct call to block pool core service.  */
62 
63 UINT  _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
64                     VOID *pool_start, ULONG pool_size);
65 
66 
67 
68 /* Define the timer for this test.  */
69 
timer_entry(ULONG i)70 static void    timer_entry(ULONG i)
71 {
72 
73 #ifndef TX_DISABLE_ERROR_CHECKING
74 
75 UINT    status;
76 CHAR    *pointer;
77 
78 
79     /* Determine if calling block pool create from initialization was successful.  */
80     if (test_block_pool_create_init != TX_SUCCESS)
81     {
82 
83         /* Error!  */
84         error++;
85     }
86 
87     /* Attempt to create a block pool from a timer.  */
88     pointer =  (CHAR *) 0x30000;
89     status =  tx_block_pool_create(&pool_3, "pool 3", 100, pointer, 320);
90 
91         /* Check status.  */
92     if (status != TX_CALLER_ERROR)
93     {
94 
95         /* Error!  */
96         error++;
97     }
98 
99     /* Attempt to delete a block pool.  */
100     status =  tx_block_pool_delete(&pool_0);
101 
102         /* Check status.  */
103     if (status != TX_CALLER_ERROR)
104     {
105 
106         /* Error!  */
107         error++;
108     }
109 
110     timer_executed =  1;
111 
112     /* Attempt to allocate a block with suspension from a timer.  */
113     status =  tx_block_allocate(&pool_0, (void **) &pointer, 10);
114 
115     /* Check status.  */
116     if (status != TX_WAIT_ERROR)
117     {
118 
119         /* Error!  */
120         error++;
121     }
122 
123 #endif
124 }
125 
126 /* Define the ISR dispatch routine.  */
127 
test_isr(void)128 static void    test_isr(void)
129 {
130 
131 #ifndef TX_DISABLE_ERROR_CHECKING
132 
133 CHAR    *pointer;
134 UINT    status;
135 
136 
137     /* Attempt to Allocate block from the pool.  */
138     status = tx_block_allocate(&pool_0, (VOID **) &pointer, TX_WAIT_FOREVER);
139 
140     /* Check status.  */
141     if (status != TX_WAIT_ERROR)
142     {
143 
144         /* Error!  */
145         error++;
146     }
147 
148     /* Attempt to create a block pool from an ISR.  */
149     status =  tx_block_pool_create(&pool_3, "pool 3", 100, (void *) 0x100000, 320);
150 
151     /* Check status.  */
152     if (status != TX_CALLER_ERROR)
153     {
154 
155         /* Error!  */
156         error++;
157     }
158 
159     /* Attempt to delete a pool from an ISR.  */
160     status =  tx_block_pool_delete(&pool_0);
161 
162     if (status != TX_CALLER_ERROR)
163     {
164 
165         /* Error!  */
166         error++;
167     }
168 
169     isr_executed =  1;
170 #endif
171 }
172 
173 
174 /* Define what the initial system looks like.  */
175 
176 #ifdef CTEST
test_application_define(void * first_unused_memory)177 void test_application_define(void *first_unused_memory)
178 #else
179 void    threadx_block_memory_basic_application_define(void *first_unused_memory)
180 #endif
181 {
182 
183 UINT    status;
184 CHAR    *pointer;
185 
186 
187     /* Put first available memory address into a character pointer.  */
188     pointer =  (CHAR *) first_unused_memory;
189 
190     /* Put system definition stuff in here, e.g. thread creates and other assorted
191        create information.  */
192 
193     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
194             pointer, TEST_STACK_SIZE_PRINTF,
195             17, 17, 100, TX_AUTO_START);
196     pointer = pointer + TEST_STACK_SIZE_PRINTF;
197 
198     /* Check status.  */
199     if (status != TX_SUCCESS)
200     {
201 
202         printf("Running Block Memory Basic Functionality Test....................... ERROR #1\n");
203         test_control_return(1);
204     }
205 
206     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
207             pointer, TEST_STACK_SIZE_PRINTF,
208             18, 18, 100, TX_DONT_START);
209     pointer = pointer + TEST_STACK_SIZE_PRINTF;
210 
211     /* Check status.  */
212     if (status != TX_SUCCESS)
213     {
214 
215         printf("Running Block Memory Basic Functionality Test....................... ERROR #2\n");
216         test_control_return(1);
217     }
218 
219     /* Create block pools 0 and 1.  */
220     status =  tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
221     pointer = pointer + 320;
222 
223     /* Check status.  */
224     if (status != TX_SUCCESS)
225     {
226 
227         printf("Running Block Memory Basic Functionality Test....................... ERROR #3\n");
228         test_control_return(1);
229     }
230 
231     status =  tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
232     pointer = pointer + 320;
233 
234     /* Check status.  */
235     if (status != TX_SUCCESS)
236     {
237 
238         printf("Running Block Memory Basic Functionality Test....................... ERROR #4\n");
239         test_control_return(1);
240     }
241 
242     /* Check the no-blocks path.  */
243     status =  _tx_block_pool_create(&pool_2, "pool 2", 100, pointer, 50);
244     pointer = pointer + 320;
245 
246     /* Check status.  */
247     if (status != TX_SIZE_ERROR)
248     {
249 
250         printf("Running Block Memory Basic Functionality Test....................... ERROR #5\n");
251         test_control_return(1);
252     }
253 }
254 
255 
256 
257 /* Define the test threads.  */
258 
thread_0_entry(ULONG thread_input)259 static void    thread_0_entry(ULONG thread_input)
260 {
261 
262 UINT    status;
263 CHAR    *pointer_1;
264 CHAR    *pointer_2;
265 CHAR    *pointer_3;
266 CHAR    *pointer_4;
267 INT      i;
268 unsigned long fake_block[20];
269 
270 
271     /* Inform user.  */
272     printf("Running Block Memory Basic Functionality Test....................... ");
273 
274     /* Perform block memory test.  */
275     block_memory.first =        0x11223344;
276     block_memory.second =       0x55667788;
277     block_memory.first_middle = 0x21314151;
278     block_memory.second_middle= 0x61718191;
279     block_memory.next_to_last = 0x99aabbcc;
280     block_memory.last =         0xddeeff00;
281 
282     /* Create the block pool.  */
283     status =  tx_block_pool_create(&block_memory.pool, "pool memory", 16, &block_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
284     tx_block_pool_delete(&block_memory.pool);
285 
286     /* Check for status.  */
287     if ((status != TX_SUCCESS) ||
288         (block_memory.first != 0x11223344) ||
289         (block_memory.second != 0x55667788) ||
290         (block_memory.first_middle != 0x21314151) ||
291         (block_memory.second_middle != 0x61718191) ||
292         (block_memory.next_to_last != 0x99aabbcc) ||
293         (block_memory.last != 0xddeeff00))
294     {
295 
296         /* Block memory error.  */
297         printf("ERROR #6\n");
298         test_control_return(1);
299     }
300 
301 #ifndef TX_DISABLE_ERROR_CHECKING
302 
303     /* Try to release a non-block.  */
304     fake_block[0] =  0;
305     fake_block[1] =  0;
306     status =  tx_block_release(&fake_block[2]);
307 
308     /* Check status.  */
309     if (status != TX_PTR_ERROR)
310     {
311 
312         /* Block memory error.  */
313         printf("ERROR #7\n");
314         test_control_return(1);
315     }
316 
317     /* Try to release a block that points to a non-pool.  */
318     fake_block[0] =  0;
319     fake_block[1] =  (unsigned long) &fake_block[0];
320     status =  tx_block_release(&fake_block[2]);
321 
322     /* Check status.  */
323     if (status != TX_PTR_ERROR)
324     {
325 
326         /* Block memory error.  */
327         printf("ERROR #8\n");
328         test_control_return(1);
329     }
330 #endif
331 
332     /* Allocate first block from the pool.  */
333     status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
334 
335     /* Check status.  */
336     if (status != TX_SUCCESS)
337     {
338 
339         /* Block memory error.  */
340         printf("ERROR #9\n");
341         test_control_return(1);
342     }
343 
344     /* Set all the memory of the blocks.  */
345     TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
346 
347     /* Allocate second block from the pool.  */
348     status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
349 
350     /* Check status.  */
351     if (status != TX_SUCCESS)
352     {
353 
354         /* Block memory error.  */
355         printf("ERROR #10\n");
356         test_control_return(1);
357     }
358 
359     /* Set all the memory of the blocks.  */
360     TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
361 
362     /* Allocate third block from the pool.  */
363     status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
364 
365     /* Check status.  */
366     if (status != TX_SUCCESS)
367     {
368 
369         /* Block memory error.  */
370         printf("ERROR #11\n");
371         test_control_return(1);
372     }
373 
374     /* Set all the memory of the blocks.  */
375     TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
376 
377     /* Attempt to allocate fourth block from the pool.  This should fail because
378        there should be no more blocks in the pool.  */
379     status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
380 
381     /* Check status.  */
382     if (status != TX_NO_MEMORY)
383     {
384 
385         /* Block memory error.  */
386         printf("ERROR ##12\n");
387         test_control_return(1);
388     }
389 
390     /* Set the memory of all of the allocated blocks.  */
391     for (i =0; i < 100; i++)
392     {
393         pointer_1[i] = (CHAR) 0xFF;
394         pointer_2[i] = (CHAR) 0xFF;
395         pointer_3[i] = (CHAR) 0xFF;
396     }
397 
398     /* Now release each of the blocks. */
399     status =  tx_block_release(pointer_1);
400 
401     /* Check for status.  */
402     if (status != TX_SUCCESS)
403     {
404 
405         /* Block memory error.  */
406         printf("ERROR #13\n");
407         test_control_return(1);
408     }
409 
410     /* Release the second block.  */
411     status =  tx_block_release(pointer_2);
412 
413     /* Check for status.  */
414     if (status != TX_SUCCESS)
415     {
416 
417         /* Block memory error.  */
418         printf("ERROR #14\n");
419         test_control_return(1);
420     }
421 
422     /* Release the third block.  */
423     status =  tx_block_release(pointer_3);
424 
425     /* Check for status.  */
426     if (status != TX_SUCCESS)
427     {
428 
429         /* Block memory error.  */
430         printf("ERROR #15\n");
431         test_control_return(1);
432     }
433 
434     /* Allocate each block again to make sure everything still
435        works.  The block addresses should come out in reverse
436        order, because a released block is placed at the head of
437        the list.  */
438 
439     /* Allocate first block from the pool.  */
440     status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
441 
442     /* Check status.  */
443     if (status != TX_SUCCESS)
444     {
445 
446         /* Block memory error.  */
447         printf("ERROR #16\n");
448         test_control_return(1);
449     }
450 
451     /* Set all the memory of the blocks.  */
452     TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
453 
454     /* Allocate second block from the pool.  */
455     status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
456 
457     /* Check status.  */
458     if (status != TX_SUCCESS)
459     {
460 
461         /* Block memory error.  */
462         printf("ERROR #17\n");
463         test_control_return(1);
464     }
465 
466     /* Set all the memory of the blocks.  */
467     TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
468 
469     /* Allocate third block from the pool.  */
470     status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
471 
472     /* Check status.  */
473     if (status != TX_SUCCESS)
474     {
475 
476         /* Block memory error.  */
477         printf("ERROR #18\n");
478         test_control_return(1);
479     }
480 
481     /* Set all the memory of the blocks.  */
482     TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
483 
484     /* Attempt to allocate fourth block from the pool.  This should fail because
485        there should be no more blocks in the pool.  */
486     status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
487 
488     /* Check status.  */
489     if (status != TX_NO_MEMORY)
490     {
491 
492         /* Block memory error.  */
493         printf("ERROR #19\n");
494         test_control_return(1);
495     }
496 
497 #ifndef TX_DISABLE_ERROR_CHECKING
498 
499     /* Create a timer for the test.  */
500     tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
501 
502     /* Setup the ISR.  */
503     test_isr_dispatch =  test_isr;
504 
505     /* Sleep for a bit...  */
506     tx_thread_sleep(3);
507 
508     /* Now resume the background thread.  */
509     tx_thread_resume(&thread_1);
510 
511     /* Sleep for a bit...  */
512     tx_thread_sleep(3);
513 
514     /* Clear the ISR.  */
515     test_isr_dispatch =  TX_NULL;
516 
517     /* Test for error.  */
518     if ((error) || (timer_executed != 1) || (isr_executed != 1))
519     {
520 
521         /* Block memory error.  */
522         printf("ERROR #20\n");
523         test_control_return(1);
524     }
525 
526 #endif
527 
528     /* Delete both block pools.  */
529     status =  tx_block_pool_delete(&pool_0);
530 
531     /* Check status.  */
532     if (status != TX_SUCCESS)
533     {
534 
535         /* Block memory error.  */
536         printf("ERROR #21\n");
537         test_control_return(1);
538     }
539 
540     status =  tx_block_pool_delete(&pool_1);
541 
542     /* Check status.  */
543     if ((status != TX_SUCCESS) || (error))
544     {
545 
546         /* Block memory error.  */
547         printf("ERROR #22\n");
548         test_control_return(1);
549     }
550     else
551     {
552 
553         /* Successful test.  */
554         printf("SUCCESS!\n");
555         test_control_return(0);
556     }
557 }
558 
559 
thread_1_entry(ULONG thread_input)560 static void    thread_1_entry(ULONG thread_input)
561 {
562 
563     while(1)
564     {
565 
566         tx_thread_relinquish();
567     }
568 }
569