1 /* This test is designed to test suspension on memory block pools.  */
2 
3 #include   <stdio.h>
4 #include   "tx_api.h"
5 
6 static unsigned long   thread_0_counter =  0;
7 static TX_THREAD       thread_0;
8 static unsigned long   thread_1_counter =  0;
9 static TX_THREAD       thread_1;
10 static unsigned long   thread_2_counter =  0;
11 static TX_THREAD       thread_2;
12 
13 static TX_BLOCK_POOL   pool_0;
14 
15 
16 /* Define thread prototypes.  */
17 
18 static void    thread_0_entry(ULONG thread_input);
19 static void    thread_1_entry(ULONG thread_input);
20 static void    thread_2_entry(ULONG thread_input);
21 
22 
23 /* Prototype for test control return.  */
24 void  test_control_return(UINT status);
25 
26 
27 /* Define what the initial system looks like.  */
28 
29 #ifdef CTEST
test_application_define(void * first_unused_memory)30 void test_application_define(void *first_unused_memory)
31 #else
32 void    threadx_block_memory_suspension_application_define(void *first_unused_memory)
33 #endif
34 {
35 
36 UINT    status;
37 CHAR    *pointer;
38 
39 
40     /* Put first available memory address into a character pointer.  */
41     pointer =  (CHAR *) first_unused_memory;
42 
43     /* Put system definition stuff in here, e.g. thread creates and other assorted
44        create information.  */
45 
46     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
47             pointer, TEST_STACK_SIZE_PRINTF,
48             17, 17, 100, TX_AUTO_START);
49     pointer = pointer + TEST_STACK_SIZE_PRINTF;
50 
51     /* Check status.  */
52     if (status != TX_SUCCESS)
53     {
54 
55         printf("Running Block Memory Suspension Test................................ ERROR #1\n");
56         test_control_return(1);
57     }
58 
59     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
60             pointer, TEST_STACK_SIZE_PRINTF,
61             17, 17, 100, TX_AUTO_START);
62     pointer = pointer + TEST_STACK_SIZE_PRINTF;
63 
64     /* Check status.  */
65     if (status != TX_SUCCESS)
66     {
67 
68         printf("Running Block Memory Suspension Test................................ ERROR #2\n");
69         test_control_return(1);
70     }
71 
72     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
73             pointer, TEST_STACK_SIZE_PRINTF,
74             17, 17, 100, TX_DONT_START);
75     pointer = pointer + TEST_STACK_SIZE_PRINTF;
76 
77     /* Check status.  */
78     if (status != TX_SUCCESS)
79     {
80 
81         printf("Running Block Memory Suspension Test................................ ERROR #3\n");
82         test_control_return(1);
83     }
84 
85     /* Create block pool.  */
86     status =  tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
87     pointer = pointer + 320;
88 
89     /* Check status.  */
90     if (status != TX_SUCCESS)
91     {
92 
93         printf("Running Block Memory Suspension Test................................ ERROR #4\n");
94         test_control_return(1);
95     }
96 }
97 
98 
99 
100 /* Define the test threads.  */
101 
thread_0_entry(ULONG thread_input)102 static void    thread_0_entry(ULONG thread_input)
103 {
104 
105 UINT    status;
106 CHAR    *pointer_1;
107 CHAR    *pointer_2;
108 CHAR    *pointer_3;
109 
110 
111     /* Inform user.  */
112     printf("Running Block Memory Suspension Test................................ ");
113 
114     /* Increment the run counter.  */
115     thread_0_counter++;
116 
117     /* Allocate all blocks from the pool.  */
118     status =  tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
119 
120     /* Check status.  */
121     if (status != TX_SUCCESS)
122     {
123 
124         /* Block memory error.  */
125         printf("ERROR #5\n");
126         test_control_return(1);
127     }
128 
129     /* Set all the memory of the blocks.  */
130     TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
131 
132     status =  tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
133 
134     /* Check status.  */
135     if (status != TX_SUCCESS)
136     {
137 
138         /* Block memory error.  */
139         printf("ERROR #6\n");
140         test_control_return(1);
141     }
142 
143     /* Set all the memory of the blocks.  */
144     TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
145 
146     /* Get the last block.  */
147     status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
148 
149     /* Check status.  */
150     if (status != TX_SUCCESS)
151     {
152 
153         /* Block memory error.  */
154         printf("ERROR #6\n");
155         test_control_return(1);
156     }
157 
158     /* Set all the memory of the blocks.  */
159     TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
160 
161     /* Let the other thread suspend on the pool.  */
162     tx_thread_relinquish();
163 
164     /* Now release the block to lift the suspension on the other thread.  */
165     status =  tx_block_release(pointer_3);
166 
167     /* Check status and run counter.  */
168     if ((status != TX_SUCCESS) || (thread_1_counter != 0))
169     {
170 
171         /* Block memory error.  */
172         printf("ERROR #7\n");
173         test_control_return(1);
174     }
175 
176     /* Let the other thread run again.  */
177     tx_thread_relinquish();
178 
179     /* Check the run counter of the other thread.  */
180     if (thread_1_counter != 1)
181     {
182 
183         /* Block memory error.  */
184         printf("ERROR #8\n");
185         test_control_return(1);
186     }
187 
188     /* At this point the other thread has run and there is one block free.  */
189 
190     /* Get the last block again.  */
191     status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
192 
193     /* Check status.  */
194     if (status != TX_SUCCESS)
195     {
196 
197         /* Block memory error.  */
198         printf("ERROR #9\n");
199         test_control_return(1);
200     }
201 
202     /* Set all the memory of the blocks.  */
203     TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
204 
205     /* Resume the second thread.  */
206     tx_thread_resume(&thread_2);
207 
208     /* Let both threads suspend on the block pool via relinquish.  */
209     tx_thread_relinquish();
210 
211     /* Now release the block.  */
212     status =  tx_block_release(pointer_3);
213 
214     /* Check status and run counter.  */
215     if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0))
216     {
217 
218         /* Block memory error.  */
219         printf("ERROR #10\n");
220         test_control_return(1);
221     }
222 
223     /* Let thread 1 release the block.  */
224     tx_thread_relinquish();
225 
226     /* Let thread 2 get the block and release the block.  */
227     tx_thread_relinquish();
228 
229     /* Check status and run counter.  */
230     if ((thread_1_counter != 3) || (thread_2_counter != 1))
231     {
232 
233         /* Block memory error.  */
234         printf("ERROR #11\n");
235         test_control_return(1);
236     }
237     else
238     {
239         /* Successful test.  */
240         printf("SUCCESS!\n");
241         test_control_return(0);
242     }
243 }
244 
245 
thread_1_entry(ULONG thread_input)246 static void    thread_1_entry(ULONG thread_input)
247 {
248 
249 UINT    status;
250 CHAR    *pointer_1;
251 
252 
253     /* Attempt to get a block from the pool.  */
254     while(1)
255     {
256 
257         /* Allocate a block from the pool.  */
258         status =  tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
259 
260         /* Determine if the allocate was successful.  */
261         if (status != TX_SUCCESS)
262             return;
263 
264         /* Set all the memory of the blocks.  */
265         TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
266 
267         /* Increment the thread counter.  */
268         thread_1_counter++;
269 
270         /* Release the block.  */
271         tx_block_release(pointer_1);
272 
273         /* Switch back to other thread.  */
274         tx_thread_relinquish();
275     }
276 }
277 
278 
thread_2_entry(ULONG thread_input)279 static void    thread_2_entry(ULONG thread_input)
280 {
281 
282 UINT    status;
283 CHAR    *pointer_1;
284 
285 
286     /* Attempt to get a block from the pool.  */
287     while(1)
288     {
289 
290         /* Allocate a block from the pool.  */
291         status =  tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
292 
293         /* Determine if the allocate was successful.  */
294         if (status != TX_SUCCESS)
295             return;
296 
297         /* Set all the memory of the blocks.  */
298         TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
299 
300         /* Increment the thread counter.  */
301         thread_2_counter++;
302 
303         /* Release the block.  */
304         tx_block_release(pointer_1);
305 
306         /* Switch back to other thread.  */
307         tx_thread_relinquish();
308     }
309 }
310 
311 
312