1 /* This test is designed to test the change priority service call.  */
2 
3 #include   <stdio.h>
4 #include   "tx_api.h"
5 #include   "tx_thread.h"
6 
7 
8 static unsigned long   thread_0_counter =  0;
9 static TX_THREAD       thread_0;
10 
11 static unsigned long   thread_1_counter =  0;
12 static TX_THREAD       thread_1;
13 
14 static unsigned long   thread_2_counter =  0;
15 static TX_THREAD       thread_2;
16 
17 static TX_THREAD       thread_3;
18 static unsigned long   thread_3_counter =  0;
19 static TX_THREAD       thread_4;
20 static unsigned long   thread_4_counter =  0;
21 
22 
23 /* Define the ISR dispatch.  */
24 
25 extern VOID    (*test_isr_dispatch)(void);
26 
27 
28 /* Define thread prototypes.  */
29 
30 static void    thread_0_entry(ULONG thread_input);
31 static void    thread_1_entry(ULONG thread_input);
32 static void    thread_2_entry(ULONG thread_input);
33 static void    thread_3_entry(ULONG thread_input);
34 static void    thread_4_entry(ULONG thread_input);
35 
36 
37 extern unsigned long _tx_thread_priority_map;
38 
39 
40 /* Prototype for test control return.  */
41 void  test_control_return(UINT status);
42 
43 
44 /* Define the ISR dispatch routine.  */
45 
test_isr(void)46 static void    test_isr(void)
47 {
48 
49 UINT    saved_preempt_disable;
50 
51 #ifndef TX_NOT_INTERRUPTABLE
52 
53     /* Determine if we have the interrupt condition we are looking for.  */
54     if ((thread_3.tx_thread_priority == 6) &&
55         (thread_3.tx_thread_state == TX_READY) &&
56         (_tx_thread_priority_list[6] != &thread_3) &&
57         (thread_3_counter > 100))
58     {
59 
60         /* Save the preempt disable flag.  */
61         saved_preempt_disable =  _tx_thread_preempt_disable;
62 
63         /* Clear the preempt disable flag to ensure the API works correctly.  */
64         _tx_thread_preempt_disable =  0;
65 
66         /* Suspend the thread to generate the condition.  */
67         tx_thread_suspend(&thread_3);
68 
69         /* Restore the preempt disable flag.  */
70         _tx_thread_preempt_disable =  saved_preempt_disable;
71 
72         /* Done trying to generate this test condition.  */
73         test_isr_dispatch =  TX_NULL;
74     }
75 #else
76 
77     /* Can't get the interrupt inside the code wit TX_NOT_INTERRUPTABLE defined, so simply stop after thread_3_counter > 100.  */
78     if (thread_3_counter > 100)
79     {
80 
81         /* Done trying to generate this test condition.  */
82         test_isr_dispatch =  TX_NULL;
83     }
84 #endif
85 }
86 
87 /* Define what the initial system looks like.  */
88 
89 #ifdef CTEST
test_application_define(void * first_unused_memory)90 void test_application_define(void *first_unused_memory)
91 #else
92 void    threadx_thread_priority_change_application_define(void *first_unused_memory)
93 #endif
94 {
95 
96 UINT    status;
97 CHAR    *pointer;
98 
99     /* Put first available memory address into a character pointer.  */
100     pointer =  (CHAR *) first_unused_memory;
101 
102     /* Put system definition stuff in here, e.g. thread creates and other assorted
103        create information.  */
104 
105     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
106             pointer, TEST_STACK_SIZE_PRINTF,
107             16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
108     pointer = pointer + TEST_STACK_SIZE_PRINTF;
109 
110     /* Check for status.  */
111     if (status != TX_SUCCESS)
112     {
113 
114         printf("Running Thread Priority Change Test................................. ERROR #1\n");
115         test_control_return(1);
116     }
117 
118     status =  tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
119             pointer, TEST_STACK_SIZE_PRINTF,
120             22, 22, TX_NO_TIME_SLICE, TX_AUTO_START);
121     pointer = pointer + TEST_STACK_SIZE_PRINTF;
122 
123     /* Check for status.  */
124     if (status != TX_SUCCESS)
125     {
126 
127         printf("Running Thread Priority Change Test................................. ERROR #2\n");
128         test_control_return(1);
129     }
130 
131     status =  tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
132             pointer, TEST_STACK_SIZE_PRINTF,
133             30, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
134     pointer = pointer + TEST_STACK_SIZE_PRINTF;
135     status +=  tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
136             pointer, TEST_STACK_SIZE_PRINTF,
137             5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
138     pointer = pointer + TEST_STACK_SIZE_PRINTF;
139     status +=  tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
140             pointer, TEST_STACK_SIZE_PRINTF,
141             6, 6, TX_NO_TIME_SLICE, TX_DONT_START);
142     pointer = pointer + TEST_STACK_SIZE_PRINTF;
143 
144     /* Check for status.  */
145     if (status != TX_SUCCESS)
146     {
147 
148         printf("Running Thread Priority Change Test................................. ERROR #3\n");
149         test_control_return(1);
150     }
151 }
152 
153 
154 
155 /* Define the test threads.  */
156 
thread_0_entry(ULONG thread_input)157 static void    thread_0_entry(ULONG thread_input)
158 {
159 
160 //ULONG   current_time;
161 UINT    old_priority;
162 UINT    status;
163 
164 
165     /* Inform user.  */
166     printf("Running Thread Priority Change Test................................. ");
167 
168     /* Resume thread 3.  */
169     tx_thread_resume(&thread_3);
170 
171     /* Increment thread 0 counter.  */
172     thread_0_counter++;
173 
174     /* Change priority to 22, to match that of the next highest priority ready thread.
175        This is to test the update of the priority list when a thread is moved to a
176        priority with already ready threads.  */
177     status =  tx_thread_priority_change(&thread_0, 22, &old_priority);
178 
179     /* Check status, return priority, and run count of other thread.  */
180     if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0))
181     {
182 
183         /* Thread error.  */
184         printf("ERROR #4\n");
185         test_control_return(1);
186     }
187 
188     /* Restore original priority.  */
189     tx_thread_priority_change(&thread_0, old_priority, &old_priority);
190 
191     /* See if we can change priority of this thread.  */
192     status =  tx_thread_priority_change(&thread_0, 7, &old_priority);
193 
194     /* Check status, return priority, and run count of other thread.  */
195     if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0))
196     {
197 
198         /* Thread error.  */
199         printf("ERROR #4\n");
200         test_control_return(1);
201     }
202 
203     /* See if we can change priority of another ready thread.  */
204     status =  tx_thread_priority_change(&thread_1, 21, &old_priority);
205 
206     /* Check status, return priority, and run count of other thread.  */
207     if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 0))
208     {
209 
210         /* Thread error.  */
211         printf("ERROR #5\n");
212         test_control_return(1);
213     }
214 
215     /* See if we can cause preemption by lowering this thread's priority.  */
216     status =  tx_thread_priority_change(&thread_0, 22, &old_priority);
217 
218     /* Check status, return priority, and run count of other thread.  */
219     if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 1))
220     {
221 
222         /* Thread error.  */
223         printf("ERROR #6\n");
224         test_control_return(1);
225     }
226 
227     /* Thread 1 should have run already...  Raise this threads priority
228        back up.  */
229     status =  tx_thread_priority_change(&thread_0, 8, &old_priority);
230 
231     /* Check status, return priority, and run count of other thread.  */
232     if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 1))
233     {
234 
235         /* Thread error.  */
236         printf("ERROR #7\n");
237         test_control_return(1);
238     }
239 
240     /* See if we can change the priority of a suspended thread.  */
241     status =  tx_thread_priority_change(&thread_1, 19, &old_priority);
242 
243     /* Check status, return priority, and run count of other thread.  */
244     if ((status != TX_SUCCESS) || (old_priority != 21) || (thread_1_counter != 1))
245     {
246 
247         /* Thread error.  */
248         printf("ERROR #8\n");
249         test_control_return(1);
250     }
251 
252     /* Resume the suspended thread so it is in a ready condition.  */
253     status =  tx_thread_resume(&thread_1);
254 
255     /* Check status, return priority, and run count of other thread.  */
256     if ((status != TX_SUCCESS) || (thread_1_counter != 1))
257     {
258 
259         /* Thread error.  */
260         printf("ERROR #9\n");
261         test_control_return(1);
262     }
263 
264     /* Should not have run yet.  Raise its priority to 8 still should not run yet!  */
265     status =  tx_thread_priority_change(&thread_1, 8, &old_priority);
266 
267     /* Check status, return priority, and run count of other thread.  */
268     if ((status != TX_SUCCESS) || (old_priority != 19) || (thread_1_counter != 1))
269     {
270 
271         /* Thread error.  */
272         printf("ERROR #10\n");
273         test_control_return(1);
274     }
275 
276     /* Raise its priority to 7, now it should run.  */
277     status =  tx_thread_priority_change(&thread_1, 7, &old_priority);
278 
279     /* Check status, return priority, and run count of other thread.  */
280     if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0))
281     {
282 
283         /* Thread error.  */
284         printf("ERROR #11\n");
285         test_control_return(1);
286     }
287 
288     /* Now thread 1 should be suspended.  Let's change thread 0's priority and make sure thread 2 doesn't run yet!  */
289     status =  tx_thread_priority_change(&thread_0, 7, &old_priority);
290 
291     /* Check status, return priority, and run count of other thread.  */
292     if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0))
293     {
294 
295         /* Thread error.  */
296         printf("ERROR #12\n");
297         test_control_return(1);
298     }
299     else
300     {
301 
302         /* Successful test.  */
303         printf("SUCCESS!\n");
304         test_control_return(0);
305     }
306 }
307 
thread_1_entry(ULONG thread_input)308 static void    thread_1_entry(ULONG thread_input)
309 {
310 
311     while(1)
312     {
313 
314         /* Increment the thread counter.  */
315         thread_1_counter++;
316 
317         /* Suspend self and wait for upper thread to resume.  */
318         tx_thread_suspend(&thread_1);
319     }
320 }
321 
322 
thread_2_entry(ULONG thread_input)323 static void    thread_2_entry(ULONG thread_input)
324 {
325 
326     while(1)
327     {
328 
329         /* This thread should never run!  */
330 
331         /* Increment the thread counter.  */
332         thread_2_counter++;
333 
334         /* Self suspend.  */
335         tx_thread_suspend(&thread_2);
336     }
337 }
338 
339 
thread_3_entry(ULONG thread_input)340 static void    thread_3_entry(ULONG thread_input)
341 {
342 
343 UINT    old_priority;
344 UINT    loop;
345 
346 
347     /* Resume threads 4.  */
348     tx_thread_resume(&thread_4);
349 
350     /* Setup the ISR.  */
351     test_isr_dispatch =  test_isr;
352     do
353     {
354 
355         loop =  rand() % 100;
356         while (loop--)
357         {
358             thread_3_counter++;
359         }
360 
361         /* Raise priority of thread 3 for code coverage.  */
362         tx_thread_priority_change(&thread_3, 6, &old_priority);
363         tx_thread_priority_change(&thread_3, 5, &old_priority);
364 
365         /* Check to see if thread 4 has run... it should not have executed
366            yet. If it does, set the thread_1_counter to indicate an error!  */
367         if (thread_4_counter)
368             thread_1_counter++;
369 
370     } while (test_isr_dispatch);
371 }
372 
373 
thread_4_entry(ULONG thread_input)374 static void    thread_4_entry(ULONG thread_input)
375 {
376     thread_4_counter++;
377 }
378 
379