1 /* This test is designed to test empty queue 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 unsigned long   thread_0_counter =  0;
8 static TX_THREAD       thread_0;
9 
10 static unsigned long   thread_1_counter =  0;
11 static TX_THREAD       thread_1;
12 
13 static unsigned long   thread_2_counter =  0;
14 static TX_THREAD       thread_2;
15 
16 static TX_QUEUE        queue_0;
17 static TX_QUEUE        queue_1;
18 
19 
20 /* Define thread prototypes.  */
21 
22 static void    thread_0_entry(ULONG thread_input);
23 static void    thread_1_entry(ULONG thread_input);
24 static void    thread_2_entry(ULONG thread_input);
25 
26 
27 /* Prototype for test control return.  */
28 
29 void  test_control_return(UINT status);
30 
31 
queue_notify(TX_QUEUE * queue_ptr)32 static void    queue_notify(TX_QUEUE *queue_ptr)
33 {
34 
35 }
36 
37 
38 /* Define what the initial system looks like.  */
39 
40 #ifdef CTEST
test_application_define(void * first_unused_memory)41 void test_application_define(void *first_unused_memory)
42 #else
43 void    threadx_queue_empty_suspension_application_define(void *first_unused_memory)
44 #endif
45 {
46 
47 UINT    status;
48 CHAR    *pointer;
49 
50 
51     /* Put first available memory address into a character pointer.  */
52     pointer =  (CHAR *) first_unused_memory;
53 
54     /* Put system definition stuff in here, e.g. thread creates and other assorted
55        create information.  */
56 
57     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
58             pointer, TEST_STACK_SIZE_PRINTF,
59             16, 16, 100, TX_AUTO_START);
60     pointer = pointer + TEST_STACK_SIZE_PRINTF;
61 
62     /* Check for status.  */
63     if (status != TX_SUCCESS)
64     {
65 
66         printf("Running Queue Empty Suspension Test................................. ERROR #1\n");
67         test_control_return(1);
68     }
69 
70     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
71             pointer, TEST_STACK_SIZE_PRINTF,
72             15, 15, 100, TX_AUTO_START);
73     pointer = pointer + TEST_STACK_SIZE_PRINTF;
74 
75     /* Check for status.  */
76     if (status != TX_SUCCESS)
77     {
78 
79         printf("Running Queue Empty Suspension Test................................. ERROR #2\n");
80         test_control_return(1);
81     }
82 
83     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
84             pointer, TEST_STACK_SIZE_PRINTF,
85             15, 15, 100, TX_DONT_START);
86     pointer = pointer + TEST_STACK_SIZE_PRINTF;
87 
88     /* Check for status.  */
89     if (status != TX_SUCCESS)
90     {
91 
92         printf("Running Queue Empty Suspension Test................................. ERROR #3\n");
93         test_control_return(1);
94     }
95 
96     /* Create the queue.  */
97     status =  tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
98     pointer = pointer + 3*2*sizeof(ULONG);
99 
100     /* Check for status.  */
101     if (status != TX_SUCCESS)
102     {
103 
104         printf("Running Queue Empty Suspension Test................................. ERROR #4\n");
105         test_control_return(1);
106     }
107 
108     /* Setup queue send notification.  */
109     status =  tx_queue_send_notify(&queue_0, queue_notify);
110 
111 #ifndef TX_DISABLE_NOTIFY_CALLBACKS
112 
113     /* Check for status.  */
114     if (status != TX_SUCCESS)
115     {
116 
117         printf("Running Queue Empty Suspension Test................................. ERROR #5\n");
118         test_control_return(1);
119     }
120 
121 #else
122 
123     /* Check for status.  */
124     if (status != TX_FEATURE_NOT_ENABLED)
125     {
126 
127         printf("Running Queue Empty Suspension Test................................. ERROR #6\n");
128         test_control_return(1);
129     }
130 
131 #endif
132 }
133 
134 
135 
136 /* Define the test threads.  */
137 
thread_0_entry(ULONG thread_input)138 static void    thread_0_entry(ULONG thread_input)
139 {
140 
141 UINT    status;
142 ULONG   source_message[2] = {0x12345678, 0};
143 
144 
145     /* Inform user.  */
146     printf("Running Queue Empty Suspension Test................................. ");
147 
148     /* Increment the thread counter.  */
149     thread_0_counter++;
150 
151 #ifndef TX_DISABLE_ERROR_CHECKING
152 
153     /* Attempt to setup notify on a non-queue.  */
154     status =  tx_queue_send_notify(TX_NULL, queue_notify);
155 
156     /* Check status.  */
157     if (status != TX_QUEUE_ERROR)
158     {
159 
160         /* Queue error.  */
161         printf("ERROR #7\n");
162         test_control_return(1);
163     }
164 
165     /* Attempt to setup notify on a non-created queue.  */
166     queue_1.tx_queue_id =  0;
167     status =  tx_queue_send_notify(&queue_1, queue_notify);
168 
169     /* Check status.  */
170     if (status != TX_QUEUE_ERROR)
171     {
172 
173         /* Queue error.  */
174         printf("ERROR #8\n");
175         test_control_return(1);
176     }
177 #endif
178 
179     /* Send message that should go directly into the the other thread's
180        destination area!  We should also preempt and the queue should
181        be empty by the next time we get around!  */
182     status =  tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
183 
184     /* Check status and run count of other thread - it should have got the
185        message already.  */
186     if ((status != TX_SUCCESS) || (thread_1_counter != 1))
187     {
188 
189         /* Queue error.  */
190         printf("ERROR #9\n");
191         test_control_return(1);
192     }
193 
194     /* Now resume thread 2 to get another thread suspended on an empty queue.  */
195     tx_thread_resume(&thread_2);
196 
197     /* Now send 2 messages to wakeup both threads!  */
198     source_message[0]++;
199     status =  tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
200     status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
201 
202     /* Check status and run count of other thread - it should have got the
203        message already.  */
204     if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_2_counter != 1))
205     {
206 
207         /* Queue error.  */
208         printf("ERROR #10\n");
209         test_control_return(1);
210     }
211     else
212     {
213 
214         /* Successful test.  */
215         printf("SUCCESS!\n");
216         test_control_return(0);
217     }
218 }
219 
220 
thread_1_entry(ULONG thread_input)221 static void    thread_1_entry(ULONG thread_input)
222 {
223 
224 UINT    status;
225 ULONG   expected_message[2] = {0x12345678, 0};
226 ULONG   dest_message[2];
227 
228 
229     /* Loop forever!  */
230     while(1)
231     {
232 
233 
234         /* Receive message from empty queue with suspension.  We should always
235            suspend until thread 0 executes.  */
236         status =  tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
237 
238         if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
239             break;
240 
241         /* Increment the thread counter.  */
242         thread_1_counter++;
243     }
244 }
245 
246 
thread_2_entry(ULONG thread_input)247 static void    thread_2_entry(ULONG thread_input)
248 {
249 
250 UINT    status;
251 ULONG   expected_message[2] = {0x12345679, 0};
252 ULONG   dest_message[2];
253 
254 
255     /* Loop forever!  */
256     while(1)
257     {
258 
259 
260         /* Receive message from empty queue with suspension.  We should always
261            suspend until thread 0 executes.  */
262         status =  tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
263 
264         if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
265             break;
266 
267         /* Increment the thread counter.  */
268         thread_2_counter++;
269     }
270 }
271 
272