1 /* This test is designed to test thread terminate (self, and other), thread delete,
2    and thread identify services.  */
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 unsigned long   thread_1_enter =  0;
12 static unsigned long   thread_1_exit =  0;
13 static TX_THREAD       thread_1;
14 
15 static unsigned long   thread_2_counter =  0;
16 static TX_THREAD       thread_2;
17 
18 static TX_THREAD       thread_3;
19 static unsigned long   thread_3_enter =  0;
20 static unsigned long   thread_3_exit =  0;
21 
22 
23 static TX_SEMAPHORE    semaphore_0;
24 
25 
26 /* Define thread prototypes.  */
27 
28 static void    thread_0_entry(ULONG thread_input);
29 static void    thread_1_entry(ULONG thread_input);
30 static void    thread_2_entry(ULONG thread_input);
31 static void    thread_3_entry(ULONG thread_input);
32 
33 
34 /* Prototype for test control return.  */
35 
36 void  test_control_return(UINT status);
37 
38 
entry_exit_notify(TX_THREAD * thread_ptr,UINT type)39 static void   entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
40 {
41 
42     /* Check for the appropriate thread.  */
43     if (thread_ptr != &thread_1)
44         return;
45 
46     /* Check for type.  */
47     if (type == TX_THREAD_ENTRY)
48         thread_1_enter++;
49     else if (type == TX_THREAD_EXIT)
50         thread_1_exit++;
51 }
52 
53 
entry_exit_notify3(TX_THREAD * thread_ptr,UINT type)54 static void   entry_exit_notify3(TX_THREAD *thread_ptr, UINT type)
55 {
56 
57     /* Check for the appropriate thread.  */
58     if (thread_ptr != &thread_3)
59         return;
60 
61     /* Check for type.  */
62     if (type == TX_THREAD_ENTRY)
63         thread_3_enter++;
64     else if (type == TX_THREAD_EXIT)
65         thread_3_exit++;
66 }
67 
68 
69 /* Define what the initial system looks like.  */
70 
71 #ifdef CTEST
test_application_define(void * first_unused_memory)72 void test_application_define(void *first_unused_memory)
73 #else
74 void    threadx_thread_terminate_delete_application_define(void *first_unused_memory)
75 #endif
76 {
77 
78 UINT    status;
79 CHAR    *pointer;
80 
81     /* Put first available memory address into a character pointer.  */
82     pointer =  (CHAR *) first_unused_memory;
83 
84     /* Put system definition stuff in here, e.g. thread creates and other assorted
85        create information.  */
86 
87     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
88             pointer, TEST_STACK_SIZE_PRINTF,
89             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
90     pointer = pointer + TEST_STACK_SIZE_PRINTF;
91 
92     /* Check for status.  */
93     if (status != TX_SUCCESS)
94     {
95 
96         printf("Running Thread Terminate and Delete Test............................ ERROR #1\n");
97         test_control_return(1);
98     }
99 
100     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
101             pointer, TEST_STACK_SIZE_PRINTF,
102             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
103     pointer = pointer + TEST_STACK_SIZE_PRINTF;
104 
105     /* Check for status.  */
106     if (status != TX_SUCCESS)
107     {
108 
109         printf("Running Thread Terminate and Delete Test............................ ERROR #2\n");
110         test_control_return(1);
111     }
112 
113     /* Setup the notify call to test that logic.  */
114     status =  tx_thread_entry_exit_notify(&thread_1, entry_exit_notify);
115 
116 #ifndef TX_DISABLE_NOTIFY_CALLBACKS
117 
118     /* Check for status.  */
119     if (status != TX_SUCCESS)
120     {
121 
122         printf("Running Thread Terminate and Delete Test............................ ERROR #3\n");
123         test_control_return(1);
124     }
125 
126 #else
127 
128     /* Check for status.  */
129     if (status != TX_FEATURE_NOT_ENABLED)
130     {
131 
132         printf("Running Thread Terminate and Delete Test............................ ERROR #4\n");
133         test_control_return(1);
134     }
135 
136 
137 #endif
138 
139     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
140             pointer, TEST_STACK_SIZE_PRINTF,
141             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
142     pointer = pointer + TEST_STACK_SIZE_PRINTF;
143 
144     /* Check for status.  */
145     if (status != TX_SUCCESS)
146     {
147 
148         printf("Running Thread Terminate and Delete Test............................ ERROR #5\n");
149         test_control_return(1);
150     }
151 
152     status =  tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
153             pointer, TEST_STACK_SIZE_PRINTF,
154             12, 12, TX_NO_TIME_SLICE, TX_AUTO_START);
155     pointer = pointer + TEST_STACK_SIZE_PRINTF;
156 
157     /* Check for status.  */
158     if (status != TX_SUCCESS)
159     {
160 
161         printf("Running Thread Terminate and Delete Test............................ ERROR #6\n");
162         test_control_return(1);
163     }
164 
165     /* Setup the notify call to test that logic.  */
166     status =  tx_thread_entry_exit_notify(&thread_3, entry_exit_notify3);
167 
168 #ifndef TX_DISABLE_NOTIFY_CALLBACKS
169 
170     /* Check for status.  */
171     if (status != TX_SUCCESS)
172     {
173 
174         printf("Running Thread Terminate and Delete Test............................ ERROR #7\n");
175         test_control_return(1);
176     }
177 
178 #else
179 
180     /* Check for status.  */
181     if (status != TX_FEATURE_NOT_ENABLED)
182     {
183 
184         printf("Running Thread Terminate and Delete Test............................ ERROR #8\n");
185         test_control_return(1);
186     }
187 
188 #endif
189 
190 
191     /* Create a semaphore for thread 3 to suspend on.  */
192     status =  tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
193 
194     /* Check for status.  */
195     if (status != TX_SUCCESS)
196     {
197 
198         printf("Running Thread Terminate and Delete Test............................ ERROR #9\n");
199         test_control_return(1);
200     }
201 }
202 
203 
204 
205 /* Define the test threads.  */
206 
thread_0_entry(ULONG thread_input)207 static void    thread_0_entry(ULONG thread_input)
208 {
209 
210 UINT    status;
211 
212 
213     /* Inform user.  */
214     printf("Running Thread Terminate and Delete Test............................ ");
215 
216     /* Let other threads execute.  */
217     tx_thread_relinquish();
218 
219     /* Make sure thread 1 is terminated and thread 2 is suspended.  */
220     if ((thread_1.tx_thread_state != TX_TERMINATED) ||
221 #ifndef TX_DISABLE_NOTIFY_CALLBACKS
222         (thread_1_enter != 1) || (thread_1_exit != 1) ||
223 #else
224         (thread_1_enter != 0) || (thread_1_exit != 0) ||
225 #endif
226         (thread_2.tx_thread_state !=  TX_SUSPENDED))
227     {
228 
229         /* Thread error.  */
230         printf("ERROR #10\n");
231         test_control_return(1);
232     }
233 
234     /* At this point, terminate thread 2 which should be in a suspended state
235        right now.  */
236     status =  tx_thread_terminate(&thread_2);
237 
238     /* Check for status.  */
239     if (status != TX_SUCCESS)
240     {
241 
242         /* Thread error.  */
243         printf("ERROR #11\n");
244         test_control_return(1);
245     }
246 
247     /* Delete thread 1 (thread 1 alread terminated) and 2.  */
248     status =  tx_thread_delete(&thread_2);
249 
250     /* Check for status.  */
251     if (status != TX_SUCCESS)
252     {
253 
254         /* Thread error.  */
255         printf("ERROR #12\n");
256         test_control_return(1);
257     }
258 
259     status =  tx_thread_delete(&thread_1);
260 
261     /* Check for status.  */
262     if (status != TX_SUCCESS)
263     {
264 
265         /* Thread error.  */
266         printf("ERROR #13\n");
267         test_control_return(1);
268     }
269 
270     /* At this point, terminate thread 3 which should be in a suspended state
271        on the semaphore right now.  */
272     status =  tx_thread_terminate(&thread_3);
273 
274     /* Check for status.  */
275     if (status != TX_SUCCESS)
276     {
277 
278         /* Thread error.  */
279         printf("ERROR #14\n");
280         test_control_return(1);
281     }
282 
283     /* Delete thread 3.  */
284     status =  tx_thread_delete(&thread_3);
285 
286     /* Check for status.  */
287     if (status != TX_SUCCESS)
288     {
289 
290         /* Thread error.  */
291         printf("ERROR #15\n");
292         test_control_return(1);
293     }
294 
295      /* Increment thread 0 counter.  */
296     thread_0_counter++;
297 
298     /* Successful test.  */
299     printf("SUCCESS!\n");
300     test_control_return(0);
301 }
302 
thread_1_entry(ULONG thread_input)303 static void    thread_1_entry(ULONG thread_input)
304 {
305 
306     /* Test identity.  */
307     if (tx_thread_identify() != &thread_1)
308         return;
309 
310     /* Increment the thread counter.  */
311     thread_1_counter++;
312 
313     /* Terminate self.  */
314     tx_thread_terminate(&thread_1);
315 }
316 
thread_2_entry(ULONG thread_input)317 static void    thread_2_entry(ULONG thread_input)
318 {
319 
320     /* Test identity.  */
321     if (tx_thread_identify() != &thread_2)
322         return;
323 
324     /* Increment thread counter.  */
325     thread_2_counter++;
326 
327     /* Suspend thread.  */
328     tx_thread_suspend(&thread_2);
329 }
330 
331 
thread_3_entry(ULONG thread_input)332 static void    thread_3_entry(ULONG thread_input)
333 {
334 
335     /* Get the semaphore with wait forever!  */
336     tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
337 
338     /* Increment thread counter.  */
339     thread_2_counter++;
340 }
341 
342