1 /* This test is designed to test queue full suspension of queue that supports 3 messages
2    that are each 2 ULONG in size.  */
3 
4 #include   <stdio.h>
5 #include   "tx_api.h"
6 
7 static TX_THREAD       thread_0;
8 
9 static unsigned long   thread_1_counter =  0;
10 static TX_THREAD       thread_1;
11 
12 static unsigned long   thread_2_counter =  0;
13 static TX_THREAD       thread_2;
14 
15 static TX_QUEUE        queue_0;
16 
17 
18 static unsigned long   thread_1a_counter =  0;
19 static TX_THREAD       thread_1a;
20 
21 static unsigned long   thread_2a_counter =  0;
22 static TX_THREAD       thread_2a;
23 
24 static TX_QUEUE        queue_0a;
25 
26 
27 static ULONG           queue_area[3];
28 
29 
30 /* Define thread prototypes.  */
31 
32 static void    thread_0_entry(ULONG thread_input);
33 static void    thread_1_entry(ULONG thread_input);
34 static void    thread_2_entry(ULONG thread_input);
35 static void    thread_1a_entry(ULONG thread_input);
36 static void    thread_2a_entry(ULONG thread_input);
37 
38 
39 /* Prototype for test control return.  */
40 
41 void  test_control_return(UINT status);
42 
43 
queue_notify(TX_QUEUE * queue_ptr)44 static void    queue_notify(TX_QUEUE *queue_ptr)
45 {
46 
47 }
48 
49 
50 /* Define what the initial system looks like.  */
51 
52 #ifdef CTEST
test_application_define(void * first_unused_memory)53 void test_application_define(void *first_unused_memory)
54 #else
55 void    threadx_queue_full_suspension_application_define(void *first_unused_memory)
56 #endif
57 {
58 
59 UINT    status;
60 CHAR    *pointer;
61 
62 
63     /* Put first available memory address into a character pointer.  */
64     pointer =  (CHAR *) first_unused_memory;
65 
66     /* Put system definition stuff in here, e.g. thread creates and other assorted
67        create information.  */
68 
69     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
70             pointer, TEST_STACK_SIZE_PRINTF,
71             16, 16, 100, TX_AUTO_START);
72     pointer = pointer + TEST_STACK_SIZE_PRINTF;
73 
74     /* Check for status.  */
75     if (status != TX_SUCCESS)
76     {
77 
78         printf("Running Queue Full Suspension Test.................................. ERROR #1\n");
79         test_control_return(1);
80     }
81 
82     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
83             pointer, TEST_STACK_SIZE_PRINTF,
84             17, 16, 100, TX_DONT_START);
85     pointer = pointer + TEST_STACK_SIZE_PRINTF;
86     status +=  tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
87             pointer, TEST_STACK_SIZE_PRINTF,
88             17, 16, 100, TX_AUTO_START);
89     pointer = pointer + TEST_STACK_SIZE_PRINTF;
90 
91     /* Check for status.  */
92     if (status != TX_SUCCESS)
93     {
94 
95         printf("Running Queue Full Suspension Test.................................. ERROR #2\n");
96         test_control_return(1);
97     }
98 
99     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
100             pointer, TEST_STACK_SIZE_PRINTF,
101             16, 16, 100, TX_DONT_START);
102     pointer = pointer + TEST_STACK_SIZE_PRINTF;
103     status +=  tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
104             pointer, TEST_STACK_SIZE_PRINTF,
105             16, 16, 100, TX_DONT_START);
106     pointer = pointer + TEST_STACK_SIZE_PRINTF;
107 
108     /* Check for status.  */
109     if (status != TX_SUCCESS)
110     {
111 
112         printf("Running Queue Full Suspension Test.................................. ERROR #3\n");
113         test_control_return(1);
114     }
115 
116     /* Create the queue.  */
117     status =  tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
118     pointer = pointer + 3*2*sizeof(ULONG);
119     status +=  tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 3*1*sizeof(ULONG));
120     pointer = pointer + 3*1*sizeof(ULONG);
121 
122     /* Check for status.  */
123     if (status != TX_SUCCESS)
124     {
125 
126         printf("Running Queue Full Suspension Test.................................. ERROR #4\n");
127         test_control_return(1);
128     }
129 
130     /* Setup queue send notification.  */
131     status =  tx_queue_send_notify(&queue_0, queue_notify);
132 
133 #ifndef TX_DISABLE_NOTIFY_CALLBACKS
134 
135     /* Check for status.  */
136     if (status != TX_SUCCESS)
137     {
138 
139         printf("Running Queue Full Suspension Test.................................. ERROR #5\n");
140         test_control_return(1);
141     }
142 #else
143 
144     /* Check for status.  */
145     if (status != TX_FEATURE_NOT_ENABLED)
146     {
147 
148         printf("Running Queue Full Suspension Test.................................. ERROR #6\n");
149         test_control_return(1);
150     }
151 
152 #endif
153 
154 }
155 
156 
157 
158 /* Define the test threads.  */
159 
thread_0_entry(ULONG thread_input)160 static void    thread_0_entry(ULONG thread_input)
161 {
162 
163 UINT    status;
164 ULONG   source_message[2] = {0x12345678, 0};
165 ULONG   dest_message[2];
166 
167 
168     /* Inform user.  */
169     printf("Running Queue Full Suspension Test.................................. ");
170 
171     /* Perform the one word queue version.  */
172 
173     /* Suspend to get thread 1a to pend on the queue.  */
174     tx_thread_suspend(&thread_0);
175     status =  tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
176     tx_thread_suspend(&thread_0);
177     tx_thread_resume(&thread_1a);
178     tx_thread_resume(&thread_2a);
179     tx_queue_delete(&queue_0a);
180     status +=  tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, queue_area, sizeof(queue_area));
181 
182 
183     /* Fill the queue with an initial 3 messages!  */
184     status +=  tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
185     status +=  tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
186     status +=  tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
187     source_message[0]++;
188 
189     /* Receive two of the messages back to put the first received message at the end
190        of the queue.  */
191     status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
192     status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
193     status +=  tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
194     source_message[0]++;
195     status +=  tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
196     source_message[0]++;
197 
198     /* Check status and run count of other thread.  */
199     if ((status != TX_SUCCESS) || (thread_1a_counter != 0))
200     {
201 
202         /* Queue error.  */
203         printf("ERROR #6a\n");
204         test_control_return(1);
205     }
206 
207     /* Send message that should cause this thread to suspend, until the
208        lower priority thread receives a message.  */
209     status =  tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
210 
211     /* Check status and run count of other thread - it should have got the
212        message already even though its counter is still 0 (it was preempted
213        in the queue receive call.  */
214     if ((status != TX_SUCCESS) || (thread_1a_counter != 5) || (thread_2a_counter != 1))
215     {
216 
217         /* Queue error.  */
218         printf("ERROR #7a\n");
219         test_control_return(1);
220     }
221 
222     /* Perform the two word queue version.  */
223 
224     /* Reset the source message.  */
225     source_message[0] = 0x12345678;
226     source_message[1] = 0;
227 
228     /* Resume threads 1 and 2.  */
229     tx_thread_resume(&thread_1);
230     tx_thread_resume(&thread_2);
231 
232     /* Fill the queue with an initial 3 messages!  */
233     status =  tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
234     status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
235     status +=  tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
236     source_message[0]++;
237 
238     /* Receive two of the messages back to put the first received message at the end
239        of the queue.  */
240     status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
241     status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
242     status +=  tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
243     source_message[0]++;
244     status +=  tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
245     source_message[0]++;
246 
247     /* Check status and run count of other thread.  */
248     if ((status != TX_SUCCESS) || (thread_1_counter != 0))
249     {
250 
251         /* Queue error.  */
252         printf("ERROR #6\n");
253         test_control_return(1);
254     }
255 
256     /* Send message that should cause this thread to suspend, until the
257        lower priority thread receives a message.  */
258     status =  tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
259 
260     /* Check status and run count of other thread - it should have got the
261        message already even though its counter is still 0 (it was preempted
262        in the queue receive call.  */
263     if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 1))
264     {
265 
266         /* Queue error.  */
267         printf("ERROR #7\n");
268         test_control_return(1);
269     }
270     else
271     {
272 
273         /* Successful test.  */
274         printf("SUCCESS!\n");
275         test_control_return(0);
276     }
277 }
278 
279 
thread_1_entry(ULONG thread_input)280 static void    thread_1_entry(ULONG thread_input)
281 {
282 UINT    status;
283 ULONG   expected_message[2] = {0x12345678, 0};
284 ULONG   dest_message[2];
285 UINT    old_priority;
286 
287 
288     /* Loop forever!  */
289     while(1)
290     {
291 
292         /* Receive messages and suspend.  */
293         status =  tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
294 
295         if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
296             break;
297 
298         /* Change thread 2 priority.  */
299         tx_thread_priority_change(&thread_2, 15, &old_priority);
300 
301         /* Increment the thread counter.  */
302         thread_1_counter++;
303     }
304 }
305 
306 
thread_2_entry(ULONG thread_input)307 static void    thread_2_entry(ULONG thread_input)
308 {
309 
310 ULONG   source_message[2] = {0x1234567C, 0};
311 
312 
313     /* Send one message to the queue.  */
314     tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
315 
316     /* Increment the thread counter.  */
317     thread_2_counter++;
318 }
319 
320 
thread_1a_entry(ULONG thread_input)321 static void    thread_1a_entry(ULONG thread_input)
322 {
323 UINT    status;
324 ULONG   expected_message[2] = {0x12345678, 0};
325 ULONG   dest_message[2];
326 UINT    old_priority;
327 
328 
329    /* Receive message and suspend.  */
330    status = tx_thread_resume(&thread_0);
331    status += tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
332    status += tx_thread_resume(&thread_0);
333    status += tx_thread_suspend(&thread_1a);
334 
335    if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]))
336        return;
337 
338     /* Loop forever!  */
339     while(1)
340     {
341 
342         /* Receive messages and suspend.  */
343         status =  tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
344 
345         if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
346             break;
347 
348         /* Change thread 2a priority.  */
349         tx_thread_priority_change(&thread_2a, 15, &old_priority);
350 
351         /* Increment the thread counter.  */
352         thread_1a_counter++;
353     }
354 }
355 
356 
thread_2a_entry(ULONG thread_input)357 static void    thread_2a_entry(ULONG thread_input)
358 {
359 
360 ULONG   source_message[2] = {0x1234567C, 0};
361 
362 
363     /* Send one message to the queue.  */
364     tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
365 
366     /* Increment the thread counter.  */
367     thread_2a_counter++;
368 }
369