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