Mercurial > flash_v2
comparison packages/kernel/current/tests/tm_basic.cxx @ 0:3111d98ba7b3 ecos-v1_1-release
Initial commit of eCos version 1.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 11:16:07 +0000 |
| parents | |
| children | 443894e2e912 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:3111d98ba7b3 |
|---|---|
| 1 //========================================================================== | |
| 2 // | |
| 3 // tm_basic.cxx | |
| 4 // | |
| 5 // Basic timing test / scaffolding | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
| 9 // | |
| 10 // ------------------------------------------- | |
| 11 // The contents of this file are subject to the Cygnus eCos Public License | |
| 12 // Version 1.0 (the "License"); you may not use this file except in | |
| 13 // compliance with the License. You may obtain a copy of the License at | |
| 14 // http://sourceware.cygnus.com/ecos | |
| 15 // | |
| 16 // Software distributed under the License is distributed on an "AS IS" | |
| 17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 18 // License for the specific language governing rights and limitations under | |
| 19 // the License. | |
| 20 // | |
| 21 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 22 // September 30, 1998. | |
| 23 // | |
| 24 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. | |
| 26 // ------------------------------------------- | |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //========================================================================== | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 32 // Author(s): gthomas | |
| 33 // Contributors: gthomas | |
| 34 // Date: 1998-10-19 | |
| 35 // Description: Very simple timing test setup | |
| 36 //####DESCRIPTIONEND#### | |
| 37 | |
| 38 #include <pkgconf/kernel.h> | |
| 39 | |
| 40 #include <cyg/kernel/sched.hxx> | |
| 41 #include <cyg/kernel/thread.hxx> | |
| 42 #include <cyg/kernel/thread.inl> | |
| 43 #include <cyg/kernel/mutex.hxx> | |
| 44 #include <cyg/kernel/sema.hxx> | |
| 45 #include <cyg/kernel/sched.inl> | |
| 46 #include <cyg/kernel/clock.hxx> | |
| 47 #include <cyg/kernel/clock.inl> | |
| 48 #include <cyg/kernel/kapi.h> | |
| 49 | |
| 50 #include <cyg/infra/testcase.h> | |
| 51 #define NTHREADS 1 | |
| 52 #include "testaux.hxx" | |
| 53 | |
| 54 // Structure used to keep track of times | |
| 55 typedef struct fun_times { | |
| 56 cyg_uint32 start; | |
| 57 cyg_uint32 end; | |
| 58 } fun_times; | |
| 59 | |
| 60 #define NSAMPLES 10 | |
| 61 #define NTEST_THREADS 32 | |
| 62 #define NTHREAD_SWITCHES 128 | |
| 63 #define NMUTEXES 32 | |
| 64 #define NMBOXES 32 | |
| 65 #define NSEMAPHORES 32 | |
| 66 #define NSCHEDS 128 | |
| 67 #define NCOUNTERS 32 | |
| 68 #define NALARMS 32 | |
| 69 | |
| 70 #define STACK_SIZE 2048 // Is this large enough? | |
| 71 static char stacks[NTEST_THREADS][STACK_SIZE]; | |
| 72 static cyg_thread test_threads[NTEST_THREADS]; | |
| 73 static cyg_handle_t threads[NTEST_THREADS]; | |
| 74 static int overhead; | |
| 75 static cyg_sem_t synchro; | |
| 76 static fun_times thread_ft[NTEST_THREADS]; | |
| 77 | |
| 78 static fun_times test2_ft[NTHREAD_SWITCHES]; | |
| 79 | |
| 80 static cyg_mutex_t test_mutexes[NMUTEXES]; | |
| 81 static fun_times mutex_ft[NMUTEXES]; | |
| 82 static cyg_thread mutex_test_thread; | |
| 83 static cyg_handle_t mutex_test_thread_handle; | |
| 84 | |
| 85 static cyg_mbox test_mboxes[NMBOXES]; | |
| 86 static cyg_handle_t test_mbox_handles[NMBOXES]; | |
| 87 static fun_times mbox_ft[NMBOXES]; | |
| 88 static cyg_thread mbox_test_thread; | |
| 89 static cyg_handle_t mbox_test_thread_handle; | |
| 90 | |
| 91 static cyg_sem_t test_semaphores[NSEMAPHORES]; | |
| 92 static fun_times semaphore_ft[NSEMAPHORES]; | |
| 93 static cyg_thread semaphore_test_thread; | |
| 94 static cyg_handle_t semaphore_test_thread_handle; | |
| 95 | |
| 96 static fun_times sched_ft[NSCHEDS]; | |
| 97 | |
| 98 static cyg_counter test_counters[NCOUNTERS]; | |
| 99 static cyg_handle_t counters[NCOUNTERS]; | |
| 100 static fun_times counter_ft[NCOUNTERS]; | |
| 101 | |
| 102 static cyg_alarm test_alarms[NALARMS]; | |
| 103 static cyg_handle_t alarms[NALARMS]; | |
| 104 static fun_times alarm_ft[NALARMS]; | |
| 105 | |
| 106 externC void diag_printf(const char *, ...); | |
| 107 externC void sprintf(char *, const char *, ...); | |
| 108 | |
| 109 void run_sched_tests(void); | |
| 110 void run_thread_tests(void); | |
| 111 void run_thread_switch_test(void); | |
| 112 void run_mutex_tests(void); | |
| 113 void run_mutex_circuit_test(void); | |
| 114 void run_mbox_tests(void); | |
| 115 void run_mbox_circuit_test(void); | |
| 116 void run_semaphore_tests(void); | |
| 117 void run_semaphore_circuit_test(void); | |
| 118 void run_counter_tests(void); | |
| 119 void run_alarm_tests(void); | |
| 120 | |
| 121 #ifdef HAL_CLOCK_LATENCY | |
| 122 extern cyg_tick_count total_clock_latency, total_clock_interrupts; | |
| 123 extern cyg_int32 min_clock_latency, max_clock_latency; | |
| 124 #endif | |
| 125 | |
| 126 cyg_uint32 | |
| 127 ticks_to_us(cyg_uint32 ticks) | |
| 128 { | |
| 129 int us; | |
| 130 // Assumes that the clock is set up for 10ms ticks | |
| 131 us = (10000 * ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; | |
| 132 return (us); | |
| 133 } | |
| 134 | |
| 135 // Wait until a clock tick [real time clock] has passed. This should keep it | |
| 136 // from happening again during a measurement, thus minimizing any fluctuations | |
| 137 void | |
| 138 wait_for_tick(void) | |
| 139 { | |
| 140 cyg_uint32 tv0, tv1; | |
| 141 HAL_CLOCK_READ(&tv0); | |
| 142 while (true) { | |
| 143 HAL_CLOCK_READ(&tv1); | |
| 144 if (tv1 < tv0) break; | |
| 145 tv0 = tv1; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 // Compute a name for a thread | |
| 150 char * | |
| 151 thread_name(char *basename, int indx) { | |
| 152 return "<<NULL>>"; // Not currently used | |
| 153 } | |
| 154 | |
| 155 // test0 - null test, never executed | |
| 156 void | |
| 157 test0(cyg_uint32 indx) | |
| 158 { | |
| 159 diag_printf("test0.%d executed?\n", indx); | |
| 160 cyg_thread_exit(); | |
| 161 } | |
| 162 | |
| 163 // test1 - empty test, simply exit. Last thread signals parent. | |
| 164 void | |
| 165 test1(cyg_uint32 indx) | |
| 166 { | |
| 167 if (indx == (NTEST_THREADS-1)) { | |
| 168 cyg_semaphore_post(&synchro); // Signal that last thread is dying | |
| 169 } | |
| 170 cyg_thread_exit(); | |
| 171 } | |
| 172 | |
| 173 // test2 - measure thread switch times | |
| 174 void | |
| 175 test2(cyg_uint32 indx) | |
| 176 { | |
| 177 int i; | |
| 178 for (i = 0; i < NTHREAD_SWITCHES; i++) { | |
| 179 if (indx == 0) { | |
| 180 HAL_CLOCK_READ(&test2_ft[i].start); | |
| 181 } else { | |
| 182 HAL_CLOCK_READ(&test2_ft[i].end); | |
| 183 } | |
| 184 cyg_thread_yield(); | |
| 185 } | |
| 186 if (indx == 1) { | |
| 187 cyg_semaphore_post(&synchro); | |
| 188 } | |
| 189 cyg_thread_exit(); | |
| 190 } | |
| 191 | |
| 192 // Full-circuit mutex unlock/lock test | |
| 193 void | |
| 194 mutex_test(cyg_uint32 indx) | |
| 195 { | |
| 196 int i; | |
| 197 cyg_mutex_lock(&test_mutexes[0]); | |
| 198 for (i = 0; i < NMUTEXES; i++) { | |
| 199 cyg_semaphore_wait(&synchro); | |
| 200 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 201 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 202 cyg_mutex_unlock(&test_mutexes[0]); | |
| 203 cyg_mutex_lock(&test_mutexes[0]); | |
| 204 cyg_semaphore_post(&synchro); | |
| 205 } | |
| 206 cyg_thread_exit(); | |
| 207 } | |
| 208 | |
| 209 // Full-circuit mbox put/get test | |
| 210 void | |
| 211 mbox_test(cyg_uint32 indx) | |
| 212 { | |
| 213 void *item; | |
| 214 do { | |
| 215 item = cyg_mbox_get(test_mbox_handles[0]); | |
| 216 HAL_CLOCK_READ(&mbox_ft[(int)item].end); | |
| 217 cyg_semaphore_post(&synchro); | |
| 218 } while ((int)item != (NMBOXES-1)); | |
| 219 cyg_thread_exit(); | |
| 220 } | |
| 221 | |
| 222 // Full-circuit semaphore post/wait test | |
| 223 void | |
| 224 semaphore_test(cyg_uint32 indx) | |
| 225 { | |
| 226 int i; | |
| 227 for (i = 0; i < NSEMAPHORES; i++) { | |
| 228 cyg_semaphore_wait(&test_semaphores[0]); | |
| 229 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 230 cyg_semaphore_post(&synchro); | |
| 231 } | |
| 232 cyg_thread_exit(); | |
| 233 } | |
| 234 | |
| 235 void | |
| 236 show_times_hdr(void) | |
| 237 { | |
| 238 diag_printf("\n"); | |
| 239 diag_printf(" Ave Min Max Variance Function\n"); | |
| 240 diag_printf("====== ====== ====== ======== ========\n"); | |
| 241 } | |
| 242 | |
| 243 void | |
| 244 show_times(fun_times ft[], int nsamples, char *title) | |
| 245 { | |
| 246 int i, delta, min, max; | |
| 247 cyg_uint32 total, ave, var; | |
| 248 total = 0; | |
| 249 min = 0x7FFFFFFF; | |
| 250 max = 0; | |
| 251 for (i = 0; i < nsamples; i++) { | |
| 252 if (ft[i].end < ft[i].start) { | |
| 253 // Clock wrapped around (timer tick) | |
| 254 delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; | |
| 255 } else { | |
| 256 delta = ft[i].end - ft[i].start; | |
| 257 } | |
| 258 delta -= 2*overhead; | |
| 259 if (delta < 0) delta = 0; | |
| 260 total += delta; | |
| 261 if (delta < min) min = delta; | |
| 262 if (delta > max) max = delta; | |
| 263 } | |
| 264 ave = total / nsamples; | |
| 265 total = 0; | |
| 266 for (i = 0; i < nsamples; i++) { | |
| 267 if (ft[i].end < ft[i].start) { | |
| 268 // Clock wrapped around (timer tick) | |
| 269 delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; | |
| 270 } else { | |
| 271 delta = ft[i].end - ft[i].start; | |
| 272 } | |
| 273 delta -= 2*overhead; | |
| 274 if (delta < 0) delta = 0; | |
| 275 total = (delta - ave) * (delta - ave); | |
| 276 } | |
| 277 var = total / (nsamples - 1); | |
| 278 diag_printf("%6d %6d %6d %6d %s\n", | |
| 279 ticks_to_us(ave), ticks_to_us(min), ticks_to_us(max), ticks_to_us(var), title); | |
| 280 } | |
| 281 | |
| 282 void | |
| 283 show_test_parameters(void) | |
| 284 { | |
| 285 diag_printf("\nTesting parameters:\n"); | |
| 286 diag_printf(" Clock samples: %3d\n", NSAMPLES); | |
| 287 diag_printf(" Threads: %3d\n", NTEST_THREADS); | |
| 288 diag_printf(" Thread switches: %3d\n", NTHREAD_SWITCHES); | |
| 289 diag_printf(" Mutexes: %3d\n", NMUTEXES); | |
| 290 diag_printf(" Mailboxes: %3d\n", NMBOXES); | |
| 291 diag_printf(" Semaphores: %3d\n", NSEMAPHORES); | |
| 292 diag_printf(" Scheduler operations: %3d\n", NSCHEDS); | |
| 293 diag_printf(" Counters: %3d\n", NCOUNTERS); | |
| 294 diag_printf(" Alarms: %3d\n", NALARMS); | |
| 295 diag_printf("\n"); | |
| 296 } | |
| 297 | |
| 298 void | |
| 299 run_thread_tests(void) | |
| 300 { | |
| 301 int i; | |
| 302 cyg_priority_t prio; | |
| 303 | |
| 304 // Set my priority higher than any I plan to create | |
| 305 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 306 | |
| 307 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 308 for (i = 0; i < NTEST_THREADS; i++) { | |
| 309 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 310 cyg_thread_create(10, // Priority - just a number | |
| 311 test0, // entry | |
| 312 i, // index | |
| 313 thread_name("thread", i), // Name | |
| 314 &stacks[i][0], // Stack | |
| 315 STACK_SIZE, // Size | |
| 316 &threads[i], // Handle | |
| 317 &test_threads[i] // Thread data structure | |
| 318 ); | |
| 319 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 320 } | |
| 321 show_times(thread_ft, NTEST_THREADS, "Create thread"); | |
| 322 | |
| 323 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 324 for (i = 0; i < NTEST_THREADS; i++) { | |
| 325 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 326 cyg_thread_yield(); | |
| 327 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 328 } | |
| 329 show_times(thread_ft, NTEST_THREADS, "Yield thread [all suspended]"); | |
| 330 | |
| 331 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 332 for (i = 0; i < NTEST_THREADS; i++) { | |
| 333 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 334 cyg_thread_suspend(threads[i]); | |
| 335 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 336 } | |
| 337 show_times(thread_ft, NTEST_THREADS, "Suspend [suspended] thread"); | |
| 338 | |
| 339 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 340 for (i = 0; i < NTEST_THREADS; i++) { | |
| 341 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 342 cyg_thread_resume(threads[i]); | |
| 343 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 344 } | |
| 345 show_times(thread_ft, NTEST_THREADS, "Resume thread"); | |
| 346 | |
| 347 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 348 for (i = 0; i < NTEST_THREADS; i++) { | |
| 349 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 350 cyg_thread_set_priority(threads[i], 11); | |
| 351 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 352 } | |
| 353 show_times(thread_ft, NTEST_THREADS, "Set priority"); | |
| 354 | |
| 355 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 356 for (i = 0; i < NTEST_THREADS; i++) { | |
| 357 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 358 prio = cyg_thread_get_priority(threads[i]); | |
| 359 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 360 } | |
| 361 show_times(thread_ft, NTEST_THREADS, "Get priority"); | |
| 362 | |
| 363 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 364 for (i = 0; i < NTEST_THREADS; i++) { | |
| 365 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 366 cyg_thread_kill(threads[i]); | |
| 367 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 368 } | |
| 369 show_times(thread_ft, NTEST_THREADS, "Kill [suspended] thread"); | |
| 370 | |
| 371 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 372 for (i = 0; i < NTEST_THREADS; i++) { | |
| 373 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 374 cyg_thread_yield(); | |
| 375 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 376 } | |
| 377 show_times(thread_ft, NTEST_THREADS, "Yield [no other] thread"); | |
| 378 | |
| 379 // Set my priority higher than any I plan to create | |
| 380 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 381 | |
| 382 // Recreate the test set | |
| 383 for (i = 0; i < NTEST_THREADS; i++) { | |
| 384 cyg_thread_create(10, // Priority - just a number | |
| 385 test0, // entry | |
| 386 i, // index | |
| 387 thread_name("thread", i), // Name | |
| 388 &stacks[i][0], // Stack | |
| 389 STACK_SIZE, // Size | |
| 390 &threads[i], // Handle | |
| 391 &test_threads[i] // Thread data structure | |
| 392 ); | |
| 393 } | |
| 394 | |
| 395 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 396 for (i = 0; i < NTEST_THREADS; i++) { | |
| 397 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 398 cyg_thread_resume(threads[i]); | |
| 399 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 400 } | |
| 401 show_times(thread_ft, NTEST_THREADS, "Resume [suspended low priority] thread"); | |
| 402 | |
| 403 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 404 for (i = 0; i < NTEST_THREADS; i++) { | |
| 405 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 406 cyg_thread_resume(threads[i]); | |
| 407 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 408 } | |
| 409 show_times(thread_ft, NTEST_THREADS, "Resume [runnable low priority] thread"); | |
| 410 | |
| 411 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 412 for (i = 0; i < NTEST_THREADS; i++) { | |
| 413 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 414 cyg_thread_suspend(threads[i]); | |
| 415 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 416 } | |
| 417 show_times(thread_ft, NTEST_THREADS, "Suspend [runnable] thread"); | |
| 418 | |
| 419 | |
| 420 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 421 for (i = 0; i < NTEST_THREADS; i++) { | |
| 422 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 423 cyg_thread_yield(); | |
| 424 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 425 } | |
| 426 show_times(thread_ft, NTEST_THREADS, "Yield [only low prio] thread"); | |
| 427 | |
| 428 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 429 for (i = 0; i < NTEST_THREADS; i++) { | |
| 430 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 431 cyg_thread_suspend(threads[i]); | |
| 432 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 433 } | |
| 434 show_times(thread_ft, NTEST_THREADS, "Suspend [runnable->not runnable] thread"); | |
| 435 for (i = 0; i < NTEST_THREADS; i++) { | |
| 436 cyg_thread_resume(threads[i]); | |
| 437 } | |
| 438 | |
| 439 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 440 for (i = 0; i < NTEST_THREADS; i++) { | |
| 441 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 442 cyg_thread_kill(threads[i]); | |
| 443 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 444 } | |
| 445 show_times(thread_ft, NTEST_THREADS, "Kill [runnable] thread"); | |
| 446 // Set my priority lower than any I plan to create | |
| 447 cyg_thread_set_priority(cyg_thread_self(), 3); | |
| 448 | |
| 449 // Set up the end-of-threads synchronizer | |
| 450 cyg_semaphore_init(&synchro, 0); | |
| 451 | |
| 452 // Recreate the test set | |
| 453 for (i = 0; i < NTEST_THREADS; i++) { | |
| 454 cyg_thread_create(2, // Priority - just a number | |
| 455 test1, // entry | |
| 456 i, // index | |
| 457 thread_name("thread", i), // Name | |
| 458 &stacks[i][0], // Stack | |
| 459 STACK_SIZE, // Size | |
| 460 &threads[i], // Handle | |
| 461 &test_threads[i] // Thread data structure | |
| 462 ); | |
| 463 } | |
| 464 | |
| 465 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 466 for (i = 0; i < NTEST_THREADS; i++) { | |
| 467 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 468 cyg_thread_resume(threads[i]); | |
| 469 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 470 } | |
| 471 show_times(thread_ft, NTEST_THREADS, "Resume [high priority] thread"); | |
| 472 cyg_semaphore_wait(&synchro); // Wait for all threads to finish | |
| 473 // Make sure they are all dead | |
| 474 for (i = 0; i < NTEST_THREADS; i++) { | |
| 475 cyg_thread_kill(threads[i]); | |
| 476 } | |
| 477 | |
| 478 run_thread_switch_test(); | |
| 479 } | |
| 480 | |
| 481 void | |
| 482 run_thread_switch_test(void) | |
| 483 { | |
| 484 int i; | |
| 485 | |
| 486 // Set up for thread context switch | |
| 487 for (i = 0; i < 2; i++) { | |
| 488 cyg_thread_create(10, // Priority - just a number | |
| 489 test2, // entry | |
| 490 i, // index | |
| 491 thread_name("thread", i), // Name | |
| 492 &stacks[i][0], // Stack | |
| 493 STACK_SIZE, // Size | |
| 494 &threads[i], // Handle | |
| 495 &test_threads[i] // Thread data structure | |
| 496 ); | |
| 497 cyg_thread_resume(threads[i]); | |
| 498 } | |
| 499 // Set up the end-of-threads synchronizer | |
| 500 cyg_semaphore_init(&synchro, 0); | |
| 501 cyg_semaphore_wait(&synchro); | |
| 502 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 503 show_times(test2_ft, NTHREAD_SWITCHES, "Thread switch"); | |
| 504 // Clean up | |
| 505 for (i = 0; i < 2; i++) { | |
| 506 cyg_thread_kill(threads[i]); | |
| 507 } | |
| 508 } | |
| 509 | |
| 510 void | |
| 511 run_mutex_tests(void) | |
| 512 { | |
| 513 int i; | |
| 514 | |
| 515 // Mutex primitives | |
| 516 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 517 for (i = 0; i < NMUTEXES; i++) { | |
| 518 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 519 cyg_mutex_init(&test_mutexes[i]); | |
| 520 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 521 } | |
| 522 show_times(mutex_ft, NMUTEXES, "Init mutex"); | |
| 523 | |
| 524 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 525 for (i = 0; i < NMUTEXES; i++) { | |
| 526 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 527 cyg_mutex_lock(&test_mutexes[i]); | |
| 528 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 529 } | |
| 530 show_times(mutex_ft, NMUTEXES, "Lock [unlocked] mutex"); | |
| 531 | |
| 532 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 533 for (i = 0; i < NMUTEXES; i++) { | |
| 534 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 535 cyg_mutex_unlock(&test_mutexes[i]); | |
| 536 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 537 } | |
| 538 show_times(mutex_ft, NMUTEXES, "Unlock [locked] mutex"); | |
| 539 | |
| 540 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 541 for (i = 0; i < NMUTEXES; i++) { | |
| 542 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 543 cyg_mutex_trylock(&test_mutexes[i]); | |
| 544 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 545 } | |
| 546 show_times(mutex_ft, NMUTEXES, "Trylock [unlocked] mutex"); | |
| 547 | |
| 548 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 549 for (i = 0; i < NMUTEXES; i++) { | |
| 550 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 551 cyg_mutex_trylock(&test_mutexes[i]); | |
| 552 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 553 } | |
| 554 show_times(mutex_ft, NMUTEXES, "Trylock [locked] mutex"); | |
| 555 | |
| 556 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 557 for (i = 0; i < NMUTEXES; i++) { | |
| 558 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 559 cyg_mutex_destroy(&test_mutexes[i]); | |
| 560 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 561 } | |
| 562 show_times(mutex_ft, NMUTEXES, "Destroy mutex"); | |
| 563 run_mutex_circuit_test(); | |
| 564 } | |
| 565 | |
| 566 void | |
| 567 run_mutex_circuit_test(void) | |
| 568 { | |
| 569 int i; | |
| 570 // Set my priority lower than any I plan to create | |
| 571 cyg_thread_set_priority(cyg_thread_self(), 4); | |
| 572 // Set up for full mutex unlock/lock test | |
| 573 cyg_mutex_init(&test_mutexes[0]); | |
| 574 cyg_semaphore_init(&synchro, 0); | |
| 575 cyg_thread_create(3, // Priority - just a number | |
| 576 mutex_test, // entry | |
| 577 0, // index | |
| 578 thread_name("thread", 0), // Name | |
| 579 &stacks[0][0], // Stack | |
| 580 STACK_SIZE, // Size | |
| 581 &mutex_test_thread_handle, // Handle | |
| 582 &mutex_test_thread // Thread data structure | |
| 583 ); | |
| 584 cyg_thread_resume(mutex_test_thread_handle); | |
| 585 // Need to raise priority so that this thread will block on the "lock" | |
| 586 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 587 for (i = 0; i < NMUTEXES; i++) { | |
| 588 cyg_semaphore_post(&synchro); | |
| 589 cyg_mutex_lock(&test_mutexes[0]); | |
| 590 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 591 cyg_mutex_unlock(&test_mutexes[0]); | |
| 592 cyg_semaphore_wait(&synchro); | |
| 593 } | |
| 594 show_times(mutex_ft, NMUTEXES, "Unlock/Lock mutex"); | |
| 595 } | |
| 596 | |
| 597 void | |
| 598 run_mbox_tests(void) | |
| 599 { | |
| 600 int i, cnt; | |
| 601 void *item; | |
| 602 // Mailbox primitives | |
| 603 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 604 for (i = 0; i < NMBOXES; i++) { | |
| 605 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 606 cyg_mbox_create(&test_mbox_handles[i], &test_mboxes[i]); | |
| 607 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 608 } | |
| 609 show_times(mbox_ft, NMBOXES, "Create mbox"); | |
| 610 | |
| 611 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 612 for (i = 0; i < NMBOXES; i++) { | |
| 613 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 614 cnt = cyg_mbox_peek(test_mbox_handles[i]); | |
| 615 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 616 } | |
| 617 show_times(mbox_ft, NMBOXES, "Peek [empty] mbox"); | |
| 618 | |
| 619 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 620 for (i = 0; i < NMBOXES; i++) { | |
| 621 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 622 cyg_mbox_put(test_mbox_handles[i], (void *)i); | |
| 623 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 624 } | |
| 625 show_times(mbox_ft, NMBOXES, "Put [first] mbox"); | |
| 626 | |
| 627 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 628 for (i = 0; i < NMBOXES; i++) { | |
| 629 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 630 cnt = cyg_mbox_peek(test_mbox_handles[i]); | |
| 631 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 632 } | |
| 633 show_times(mbox_ft, NMBOXES, "Peek [1 msg] mbox"); | |
| 634 | |
| 635 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 636 for (i = 0; i < NMBOXES; i++) { | |
| 637 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 638 cyg_mbox_put(test_mbox_handles[i], (void *)i); | |
| 639 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 640 } | |
| 641 show_times(mbox_ft, NMBOXES, "Put [second] mbox"); | |
| 642 | |
| 643 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 644 for (i = 0; i < NMBOXES; i++) { | |
| 645 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 646 cnt = cyg_mbox_peek(test_mbox_handles[i]); | |
| 647 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 648 } | |
| 649 show_times(mbox_ft, NMBOXES, "Peek [2 msgs] mbox"); | |
| 650 | |
| 651 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 652 for (i = 0; i < NMBOXES; i++) { | |
| 653 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 654 item = cyg_mbox_get(test_mbox_handles[i]); | |
| 655 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 656 } | |
| 657 show_times(mbox_ft, NMBOXES, "Get [first] mbox"); | |
| 658 | |
| 659 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 660 for (i = 0; i < NMBOXES; i++) { | |
| 661 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 662 item = cyg_mbox_get(test_mbox_handles[i]); | |
| 663 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 664 } | |
| 665 show_times(mbox_ft, NMBOXES, "Get [second] mbox"); | |
| 666 | |
| 667 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 668 for (i = 0; i < NMBOXES; i++) { | |
| 669 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 670 cyg_mbox_tryput(test_mbox_handles[i], (void *)i); | |
| 671 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 672 } | |
| 673 show_times(mbox_ft, NMBOXES, "Tryput [first] mbox"); | |
| 674 | |
| 675 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 676 for (i = 0; i < NMBOXES; i++) { | |
| 677 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 678 item = cyg_mbox_peek_item(test_mbox_handles[i]); | |
| 679 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 680 } | |
| 681 show_times(mbox_ft, NMBOXES, "Peek item [non-empty] mbox"); | |
| 682 | |
| 683 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 684 for (i = 0; i < NMBOXES; i++) { | |
| 685 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 686 item = cyg_mbox_tryget(test_mbox_handles[i]); | |
| 687 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 688 } | |
| 689 show_times(mbox_ft, NMBOXES, "Tryget [non-empty] mbox"); | |
| 690 | |
| 691 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 692 for (i = 0; i < NMBOXES; i++) { | |
| 693 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 694 item = cyg_mbox_peek_item(test_mbox_handles[i]); | |
| 695 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 696 } | |
| 697 show_times(mbox_ft, NMBOXES, "Peek item [empty] mbox"); | |
| 698 | |
| 699 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 700 for (i = 0; i < NMBOXES; i++) { | |
| 701 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 702 item = cyg_mbox_tryget(test_mbox_handles[i]); | |
| 703 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 704 } | |
| 705 show_times(mbox_ft, NMBOXES, "Tryget [empty] mbox"); | |
| 706 | |
| 707 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 708 for (i = 0; i < NMBOXES; i++) { | |
| 709 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 710 cyg_mbox_waiting_to_get(test_mbox_handles[i]); | |
| 711 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 712 } | |
| 713 show_times(mbox_ft, NMBOXES, "Waiting to get mbox"); | |
| 714 | |
| 715 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 716 for (i = 0; i < NMBOXES; i++) { | |
| 717 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 718 cyg_mbox_waiting_to_put(test_mbox_handles[i]); | |
| 719 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 720 } | |
| 721 show_times(mbox_ft, NMBOXES, "Waiting to put mbox"); | |
| 722 | |
| 723 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 724 for (i = 0; i < NMBOXES; i++) { | |
| 725 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 726 cyg_mbox_delete(test_mbox_handles[i]); | |
| 727 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 728 } | |
| 729 show_times(mbox_ft, NMBOXES, "Delete mbox"); | |
| 730 | |
| 731 run_mbox_circuit_test(); | |
| 732 } | |
| 733 | |
| 734 void | |
| 735 run_mbox_circuit_test(void) | |
| 736 { | |
| 737 int i; | |
| 738 // Set my priority lower than any I plan to create | |
| 739 cyg_thread_set_priority(cyg_thread_self(), 3); | |
| 740 // Set up for full mbox put/get test | |
| 741 cyg_mbox_create(&test_mbox_handles[0], &test_mboxes[0]); | |
| 742 cyg_semaphore_init(&synchro, 0); | |
| 743 cyg_thread_create(2, // Priority - just a number | |
| 744 mbox_test, // entry | |
| 745 0, // index | |
| 746 thread_name("thread", 0), // Name | |
| 747 &stacks[0][0], // Stack | |
| 748 STACK_SIZE, // Size | |
| 749 &mbox_test_thread_handle, // Handle | |
| 750 &mbox_test_thread // Thread data structure | |
| 751 ); | |
| 752 cyg_thread_resume(mbox_test_thread_handle); | |
| 753 for (i = 0; i < NMBOXES; i++) { | |
| 754 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 755 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 756 cyg_mbox_put(test_mbox_handles[0], (void *)i); | |
| 757 cyg_semaphore_wait(&synchro); | |
| 758 } | |
| 759 show_times(mbox_ft, NMBOXES, "Put/Get mbox"); | |
| 760 } | |
| 761 | |
| 762 void | |
| 763 run_semaphore_tests(void) | |
| 764 { | |
| 765 int i; | |
| 766 cyg_ucount32 sem_val; | |
| 767 // Semaphore primitives | |
| 768 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 769 for (i = 0; i < NSEMAPHORES; i++) { | |
| 770 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 771 cyg_semaphore_init(&test_semaphores[i], 0); | |
| 772 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 773 } | |
| 774 show_times(semaphore_ft, NSEMAPHORES, "Init semaphore"); | |
| 775 | |
| 776 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 777 for (i = 0; i < NSEMAPHORES; i++) { | |
| 778 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 779 cyg_semaphore_post(&test_semaphores[i]); | |
| 780 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 781 } | |
| 782 show_times(semaphore_ft, NSEMAPHORES, "Post [0] semaphore"); | |
| 783 | |
| 784 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 785 for (i = 0; i < NSEMAPHORES; i++) { | |
| 786 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 787 cyg_semaphore_wait(&test_semaphores[i]); | |
| 788 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 789 } | |
| 790 show_times(semaphore_ft, NSEMAPHORES, "Wait [1] semaphore"); | |
| 791 | |
| 792 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 793 for (i = 0; i < NSEMAPHORES; i++) { | |
| 794 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 795 cyg_semaphore_trywait(&test_semaphores[i]); | |
| 796 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 797 } | |
| 798 show_times(semaphore_ft, NSEMAPHORES, "Trywait [0] semaphore"); | |
| 799 | |
| 800 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 801 for (i = 0; i < NSEMAPHORES; i++) { | |
| 802 cyg_semaphore_post(&test_semaphores[i]); | |
| 803 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 804 cyg_semaphore_trywait(&test_semaphores[i]); | |
| 805 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 806 } | |
| 807 show_times(semaphore_ft, NSEMAPHORES, "Trywait [1] semaphore"); | |
| 808 | |
| 809 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 810 for (i = 0; i < NSEMAPHORES; i++) { | |
| 811 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 812 cyg_semaphore_peek(&test_semaphores[i], &sem_val); | |
| 813 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 814 } | |
| 815 show_times(semaphore_ft, NSEMAPHORES, "Peek semaphore"); | |
| 816 | |
| 817 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 818 for (i = 0; i < NSEMAPHORES; i++) { | |
| 819 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 820 cyg_semaphore_destroy(&test_semaphores[i]); | |
| 821 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 822 } | |
| 823 show_times(semaphore_ft, NSEMAPHORES, "Destroy semaphore"); | |
| 824 | |
| 825 run_semaphore_circuit_test(); | |
| 826 } | |
| 827 | |
| 828 void | |
| 829 run_semaphore_circuit_test(void) | |
| 830 { | |
| 831 int i; | |
| 832 // Set my priority lower than any I plan to create | |
| 833 cyg_thread_set_priority(cyg_thread_self(), 3); | |
| 834 // Set up for full semaphore post/wait test | |
| 835 cyg_semaphore_init(&test_semaphores[0], 0); | |
| 836 cyg_semaphore_init(&synchro, 0); | |
| 837 cyg_thread_create(2, // Priority - just a number | |
| 838 semaphore_test, // entry | |
| 839 0, // index | |
| 840 thread_name("thread", 0), // Name | |
| 841 &stacks[0][0], // Stack | |
| 842 STACK_SIZE, // Size | |
| 843 &semaphore_test_thread_handle, // Handle | |
| 844 &semaphore_test_thread // Thread data structure | |
| 845 ); | |
| 846 cyg_thread_resume(semaphore_test_thread_handle); | |
| 847 for (i = 0; i < NSEMAPHORES; i++) { | |
| 848 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 849 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 850 cyg_semaphore_post(&test_semaphores[0]); | |
| 851 cyg_semaphore_wait(&synchro); | |
| 852 } | |
| 853 show_times(semaphore_ft, NSEMAPHORES, "Post/Wait semaphore"); | |
| 854 } | |
| 855 | |
| 856 void | |
| 857 run_counter_tests(void) | |
| 858 { | |
| 859 int i; | |
| 860 cyg_tick_count_t val; | |
| 861 | |
| 862 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 863 for (i = 0; i < NCOUNTERS; i++) { | |
| 864 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 865 cyg_counter_create(&counters[i], &test_counters[i]); | |
| 866 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 867 } | |
| 868 show_times(counter_ft, NCOUNTERS, "Create counter"); | |
| 869 | |
| 870 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 871 for (i = 0; i < NCOUNTERS; i++) { | |
| 872 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 873 val = cyg_counter_current_value(counters[i]); | |
| 874 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 875 } | |
| 876 show_times(counter_ft, NCOUNTERS, "Get counter value"); | |
| 877 | |
| 878 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 879 for (i = 0; i < NCOUNTERS; i++) { | |
| 880 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 881 cyg_counter_set_value(counters[i], val); | |
| 882 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 883 } | |
| 884 show_times(counter_ft, NCOUNTERS, "Set counter value"); | |
| 885 | |
| 886 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 887 for (i = 0; i < NCOUNTERS; i++) { | |
| 888 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 889 cyg_counter_tick(counters[i]); | |
| 890 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 891 } | |
| 892 show_times(counter_ft, NCOUNTERS, "Tick counter"); | |
| 893 | |
| 894 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 895 for (i = 0; i < NCOUNTERS; i++) { | |
| 896 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 897 cyg_counter_delete(counters[i]); | |
| 898 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 899 } | |
| 900 show_times(counter_ft, NCOUNTERS, "Delete counter"); | |
| 901 } | |
| 902 | |
| 903 // Alarm callback function | |
| 904 void | |
| 905 alarm_cb(cyg_handle_t alarm, cyg_addrword_t val) | |
| 906 { | |
| 907 // empty call back | |
| 908 } | |
| 909 | |
| 910 // Callback used to test determinancy | |
| 911 static volatile int alarm_cnt; | |
| 912 void | |
| 913 alarm_cb2(cyg_handle_t alarm, cyg_addrword_t indx) | |
| 914 { | |
| 915 if (alarm_cnt == NSCHEDS) return; | |
| 916 sched_ft[alarm_cnt].start = 0; | |
| 917 HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end); | |
| 918 if (alarm_cnt == NSCHEDS) { | |
| 919 cyg_semaphore_post(&synchro); | |
| 920 } | |
| 921 } | |
| 922 | |
| 923 // Null thread, used to keep scheduler busy | |
| 924 void | |
| 925 alarm_test(cyg_uint32 id) | |
| 926 { | |
| 927 while (true) { | |
| 928 cyg_thread_yield(); | |
| 929 } | |
| 930 } | |
| 931 | |
| 932 void | |
| 933 run_alarm_tests(void) | |
| 934 { | |
| 935 int i; | |
| 936 cyg_tick_count_t init_val, step_val; | |
| 937 cyg_handle_t rtc_handle; | |
| 938 | |
| 939 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 940 for (i = 0; i < NCOUNTERS; i++) { | |
| 941 cyg_counter_create(&counters[i], &test_counters[i]); | |
| 942 } | |
| 943 for (i = 0; i < NALARMS; i++) { | |
| 944 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 945 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]); | |
| 946 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 947 } | |
| 948 show_times(alarm_ft, NALARMS, "Create alarm"); | |
| 949 | |
| 950 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 951 init_val = 0; step_val = 0; | |
| 952 for (i = 0; i < NALARMS; i++) { | |
| 953 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 954 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 955 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 956 } | |
| 957 show_times(alarm_ft, NALARMS, "Initialize alarm"); | |
| 958 | |
| 959 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 960 init_val = 0; step_val = 0; | |
| 961 for (i = 0; i < NALARMS; i++) { | |
| 962 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 963 cyg_alarm_disable(alarms[i]); | |
| 964 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 965 } | |
| 966 show_times(alarm_ft, NALARMS, "Disable alarm"); | |
| 967 | |
| 968 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 969 init_val = 0; step_val = 0; | |
| 970 for (i = 0; i < NALARMS; i++) { | |
| 971 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 972 cyg_alarm_enable(alarms[i]); | |
| 973 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 974 } | |
| 975 show_times(alarm_ft, NALARMS, "Enable alarm"); | |
| 976 | |
| 977 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 978 for (i = 0; i < NALARMS; i++) { | |
| 979 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 980 cyg_alarm_delete(alarms[i]); | |
| 981 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 982 } | |
| 983 show_times(alarm_ft, NALARMS, "Delete alarm"); | |
| 984 | |
| 985 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 986 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 987 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]); | |
| 988 init_val = 9999; step_val = 9999; | |
| 989 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 990 cyg_alarm_enable(alarms[0]); | |
| 991 for (i = 0; i < NCOUNTERS; i++) { | |
| 992 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 993 cyg_counter_tick(counters[0]); | |
| 994 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 995 } | |
| 996 show_times(counter_ft, NCOUNTERS, "Tick counter [1 alarm]"); | |
| 997 | |
| 998 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 999 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 1000 for (i = 0; i < NALARMS; i++) { | |
| 1001 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]); | |
| 1002 init_val = 9999; step_val = 9999; | |
| 1003 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 1004 cyg_alarm_enable(alarms[i]); | |
| 1005 } | |
| 1006 for (i = 0; i < NCOUNTERS; i++) { | |
| 1007 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 1008 cyg_counter_tick(counters[0]); | |
| 1009 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1010 } | |
| 1011 show_times(counter_ft, NCOUNTERS, "Tick counter [many alarms]"); | |
| 1012 | |
| 1013 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1014 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 1015 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]); | |
| 1016 init_val = 1; step_val = 1; | |
| 1017 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1018 cyg_alarm_enable(alarms[0]); | |
| 1019 for (i = 0; i < NCOUNTERS; i++) { | |
| 1020 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 1021 cyg_counter_tick(counters[0]); | |
| 1022 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1023 } | |
| 1024 show_times(counter_ft, NCOUNTERS, "Tick & fire counter [1 alarm]"); | |
| 1025 | |
| 1026 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1027 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 1028 for (i = 0; i < NALARMS; i++) { | |
| 1029 cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]); | |
| 1030 init_val = 1; step_val = 1; | |
| 1031 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 1032 cyg_alarm_enable(alarms[i]); | |
| 1033 } | |
| 1034 for (i = 0; i < NCOUNTERS; i++) { | |
| 1035 HAL_CLOCK_READ(&counter_ft[i].start); | |
| 1036 cyg_counter_tick(counters[0]); | |
| 1037 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1038 } | |
| 1039 for (i = 0; i < NALARMS; i++) { | |
| 1040 cyg_alarm_delete(alarms[i]); | |
| 1041 } | |
| 1042 show_times(counter_ft, NCOUNTERS, "Tick & fire counter [many alarms]"); | |
| 1043 | |
| 1044 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1045 cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); | |
| 1046 cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); | |
| 1047 init_val = 5; step_val = 5; alarm_cnt = 0; | |
| 1048 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1049 cyg_semaphore_init(&synchro, 0); | |
| 1050 cyg_alarm_enable(alarms[0]); | |
| 1051 cyg_semaphore_wait(&synchro); | |
| 1052 cyg_alarm_disable(alarms[0]); | |
| 1053 cyg_alarm_delete(alarms[0]); | |
| 1054 show_times(sched_ft, NSCHEDS, "Alarm latency [0 threads]"); | |
| 1055 | |
| 1056 // Set my priority higher than any I plan to create | |
| 1057 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1058 for (i = 0; i < 2; i++) { | |
| 1059 cyg_thread_create(10, // Priority - just a number | |
| 1060 alarm_test, // entry | |
| 1061 i, // index | |
| 1062 thread_name("thread", i), // Name | |
| 1063 &stacks[i][0], // Stack | |
| 1064 STACK_SIZE, // Size | |
| 1065 &threads[i], // Handle | |
| 1066 &test_threads[i] // Thread data structure | |
| 1067 ); | |
| 1068 cyg_thread_resume(threads[i]); | |
| 1069 } | |
| 1070 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1071 cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); | |
| 1072 cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); | |
| 1073 init_val = 5; step_val = 5; alarm_cnt = 0; | |
| 1074 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1075 cyg_semaphore_init(&synchro, 0); | |
| 1076 cyg_alarm_enable(alarms[0]); | |
| 1077 cyg_semaphore_wait(&synchro); | |
| 1078 cyg_alarm_disable(alarms[0]); | |
| 1079 cyg_alarm_delete(alarms[0]); | |
| 1080 show_times(sched_ft, NSCHEDS, "Alarm latency [2 threads]"); | |
| 1081 for (i = 0; i < 2; i++) { | |
| 1082 cyg_thread_suspend(threads[i]); | |
| 1083 cyg_thread_kill(threads[i]); | |
| 1084 } | |
| 1085 | |
| 1086 // Set my priority higher than any I plan to create | |
| 1087 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1088 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1089 cyg_thread_create(10, // Priority - just a number | |
| 1090 alarm_test, // entry | |
| 1091 i, // index | |
| 1092 thread_name("thread", i), // Name | |
| 1093 &stacks[i][0], // Stack | |
| 1094 STACK_SIZE, // Size | |
| 1095 &threads[i], // Handle | |
| 1096 &test_threads[i] // Thread data structure | |
| 1097 ); | |
| 1098 cyg_thread_resume(threads[i]); | |
| 1099 } | |
| 1100 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1101 cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); | |
| 1102 cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); | |
| 1103 init_val = 5; step_val = 5; alarm_cnt = 0; | |
| 1104 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1105 cyg_semaphore_init(&synchro, 0); | |
| 1106 cyg_alarm_enable(alarms[0]); | |
| 1107 cyg_semaphore_wait(&synchro); | |
| 1108 cyg_alarm_disable(alarms[0]); | |
| 1109 cyg_alarm_delete(alarms[0]); | |
| 1110 show_times(sched_ft, NSCHEDS, "Alarm latency [many threads]"); | |
| 1111 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1112 cyg_thread_suspend(threads[i]); | |
| 1113 cyg_thread_kill(threads[i]); | |
| 1114 } | |
| 1115 } | |
| 1116 | |
| 1117 void | |
| 1118 run_sched_tests(void) | |
| 1119 { | |
| 1120 int i; | |
| 1121 | |
| 1122 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1123 for (i = 0; i < NSCHEDS; i++) { | |
| 1124 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1125 cyg_scheduler_lock(); | |
| 1126 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1127 cyg_scheduler_unlock(); | |
| 1128 } | |
| 1129 show_times(sched_ft, NSCHEDS, "Scheduler lock"); | |
| 1130 | |
| 1131 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1132 for (i = 0; i < NSCHEDS; i++) { | |
| 1133 cyg_scheduler_lock(); | |
| 1134 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1135 cyg_scheduler_unlock(); | |
| 1136 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1137 } | |
| 1138 show_times(sched_ft, NSCHEDS, "Scheduler unlock [0 threads]"); | |
| 1139 | |
| 1140 // Set my priority higher than any I plan to create | |
| 1141 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1142 for (i = 0; i < 1; i++) { | |
| 1143 cyg_thread_create(10, // Priority - just a number | |
| 1144 test0, // entry | |
| 1145 i, // index | |
| 1146 thread_name("thread", i), // Name | |
| 1147 &stacks[i][0], // Stack | |
| 1148 STACK_SIZE, // Size | |
| 1149 &threads[i], // Handle | |
| 1150 &test_threads[i] // Thread data structure | |
| 1151 ); | |
| 1152 } | |
| 1153 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1154 for (i = 0; i < NSCHEDS; i++) { | |
| 1155 cyg_scheduler_lock(); | |
| 1156 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1157 cyg_scheduler_unlock(); | |
| 1158 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1159 } | |
| 1160 show_times(sched_ft, NSCHEDS, "Scheduler unlock [1 suspended thread]"); | |
| 1161 for (i = 0; i < 1; i++) { | |
| 1162 cyg_thread_kill(threads[i]); | |
| 1163 } | |
| 1164 | |
| 1165 // Set my priority higher than any I plan to create | |
| 1166 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1167 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1168 cyg_thread_create(10, // Priority - just a number | |
| 1169 test0, // entry | |
| 1170 i, // index | |
| 1171 thread_name("thread", i), // Name | |
| 1172 &stacks[i][0], // Stack | |
| 1173 STACK_SIZE, // Size | |
| 1174 &threads[i], // Handle | |
| 1175 &test_threads[i] // Thread data structure | |
| 1176 ); | |
| 1177 } | |
| 1178 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1179 for (i = 0; i < NSCHEDS; i++) { | |
| 1180 cyg_scheduler_lock(); | |
| 1181 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1182 cyg_scheduler_unlock(); | |
| 1183 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1184 } | |
| 1185 show_times(sched_ft, NSCHEDS, "Scheduler unlock [many suspended threads]"); | |
| 1186 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1187 cyg_thread_kill(threads[i]); | |
| 1188 } | |
| 1189 | |
| 1190 // Set my priority higher than any I plan to create | |
| 1191 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1192 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1193 cyg_thread_create(10, // Priority - just a number | |
| 1194 test0, // entry | |
| 1195 i, // index | |
| 1196 thread_name("thread", i), // Name | |
| 1197 &stacks[i][0], // Stack | |
| 1198 STACK_SIZE, // Size | |
| 1199 &threads[i], // Handle | |
| 1200 &test_threads[i] // Thread data structure | |
| 1201 ); | |
| 1202 cyg_thread_resume(threads[i]); | |
| 1203 } | |
| 1204 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1205 for (i = 0; i < NSCHEDS; i++) { | |
| 1206 cyg_scheduler_lock(); | |
| 1207 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1208 cyg_scheduler_unlock(); | |
| 1209 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1210 } | |
| 1211 show_times(sched_ft, NSCHEDS, "Scheduler unlock [many low prio threads]"); | |
| 1212 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1213 cyg_thread_kill(threads[i]); | |
| 1214 } | |
| 1215 } | |
| 1216 | |
| 1217 void | |
| 1218 run_all_tests(CYG_ADDRESS id) | |
| 1219 { | |
| 1220 int i; | |
| 1221 cyg_uint32 tv[NSAMPLES], tv0, tv1, us; | |
| 1222 cyg_tick_count_t ticks; | |
| 1223 #ifdef CYG_SCHEDULER_LOCK_TIMINGS | |
| 1224 cyg_uint32 lock_ave, lock_max; | |
| 1225 #endif | |
| 1226 #ifdef HAL_CLOCK_LATENCY | |
| 1227 cyg_int32 clock_ave; | |
| 1228 #endif | |
| 1229 | |
| 1230 for (i = 0; i < NSAMPLES; i++) { | |
| 1231 HAL_CLOCK_READ(&tv[i]); | |
| 1232 } | |
| 1233 diag_printf("Clock: "); | |
| 1234 tv0 = 0; | |
| 1235 for (i = 0; i < NSAMPLES; i++) { | |
| 1236 diag_printf("%x ", tv[i]); | |
| 1237 if (i > 0) { | |
| 1238 tv0 += tv[i] - tv[i-1]; | |
| 1239 } | |
| 1240 } | |
| 1241 diag_printf("\n"); | |
| 1242 | |
| 1243 overhead = tv0 / (NSAMPLES-1); | |
| 1244 diag_printf("Average %d clock ticks overhead\n", overhead); | |
| 1245 | |
| 1246 // Try and measure how long the clock interrupt handling takes | |
| 1247 HAL_CLOCK_READ(&tv0); | |
| 1248 while (true) { | |
| 1249 HAL_CLOCK_READ(&tv1); | |
| 1250 if (tv1 < tv0) break; | |
| 1251 tv0 = tv1; | |
| 1252 } | |
| 1253 tv1 -= overhead; // Adjust out the cost of getting the timer value | |
| 1254 us = ticks_to_us(tv1); | |
| 1255 diag_printf("Clock interrupt took %d microseconds (%d clock ticks)\n", us, tv1); | |
| 1256 | |
| 1257 ticks = cyg_current_time(); | |
| 1258 diag_printf("Ticks: %x\n", (int)ticks); | |
| 1259 | |
| 1260 show_test_parameters(); | |
| 1261 show_times_hdr(); | |
| 1262 | |
| 1263 run_thread_tests(); | |
| 1264 run_sched_tests(); | |
| 1265 run_mutex_tests(); | |
| 1266 run_mbox_tests(); | |
| 1267 run_semaphore_tests(); | |
| 1268 run_counter_tests(); | |
| 1269 run_alarm_tests(); | |
| 1270 | |
| 1271 #ifdef CYG_SCHEDULER_LOCK_TIMINGS | |
| 1272 Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max); | |
| 1273 diag_printf("\nMax lock: %d, Ave lock: %d\n", ticks_to_us(lock_max), ticks_to_us(lock_ave)); | |
| 1274 #endif | |
| 1275 | |
| 1276 #ifdef HAL_CLOCK_LATENCY | |
| 1277 clock_ave = total_clock_latency / total_clock_interrupts; | |
| 1278 diag_printf("\nClock/interrupt latency - ave: %d, min: %d, max: %d\n", | |
| 1279 ticks_to_us(clock_ave), ticks_to_us(min_clock_latency), ticks_to_us(max_clock_latency)); | |
| 1280 #endif | |
| 1281 | |
| 1282 ticks = cyg_current_time(); | |
| 1283 diag_printf("\nTiming complete - %d ms total\n", (int)ticks*10); | |
| 1284 | |
| 1285 CYG_TEST_PASS_FINISH("Basic timing OK"); | |
| 1286 } | |
| 1287 | |
| 1288 void tm_basic_main( void ) | |
| 1289 { | |
| 1290 CYG_TEST_INIT(); | |
| 1291 | |
| 1292 new_thread(run_all_tests, 0); | |
| 1293 | |
| 1294 Cyg_Scheduler::scheduler.start(); | |
| 1295 } | |
| 1296 | |
| 1297 externC void | |
| 1298 cyg_start( void ) | |
| 1299 { | |
| 1300 tm_basic_main(); | |
| 1301 } | |
| 1302 // EOF tm_basic.cxx |
