1 /* This test is designed to test a simple sleep for 100 ticks.  */
2 
3 #include   <stdio.h>
4 #include   "tx_api.h"
5 #include   "tx_thread.h"
6 #include   "tx_timer.h"
7 
8 //#define DEBUG
9 
10 /* Define the ISR dispatch.  */
11 
12 extern VOID    (*test_isr_dispatch)(void);
13 
14 
15 
16 static TX_THREAD       thread_0;
17 
18 static int             error = 0;
19 
20 static int             isr_count =  0;
21 
22 #ifdef TEST_INTERRUPT_CONDITION
23 #ifndef TX_NOT_INTERRUPTABLE
24 
25 #if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
26 /* Use larger array size when running on Win32 test platform because of greater speed.  */
27 #define ARRAY_SIZE              100
28 #else
29 #define ARRAY_SIZE              10
30 #endif
31 
32 
33 static UINT                     isr_test_suspend_interrupt = TX_TRUE;
34 static UINT                     isr_test_suspend_interrupted_condition =  TX_FALSE;
35 static ULONG                    min_loop_count;
36 static ULONG                    max_loop_count;
37 static TX_SEMAPHORE             test_semaphore;
38 static ULONG                    loop_count;
39 static volatile ULONG           count;
40 static volatile ULONG           destination =  0;
41 static ULONG                    array_delay[ARRAY_SIZE];
42 static ULONG                    start_time;
43 static ULONG                    lower_bound;
44 static ULONG                    upper_bound;
45 static ULONG                    current_itterations;
46 #ifdef DEBUG_1
47 static ULONG                    last_loop_count;
48 #endif
delay_function(void)49 static ULONG   delay_function(void)
50 {
51 
52 ULONG   accumulator;
53 ULONG   i;
54 
55     for (i = 0; i < ARRAY_SIZE; i++)
56         array_delay[i] = i;
57 
58     for (i = 0; i < ARRAY_SIZE-4; i++)
59     {
60         array_delay[i] =  (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]);
61     }
62 
63     accumulator =  0;
64     for (i = 0; i < ARRAY_SIZE; i++)
65         accumulator =  accumulator + array_delay[i];
66 
67     return(accumulator);
68 }
69 
70 #endif
71 #endif
72 
73 
74 /* Define thread prototypes.  */
75 
76 static void    thread_0_entry(ULONG thread_input);
77 
78 
79 /* Prototype for test control return.  */
80 
81 void  test_control_return(UINT status);
82 
83 
84 
85 /* Define the ISR dispatch routine.  */
86 
test_isr(void)87 static void    test_isr(void)
88 {
89 
90 UINT    status;
91 
92 #ifdef TEST_INTERRUPT_CONDITION
93 #ifndef TX_NOT_INTERRUPTABLE
94 ULONG i;
95 
96     /* Determine if we are in calibration mode.  */
97     if ((loop_count) && (loop_count != 0xFFFFFFFF))
98     {
99         if (loop_count < min_loop_count)
100             min_loop_count =  loop_count;
101         if (loop_count > max_loop_count)
102             max_loop_count =  loop_count;
103 
104         lower_bound = loop_count - 1;
105         upper_bound = loop_count + 1;
106         if (lower_bound < min_loop_count)
107             lower_bound =  min_loop_count;
108         if (upper_bound > max_loop_count)
109             lower_bound = max_loop_count;
110 
111         if ((current_itterations < lower_bound) || (current_itterations > upper_bound))
112             current_itterations =  lower_bound;
113 
114 #ifdef DEBUG_1
115         /* Last loop count.  */
116         last_loop_count =  loop_count;
117 #endif
118 
119         /* Reset the loop count to all ones!  */
120         loop_count =  0xFFFFFFFF;
121     }
122     count++;
123     for (i = 0; i < (count%32); i++)
124         destination++;
125 
126     /* Determine if the ISR is in the mode to wakeup the thread suspending with a timeout.   */
127     if (isr_test_suspend_interrupt)
128     {
129 
130         /* Determine if the thread is suspended on the semaphore...  */
131         if (thread_0.tx_thread_state == TX_SEMAPHORE_SUSP)
132         {
133 
134             /* Determine if the test condition is present...  */
135             if ((_tx_thread_preempt_disable) &&
136                 (thread_0.tx_thread_timer.tx_timer_internal_list_head == TX_NULL))
137             {
138 
139                 /* Set the flag showing the condition is present.  */
140                 isr_test_suspend_interrupted_condition =  TX_TRUE;
141 
142                 /* All done with the test.  */
143                 isr_test_suspend_interrupt =  TX_FALSE;
144             }
145 
146             /* Post to the semaphore to wakeup the thread.  */
147             tx_semaphore_put(&test_semaphore);
148         }
149 
150         return;
151     }
152 #endif
153 #endif
154 
155     /* Increment the ISR count.  */
156     isr_count++;
157 
158     /* Call sleep from ISR to check for error!  */
159     status =  tx_thread_sleep(100);
160 
161     /* Check status.  */
162     if (status != TX_CALLER_ERROR)
163     {
164 
165 
166         error =  1;
167     }
168 
169     /* End the ISR.  */
170     test_isr_dispatch =  TX_NULL;
171 }
172 
173 
174 /* Define what the initial system looks like.  */
175 
176 #ifdef CTEST
test_application_define(void * first_unused_memory)177 void test_application_define(void *first_unused_memory)
178 #else
179 void    threadx_thread_sleep_for_100ticks_application_define(void *first_unused_memory)
180 #endif
181 {
182 
183 UINT    status;
184 CHAR    *pointer;
185 
186     /* Put first available memory address into a character pointer.  */
187     pointer =  (CHAR *) first_unused_memory;
188 
189 
190     /* Put system definition stuff in here, e.g. thread creates and other assorted
191        create information.  */
192 
193     status =  tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
194             pointer, TEST_STACK_SIZE_PRINTF,
195             16, 16, 3, TX_AUTO_START);
196 
197     /* Check for status.  */
198     if (status != TX_SUCCESS)
199     {
200 
201         printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #1\n");
202         test_control_return(1);
203     }
204 
205 #ifdef TEST_INTERRUPT_CONDITION
206 #ifndef TX_NOT_INTERRUPTABLE
207 
208     status =  tx_semaphore_create(&test_semaphore, "test semaphore", 0);
209 
210     /* Check for status.  */
211     if (status != TX_SUCCESS)
212     {
213 
214         printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #2\n");
215         test_control_return(1);
216     }
217 
218     min_loop_count =       0xFFFFFFFF;
219     max_loop_count =       0;
220     loop_count =           0xFFFFFFFF;
221     current_itterations =  0;
222 #ifdef DEBUG_1
223     last_loop_count =      0x0;
224 #endif
225 #endif
226 #endif
227 }
228 
229 
230 
231 /* Define the test threads.  */
232 
thread_0_entry(ULONG thread_input)233 static void    thread_0_entry(ULONG thread_input)
234 {
235 
236 UINT    status;
237 #ifdef TEST_INTERRUPT_CONDITION
238 #ifndef TX_NOT_INTERRUPTABLE
239 ULONG                i;
240 volatile ULONG       value = 0;
241 #endif
242 #endif
243 
244     /* Inform user.  */
245     printf("Running Thread Sleep for 100 Ticks Test............................. ");
246 
247     /* Call sleep with an expiration of 0 and test error code.  */
248     status =  tx_thread_sleep(0);
249 
250     /* Check error code.  */
251     if (status != TX_SUCCESS)
252     {
253 
254         /* Thread Simple Sleep error.  */
255         printf("ERROR #3\n");
256         test_control_return(1);
257     }
258 
259 #ifdef TEST_INTERRUPT_CONDITION
260 #ifndef TX_NOT_INTERRUPTABLE
261 
262 
263     isr_test_suspend_interrupt = TX_TRUE;
264     isr_test_suspend_interrupted_condition =  TX_FALSE;
265 #endif
266 #endif
267 
268     /* Setup the test ISR.  */
269     test_isr_dispatch =  test_isr;
270 
271 #ifdef TEST_INTERRUPT_CONDITION
272 #ifndef TX_NOT_INTERRUPTABLE
273 
274     /* Callibrate the loop count from thread sleep.  */
275     for (i = 0; i < 180; i++)
276     {
277 
278         /* Sleep to get a fresh time.  */
279         tx_thread_sleep(1);
280 
281         /* Set the loop count to 0 and start counting....  */
282         loop_count =  0;
283         start_time =  _tx_timer_system_clock;
284         do
285         {
286 
287             /* Call delay function.  */
288             delay_function();
289             loop_count++;
290         } while (start_time == _tx_timer_system_clock);
291 
292         /* Wait to reset the loop count.  */
293         tx_thread_sleep(1);
294     }
295 
296 #if 1
297     /* Setup the lower and upper bounds.  */
298     lower_bound =  min_loop_count;
299     if (lower_bound > 5)
300         lower_bound = lower_bound - 5;
301     upper_bound =  max_loop_count + 5;
302 #else
303     /* Setup the lower and upper bounds.  */
304     lower_bound =  min_loop_count;
305     upper_bound =  max_loop_count;
306 #endif
307 
308     current_itterations =  lower_bound;
309 #ifdef DEBUG
310     i =  0;
311 #endif
312     while (isr_test_suspend_interrupted_condition != TX_TRUE)
313     {
314 
315         /* Sleep to get a frest timer slot.  */
316         tx_thread_sleep(1);
317 
318         /* Loop to delay to next interrupt.  */
319         loop_count =  0;
320         start_time =  _tx_timer_system_clock;
321         do
322         {
323             /* Call delay function.  */
324             delay_function();
325             loop_count++;
326         } while (loop_count < current_itterations);
327 
328         /* Check for a timer interrupt... if so, just skip the semaphore get.  */
329         if (start_time != _tx_timer_system_clock)
330             continue;
331 
332         /* Suspend on the semaphore for 20 ticks...  */
333         tx_semaphore_get(&test_semaphore, 20);
334 
335         /* Adjust the current itterations.  */
336         current_itterations++;
337         if (current_itterations > upper_bound)
338         {
339             if (lower_bound > min_loop_count)
340                 lower_bound--;
341             if (upper_bound < max_loop_count)
342                 upper_bound++;
343             current_itterations =  lower_bound;
344         }
345 
346         /* Set the tick count simply to use value.  */
347         tx_time_set(value);
348 #ifdef DEBUG
349         /* Debug block.  */
350         i++;
351         if ((i % 180) == 0)
352         {
353             printf("*** update ***\n");
354             if (loop_count == 0xFFFFFFFF)
355             printf("loop count:      NA\n");
356             else
357             printf("loop count:      %lu\n", loop_count);
358             printf("current:         %lu\n", current_itterations);
359             printf("last loop count: %lu\n", last_loop_count);
360             printf("minimum:         %lu\n", min_loop_count);
361             printf("maximum:         %lu\n", max_loop_count);
362             printf("lower bound:     %lu\n", lower_bound);
363             printf("upper bound:     %lu\n", upper_bound);
364             printf("count:           %lu\n", i);
365         }
366 #endif
367     }
368 
369 #ifdef DEBUG
370     /* Debug block  */
371     printf("*** final ***\n");
372     if (loop_count == 0xFFFFFFFF)
373     printf("loop count:      NA\n");
374     else
375     printf("loop count:      %lu\n", loop_count);
376     printf("current:         %lu\n", current_itterations);
377     printf("last loop count: %lu\n", last_loop_count);
378     printf("minimum:         %lu\n", min_loop_count);
379     printf("maximum:         %lu\n", max_loop_count);
380     printf("lower bound:     %lu\n", lower_bound);
381     printf("upper bound:     %lu\n", upper_bound);
382     printf("count:           %lu\n", i);
383 #endif
384 
385     /* Clear the tick count. */
386     tx_time_set(0);
387 
388     /* Sleep for 100 ticks.  */
389     tx_thread_sleep(100);
390 
391     /* Check for error.  */
392     if (tx_time_get() < 100)
393     {
394 
395         /* Thread Simple Sleep error.  */
396         printf("ERROR #4\n");
397         test_control_return(1);
398     }
399 #endif
400 #endif
401 
402     /* Clear the tick count. */
403     tx_time_set(0);
404 
405 
406     /* Sleep for 100 ticks.  */
407     status =  tx_thread_sleep(100);
408 
409     /* Determine if the sleep was accurate.  */
410     if ((status != TX_SUCCESS) || (tx_time_get() < 100) ||
411         (tx_time_get() > 101))
412     {
413 
414         /* Thread Simple Sleep error.  */
415         printf("ERROR #5\n");
416         test_control_return(1);
417     }
418 
419     /* Check to make sure the ISR happened and the proper return value was present.  */
420     if ((isr_count == 0) || (error))
421     {
422 
423         /* Thread Simple Sleep error.  */
424         printf("ERROR #6\n");
425         test_control_return(1);
426     }
427     else
428     {
429 
430         /* Successful Simple Sleep test.  */
431         printf("SUCCESS!\n");
432         test_control_return(0);
433     }
434 }
435 
436