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