1 /* This test is designed to test event flag suspension with a single suspended thread
2    being terminated at the same priority level.  */
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 static unsigned long   thread_1_counter =  0;
10 static TX_THREAD       thread_1;
11 static unsigned long   thread_2_counter =  0;
12 static TX_THREAD       thread_2;
13 
14 
15 extern UINT     _tx_thread_preempt_disable;
16 
17 static TX_EVENT_FLAGS_GROUP group_0;
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 void  test_control_return(UINT status);
29 
30 
event_set_notify(TX_EVENT_FLAGS_GROUP * group)31 static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
32 {
33 
34     /* Not necessary to do anything in this function.  */
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_event_flag_single_thread_terminate_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             17, 17, 100, TX_AUTO_START);
60     pointer = pointer + TEST_STACK_SIZE_PRINTF;
61 
62     /* Check status.  */
63     if (status != TX_SUCCESS)
64     {
65 
66         printf("Running Event Flag Single Thread Terminate 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             18, 18, 100, TX_AUTO_START);
73     pointer = pointer + TEST_STACK_SIZE_PRINTF;
74 
75     /* Check status.  */
76     if (status != TX_SUCCESS)
77     {
78 
79         printf("Running Event Flag Single Thread Terminate Test..................... ERROR #2\n");
80         test_control_return(1);
81     }
82 
83     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
84             pointer, TEST_STACK_SIZE_PRINTF,
85             18, 18, 100, TX_DONT_START);
86     pointer = pointer + TEST_STACK_SIZE_PRINTF;
87 
88     /* Check status.  */
89     if (status != TX_SUCCESS)
90     {
91 
92         printf("Running Event Flag Single Thread Terminate Test..................... ERROR #3\n");
93         test_control_return(1);
94     }
95 
96     /* Create event flag group 0.  */
97     status =  tx_event_flags_create(&group_0, "group 0");
98 
99     /* Check status.  */
100     if (status != TX_SUCCESS)
101     {
102 
103         printf("Running Event Flag Single Thread Terminate Test..................... ERROR #4\n");
104         test_control_return(1);
105     }
106 
107     /* Register the event set notify function.  */
108     status =  tx_event_flags_set_notify(&group_0, event_set_notify);
109 
110 #ifndef TX_DISABLE_NOTIFY_CALLBACKS
111 
112     /* Check status.  */
113     if (status != TX_SUCCESS)
114     {
115 
116         printf("Running Event Flag Single Thread Terminate Test..................... ERROR #5\n");
117         test_control_return(1);
118     }
119 #else
120 
121     /* Check status.  */
122     if (status != TX_FEATURE_NOT_ENABLED)
123     {
124 
125         printf("Running Event Flag Single Thread Terminate Test..................... ERROR #6\n");
126         test_control_return(1);
127     }
128 
129 #endif
130 
131 }
132 
133 
134 
135 /* Define the test threads.  */
136 
thread_0_entry(ULONG thread_input)137 static void    thread_0_entry(ULONG thread_input)
138 {
139 
140 UINT    status;
141 
142 
143     /* Inform user.  */
144     printf("Running Event Flag Single Thread Terminate Test..................... ");
145 
146     /* Increment run counter.  */
147     thread_0_counter++;
148 
149     /* Sleep to allow lower-priority thread 1 to run.  */
150     tx_thread_sleep(5);
151 
152     /* Resume Thread 2.  */
153     status =  tx_thread_resume(&thread_2);
154 
155     /* Check status.  */
156     if (status != TX_SUCCESS)
157     {
158 
159         /* Event flag error.  */
160         printf("ERROR #7\n");
161         test_control_return(1);
162     }
163 
164     /* Now terminate thread 1.  */
165     status =  tx_thread_terminate(&thread_1);
166 
167     /* Check status.  */
168     if (status != TX_SUCCESS)
169     {
170 
171         /* Event flag error.  */
172         printf("ERROR #8\n");
173         test_control_return(1);
174     }
175 
176     /* Now sleep to allow Thread 2 to run.  */
177     tx_thread_sleep(5);
178 
179     /* Set only one of the event flags needed.  */
180     status =  tx_event_flags_set(&group_0, 0x00080000, TX_OR);
181 
182     /* Now sleep to allow thread 2 to run.  */
183     tx_thread_sleep(5);
184 
185     /* Check status.  */
186     if ((status != TX_SUCCESS) && (thread_2_counter != 1))
187     {
188 
189         /* Event flag error.  */
190         printf("ERROR #9\n");
191         test_control_return(1);
192     }
193 
194     /* Set the other event flag needed.  */
195     status =  tx_event_flags_set(&group_0, 0x00800000, TX_OR);
196 
197     /* Now sleep to allow thread 2 to run.  */
198     tx_thread_sleep(5);
199 
200     /* Check status.  */
201     if ((status != TX_SUCCESS) && (thread_2_counter != 2))
202     {
203 
204         /* Event flag error.  */
205         printf("ERROR #10\n");
206         test_control_return(1);
207     }
208 
209     /* At this point, thread 2 is suspended on the flags again. Or some flags that are
210        not needed.  */
211 
212     /* Set an event flag that is not needed.  */
213     status =  tx_event_flags_set(&group_0, 0x00000001, TX_OR);
214 
215     /* Now sleep to allow thread 2 to run.  */
216     tx_thread_sleep(5);
217 
218     /* Check status.  */
219     if ((status != TX_SUCCESS) && (thread_2_counter != 2))
220     {
221 
222         /* Event flag error.  */
223         printf("ERROR #11\n");
224         test_control_return(1);
225     }
226 
227     /* Set an event flag that is needed.  */
228     status =  tx_event_flags_set(&group_0, 0x00080001, TX_OR);
229 
230     /* Now sleep to allow thread 2 to run.  */
231     tx_thread_sleep(5);
232 
233     /* Check status and run counters.  */
234     if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 3) ||
235         (_tx_thread_preempt_disable))
236     {
237 
238         /* Event flag error.  */
239         printf("ERROR #12\n");
240         test_control_return(1);
241     }
242 
243     /* Terminate thread 2.  */
244     status =  tx_thread_terminate(&thread_2);
245 
246     /* Check status.  */
247     if ((status != TX_SUCCESS) || (thread_2_counter != 3))
248     {
249 
250         /* Event flag error.  */
251         printf("ERROR #13\n");
252         test_control_return(1);
253     }
254     else
255     {
256 
257         /* Successful test.  */
258         printf("SUCCESS!\n");
259         test_control_return(0);
260     }
261 }
262 
263 
thread_1_entry(ULONG thread_input)264 static void    thread_1_entry(ULONG thread_input)
265 {
266 
267 UINT    status;
268 
269 
270     /* Wait for event flags.  */
271     while(1)
272     {
273 
274         /* Increment run counter.  */
275         thread_1_counter++;
276 
277         /* Self suspend thread.  */
278         status =  tx_thread_suspend(&thread_1);
279 
280         /* Check status.  */
281         if (status != TX_SUCCESS)
282         {
283             thread_1_counter =  0;  /* Make an error!  */
284             return;
285         }
286     }
287 }
288 
289 
thread_2_entry(ULONG thread_input)290 static void    thread_2_entry(ULONG thread_input)
291 {
292 
293 UINT    status;
294 ULONG   actual_events;
295 
296     /* Wait for event flags.  */
297     while(1)
298     {
299 
300         /* Increment run counter.  */
301         thread_2_counter++;
302 
303         /* Attempt to get events from event flag group.  AND option.  */
304         status =  tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
305 
306         /* Check status.  */
307         if (status != TX_SUCCESS)
308             return;
309 
310         /* Increment run counter.  */
311         thread_2_counter++;
312 
313         /* Attempt to get events from event flag group.  OR option.  */
314         status =  tx_event_flags_get(&group_0, 0x000880000, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
315 
316         /* Check status.  */
317         if (status != TX_SUCCESS)
318             return;
319 
320         /* Increment run counter.  */
321         thread_2_counter++;
322 
323         /* Attempt to get events from event flag group.  AND option.  */
324         status =  tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
325 
326         /* Check status.  */
327         if (status != TX_NO_EVENTS)
328             return;
329     }
330 }
331 
332