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