Mercurial > flash_v2
annotate packages/kernel/current/tests/tm_basic.cxx @ 4:1d7f19c9e4d1 ecos-sw-1999-05-11
Merge from eCos master repository on 1999-05-11-21:11:10-BST
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 14:07:25 +0000 |
| parents | 443894e2e912 |
| children | ece80412419a |
| rev | line source |
|---|---|
| 0 | 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 | |
| 2 | 25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
| 0 | 26 // ------------------------------------------- |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //========================================================================== | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 32 // Author(s): gthomas | |
| 33 // Contributors: gthomas | |
| 34 // Date: 1998-10-19 | |
| 2 | 35 // Description: Very simple kernel timing test |
| 0 | 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> | |
| 2 | 51 |
| 52 // Define this to see the statistics with the first sample datum removed. | |
| 53 // This can expose the effects of caches on the speed of operations. | |
| 54 #undef STATS_WITHOUT_FIRST_SAMPLE | |
| 55 | |
| 56 #if defined(CYGFUN_KERNEL_API_C) && \ | |
| 57 defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \ | |
| 58 defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \ | |
| 59 !defined(CYGPKG_HAL_I386_LINUX) && \ | |
| 60 (CYGNUM_KERNEL_SCHED_PRIORITIES > 12) | |
| 61 | |
| 0 | 62 #define NTHREADS 1 |
| 63 #include "testaux.hxx" | |
| 64 | |
| 65 // Structure used to keep track of times | |
| 66 typedef struct fun_times { | |
| 67 cyg_uint32 start; | |
| 68 cyg_uint32 end; | |
| 69 } fun_times; | |
| 70 | |
| 2 | 71 #define NSAMPLES 32 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
72 #define NTEST_THREADS 16 |
| 0 | 73 #define NTHREAD_SWITCHES 128 |
| 74 #define NMUTEXES 32 | |
| 75 #define NMBOXES 32 | |
| 76 #define NSEMAPHORES 32 | |
| 77 #define NSCHEDS 128 | |
| 78 #define NCOUNTERS 32 | |
| 79 #define NALARMS 32 | |
| 80 | |
| 2 | 81 #define NSAMPLES_SIM 2 |
| 82 #define NTEST_THREADS_SIM 2 | |
| 83 #define NTHREAD_SWITCHES_SIM 4 | |
| 84 #define NMUTEXES_SIM 2 | |
| 85 #define NMBOXES_SIM 2 | |
| 86 #define NSEMAPHORES_SIM 2 | |
| 87 #define NSCHEDS_SIM 4 | |
| 88 #define NCOUNTERS_SIM 2 | |
| 89 #define NALARMS_SIM 2 | |
| 90 | |
| 91 static int nsamples; | |
| 92 static int ntest_threads; | |
| 93 static int nthread_switches; | |
| 94 static int nmutexes; | |
| 95 static int nmboxes; | |
| 96 static int nsemaphores; | |
| 97 static int nscheds; | |
| 98 static int ncounters; | |
| 99 static int nalarms; | |
| 100 | |
| 101 #define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM | |
| 102 | |
| 0 | 103 static char stacks[NTEST_THREADS][STACK_SIZE]; |
| 104 static cyg_thread test_threads[NTEST_THREADS]; | |
| 105 static cyg_handle_t threads[NTEST_THREADS]; | |
| 106 static int overhead; | |
| 107 static cyg_sem_t synchro; | |
| 108 static fun_times thread_ft[NTEST_THREADS]; | |
| 109 | |
| 110 static fun_times test2_ft[NTHREAD_SWITCHES]; | |
| 111 | |
| 112 static cyg_mutex_t test_mutexes[NMUTEXES]; | |
| 113 static fun_times mutex_ft[NMUTEXES]; | |
| 114 static cyg_thread mutex_test_thread; | |
| 115 static cyg_handle_t mutex_test_thread_handle; | |
| 116 | |
| 117 static cyg_mbox test_mboxes[NMBOXES]; | |
| 118 static cyg_handle_t test_mbox_handles[NMBOXES]; | |
| 119 static fun_times mbox_ft[NMBOXES]; | |
| 120 static cyg_thread mbox_test_thread; | |
| 121 static cyg_handle_t mbox_test_thread_handle; | |
| 122 | |
| 123 static cyg_sem_t test_semaphores[NSEMAPHORES]; | |
| 124 static fun_times semaphore_ft[NSEMAPHORES]; | |
| 125 static cyg_thread semaphore_test_thread; | |
| 126 static cyg_handle_t semaphore_test_thread_handle; | |
| 127 | |
| 128 static fun_times sched_ft[NSCHEDS]; | |
| 129 | |
| 130 static cyg_counter test_counters[NCOUNTERS]; | |
| 131 static cyg_handle_t counters[NCOUNTERS]; | |
| 132 static fun_times counter_ft[NCOUNTERS]; | |
| 133 | |
| 134 static cyg_alarm test_alarms[NALARMS]; | |
| 135 static cyg_handle_t alarms[NALARMS]; | |
| 136 static fun_times alarm_ft[NALARMS]; | |
| 137 | |
| 2 | 138 static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION; |
| 139 static long ns_per_system_clock; | |
| 140 | |
| 141 #ifdef HAL_CLOCK_LATENCY | |
| 142 // Data kept by kernel real time clock measuring clock interrupt latency | |
| 143 extern cyg_tick_count total_clock_latency, total_clock_interrupts; | |
| 144 extern cyg_int32 min_clock_latency, max_clock_latency; | |
| 145 extern bool measure_clock_latency; | |
| 146 #endif | |
| 147 | |
| 0 | 148 externC void diag_printf(const char *, ...); |
| 149 | |
| 150 void run_sched_tests(void); | |
| 151 void run_thread_tests(void); | |
| 152 void run_thread_switch_test(void); | |
| 153 void run_mutex_tests(void); | |
| 154 void run_mutex_circuit_test(void); | |
| 155 void run_mbox_tests(void); | |
| 156 void run_mbox_circuit_test(void); | |
| 157 void run_semaphore_tests(void); | |
| 158 void run_semaphore_circuit_test(void); | |
| 159 void run_counter_tests(void); | |
| 160 void run_alarm_tests(void); | |
| 161 | |
| 162 // Wait until a clock tick [real time clock] has passed. This should keep it | |
| 163 // from happening again during a measurement, thus minimizing any fluctuations | |
| 164 void | |
| 165 wait_for_tick(void) | |
| 166 { | |
| 2 | 167 cyg_tick_count_t tv0, tv1; |
| 168 tv0 = cyg_current_time(); | |
| 0 | 169 while (true) { |
| 2 | 170 tv1 = cyg_current_time(); |
| 171 if (tv1 != tv0) break; | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 // Display a number of ticks as microseconds | |
| 176 // Note: for improved calculation significance, values are kept in ticks*1000 | |
| 177 void | |
| 178 show_ticks_in_us(cyg_uint32 ticks) | |
| 179 { | |
| 180 long long ns; | |
| 181 ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; | |
| 182 ns += 5; // for rounding to .01us | |
| 183 diag_printf("%5d.%02d", (int)(ns/1000), (int)((ns%1000)/10)); | |
| 184 } | |
| 185 | |
| 186 // | |
| 187 // If the kernel is instrumented to measure clock interrupt latency, these | |
| 188 // measurements can be drastically perturbed by printing via "diag_printf()" | |
| 189 // since that code may run with interrupts disabled for long periods. | |
| 190 // | |
| 191 // In order to get accurate/reasonable latency figures _for the kernel | |
| 192 // primitive functions beint tested_, the kernel's latency measurements | |
| 193 // are suspended while the printing actually takes place. | |
| 194 // | |
| 195 // The measurements are reenabled after the printing, thus allowing for | |
| 196 // fair measurements of the kernel primitives, which are not distorted | |
| 197 // by the printing mechanisms. | |
| 198 | |
| 199 #ifdef HAL_CLOCK_LATENCY | |
| 200 void | |
| 201 disable_clock_latency_measurement(void) | |
| 202 { | |
| 203 wait_for_tick(); | |
| 204 measure_clock_latency = false; | |
| 205 } | |
| 206 | |
| 207 void | |
| 208 enable_clock_latency_measurement(void) | |
| 209 { | |
| 210 wait_for_tick(); | |
| 211 measure_clock_latency = true; | |
| 212 } | |
| 213 | |
| 214 // Ensure that the measurements are reasonable (no startup anomalies) | |
| 215 void | |
| 216 reset_clock_latency_measurement(void) | |
| 217 { | |
| 218 disable_clock_latency_measurement(); | |
| 219 total_clock_latency = 0; | |
| 220 total_clock_interrupts = 0; | |
| 221 min_clock_latency = 0x7FFFFFFF; | |
| 222 max_clock_latency = 0; | |
| 223 enable_clock_latency_measurement(); | |
| 224 } | |
| 225 #else | |
| 226 #define disable_clock_latency_measurement() | |
| 227 #define enable_clock_latency_measurement() | |
| 228 #define reset_clock_latency_measurement() | |
| 229 #endif | |
| 230 | |
| 231 void | |
| 232 show_times_hdr(void) | |
| 233 { | |
| 234 disable_clock_latency_measurement(); | |
| 235 diag_printf("\n"); | |
| 236 diag_printf(" Confidence\n"); | |
| 237 diag_printf(" Ave Min Max Var Ave Min Function\n"); | |
| 238 diag_printf(" ====== ====== ====== ====== ========== ========\n"); | |
| 239 enable_clock_latency_measurement(); | |
| 240 } | |
| 241 | |
| 242 void | |
| 243 show_times_detail(fun_times ft[], int nsamples, char *title, bool ignore_first) | |
| 244 { | |
| 245 int i, delta, min, max, con_ave, con_min, ave_dev; | |
| 246 int start_sample, total_samples; | |
| 247 cyg_int32 total, ave; | |
| 248 | |
| 249 if (ignore_first) { | |
| 250 start_sample = 1; | |
| 251 total_samples = nsamples-1; | |
| 252 } else { | |
| 253 start_sample = 0; | |
| 254 total_samples = nsamples; | |
| 0 | 255 } |
| 2 | 256 total = 0; |
| 257 min = 0x7FFFFFFF; | |
| 258 max = 0; | |
| 259 for (i = start_sample; i < nsamples; i++) { | |
| 260 if (ft[i].end < ft[i].start) { | |
| 261 // Clock wrapped around (timer tick) | |
| 262 delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; | |
| 263 } else { | |
| 264 delta = ft[i].end - ft[i].start; | |
| 265 } | |
| 266 delta -= overhead; | |
| 267 if (delta < 0) delta = 0; | |
| 268 delta *= 1000; | |
| 269 total += delta; | |
| 270 if (delta < min) min = delta; | |
| 271 if (delta > max) max = delta; | |
| 272 } | |
| 273 ave = total / total_samples; | |
| 274 total = 0; | |
| 275 ave_dev = 0; | |
| 276 for (i = start_sample; i < nsamples; i++) { | |
| 277 if (ft[i].end < ft[i].start) { | |
| 278 // Clock wrapped around (timer tick) | |
| 279 delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; | |
| 280 } else { | |
| 281 delta = ft[i].end - ft[i].start; | |
| 282 } | |
| 283 delta -= overhead; | |
| 284 if (delta < 0) delta = 0; | |
| 285 delta *= 1000; | |
| 286 delta = delta - ave; | |
| 287 if (delta < 0) delta = -delta; | |
| 288 ave_dev += delta; | |
| 289 } | |
| 290 ave_dev /= total_samples; | |
| 291 con_ave = 0; | |
| 292 con_min = 0; | |
| 293 for (i = start_sample; i < nsamples; i++) { | |
| 294 if (ft[i].end < ft[i].start) { | |
| 295 // Clock wrapped around (timer tick) | |
| 296 delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; | |
| 297 } else { | |
| 298 delta = ft[i].end - ft[i].start; | |
| 299 } | |
| 300 delta -= overhead; | |
| 301 if (delta < 0) delta = 0; | |
| 302 delta *= 1000; | |
| 303 if ((delta <= (ave+ave_dev)) && (delta >= (ave-ave_dev))) con_ave++; | |
| 304 if ((delta <= (min+ave_dev)) && (delta >= (min-ave_dev))) con_min++; | |
| 305 } | |
| 306 con_ave = (con_ave * 100) / total_samples; | |
| 307 con_min = (con_min * 100) / total_samples; | |
| 308 show_ticks_in_us(ave); | |
| 309 show_ticks_in_us(min); | |
| 310 show_ticks_in_us(max); | |
| 311 show_ticks_in_us(ave_dev); | |
| 312 disable_clock_latency_measurement(); | |
| 313 diag_printf(" %3d%% %3d%%", con_ave, con_min); | |
| 314 diag_printf(" %s\n", title); | |
| 315 enable_clock_latency_measurement(); | |
| 316 } | |
| 317 | |
| 318 void | |
| 319 show_times(fun_times ft[], int nsamples, char *title) | |
| 320 { | |
| 321 show_times_detail(ft, nsamples, title, false); | |
| 322 #ifdef STATS_WITHOUT_FIRST_SAMPLE | |
| 323 show_times_detail(ft, nsamples, "", true); | |
| 324 #endif | |
| 325 } | |
| 326 | |
| 327 void | |
| 328 show_test_parameters(void) | |
| 329 { | |
| 330 disable_clock_latency_measurement(); | |
| 331 diag_printf("\nTesting parameters:\n"); | |
| 332 diag_printf(" Clock samples: %3d\n", nsamples); | |
| 333 diag_printf(" Threads: %3d\n", ntest_threads); | |
| 334 diag_printf(" Thread switches: %3d\n", nthread_switches); | |
| 335 diag_printf(" Mutexes: %3d\n", nmutexes); | |
| 336 diag_printf(" Mailboxes: %3d\n", nmboxes); | |
| 337 diag_printf(" Semaphores: %3d\n", nsemaphores); | |
| 338 diag_printf(" Scheduler operations: %3d\n", nscheds); | |
| 339 diag_printf(" Counters: %3d\n", ncounters); | |
| 340 diag_printf(" Alarms: %3d\n", nalarms); | |
| 341 diag_printf("\n"); | |
| 342 enable_clock_latency_measurement(); | |
| 343 } | |
| 344 | |
| 345 void | |
| 346 end_of_test_group(void) | |
| 347 { | |
| 348 disable_clock_latency_measurement(); | |
| 349 diag_printf("\n"); | |
| 350 enable_clock_latency_measurement(); | |
| 0 | 351 } |
| 352 | |
| 353 // Compute a name for a thread | |
| 354 char * | |
| 355 thread_name(char *basename, int indx) { | |
| 356 return "<<NULL>>"; // Not currently used | |
| 357 } | |
| 358 | |
| 359 // test0 - null test, never executed | |
| 360 void | |
| 361 test0(cyg_uint32 indx) | |
| 362 { | |
| 363 diag_printf("test0.%d executed?\n", indx); | |
| 364 cyg_thread_exit(); | |
| 365 } | |
| 366 | |
| 367 // test1 - empty test, simply exit. Last thread signals parent. | |
| 368 void | |
| 369 test1(cyg_uint32 indx) | |
| 370 { | |
| 2 | 371 if (indx == (cyg_uint32)(ntest_threads-1)) { |
| 0 | 372 cyg_semaphore_post(&synchro); // Signal that last thread is dying |
| 373 } | |
| 374 cyg_thread_exit(); | |
| 375 } | |
| 376 | |
| 377 // test2 - measure thread switch times | |
| 378 void | |
| 379 test2(cyg_uint32 indx) | |
| 380 { | |
| 381 int i; | |
| 2 | 382 for (i = 0; i < nthread_switches; i++) { |
| 0 | 383 if (indx == 0) { |
| 384 HAL_CLOCK_READ(&test2_ft[i].start); | |
| 385 } else { | |
| 386 HAL_CLOCK_READ(&test2_ft[i].end); | |
| 387 } | |
| 388 cyg_thread_yield(); | |
| 389 } | |
| 390 if (indx == 1) { | |
| 391 cyg_semaphore_post(&synchro); | |
| 392 } | |
| 393 cyg_thread_exit(); | |
| 394 } | |
| 395 | |
| 396 // Full-circuit mutex unlock/lock test | |
| 397 void | |
| 398 mutex_test(cyg_uint32 indx) | |
| 399 { | |
| 400 int i; | |
| 401 cyg_mutex_lock(&test_mutexes[0]); | |
| 2 | 402 for (i = 0; i < nmutexes; i++) { |
| 0 | 403 cyg_semaphore_wait(&synchro); |
| 404 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 405 HAL_CLOCK_READ(&mutex_ft[i].start); | |
| 406 cyg_mutex_unlock(&test_mutexes[0]); | |
| 407 cyg_mutex_lock(&test_mutexes[0]); | |
| 408 cyg_semaphore_post(&synchro); | |
| 409 } | |
| 410 cyg_thread_exit(); | |
| 411 } | |
| 412 | |
| 413 // Full-circuit mbox put/get test | |
| 414 void | |
| 415 mbox_test(cyg_uint32 indx) | |
| 416 { | |
| 417 void *item; | |
| 418 do { | |
| 419 item = cyg_mbox_get(test_mbox_handles[0]); | |
| 420 HAL_CLOCK_READ(&mbox_ft[(int)item].end); | |
| 421 cyg_semaphore_post(&synchro); | |
| 2 | 422 } while ((int)item != (nmboxes-1)); |
| 0 | 423 cyg_thread_exit(); |
| 424 } | |
| 425 | |
| 426 // Full-circuit semaphore post/wait test | |
| 427 void | |
| 428 semaphore_test(cyg_uint32 indx) | |
| 429 { | |
| 430 int i; | |
| 2 | 431 for (i = 0; i < nsemaphores; i++) { |
| 0 | 432 cyg_semaphore_wait(&test_semaphores[0]); |
| 433 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 434 cyg_semaphore_post(&synchro); | |
| 435 } | |
| 436 cyg_thread_exit(); | |
| 437 } | |
| 438 | |
| 2 | 439 // |
| 440 // This set of tests is used to measure kernel primitives that deal with threads | |
| 441 // | |
| 0 | 442 void |
| 443 run_thread_tests(void) | |
| 444 { | |
| 445 int i; | |
| 446 cyg_priority_t prio; | |
| 447 | |
| 448 // Set my priority higher than any I plan to create | |
| 449 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 450 | |
| 451 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 452 for (i = 0; i < ntest_threads; i++) { |
| 0 | 453 HAL_CLOCK_READ(&thread_ft[i].start); |
| 454 cyg_thread_create(10, // Priority - just a number | |
| 455 test0, // 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 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 464 } | |
| 2 | 465 show_times(thread_ft, ntest_threads, "Create thread"); |
| 0 | 466 |
| 467 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 468 for (i = 0; i < ntest_threads; i++) { |
| 0 | 469 HAL_CLOCK_READ(&thread_ft[i].start); |
| 470 cyg_thread_yield(); | |
| 471 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 472 } | |
| 2 | 473 show_times(thread_ft, ntest_threads, "Yield thread [all suspended]"); |
| 0 | 474 |
| 475 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 476 for (i = 0; i < ntest_threads; i++) { |
| 0 | 477 HAL_CLOCK_READ(&thread_ft[i].start); |
| 478 cyg_thread_suspend(threads[i]); | |
| 479 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 480 } | |
| 2 | 481 show_times(thread_ft, ntest_threads, "Suspend [suspended] thread"); |
| 0 | 482 |
| 483 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 484 for (i = 0; i < ntest_threads; i++) { |
| 0 | 485 HAL_CLOCK_READ(&thread_ft[i].start); |
| 486 cyg_thread_resume(threads[i]); | |
| 487 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 488 } | |
| 2 | 489 show_times(thread_ft, ntest_threads, "Resume thread"); |
| 0 | 490 |
| 491 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 492 for (i = 0; i < ntest_threads; i++) { |
| 0 | 493 HAL_CLOCK_READ(&thread_ft[i].start); |
| 494 cyg_thread_set_priority(threads[i], 11); | |
| 495 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 496 } | |
| 2 | 497 show_times(thread_ft, ntest_threads, "Set priority"); |
| 0 | 498 |
| 499 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 500 for (i = 0; i < ntest_threads; i++) { |
| 0 | 501 HAL_CLOCK_READ(&thread_ft[i].start); |
| 502 prio = cyg_thread_get_priority(threads[i]); | |
| 503 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 504 } | |
| 2 | 505 show_times(thread_ft, ntest_threads, "Get priority"); |
| 0 | 506 |
| 507 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 508 for (i = 0; i < ntest_threads; i++) { |
| 0 | 509 HAL_CLOCK_READ(&thread_ft[i].start); |
| 510 cyg_thread_kill(threads[i]); | |
| 511 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 512 } | |
| 2 | 513 show_times(thread_ft, ntest_threads, "Kill [suspended] thread"); |
| 0 | 514 |
| 515 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 516 for (i = 0; i < ntest_threads; i++) { |
| 0 | 517 HAL_CLOCK_READ(&thread_ft[i].start); |
| 518 cyg_thread_yield(); | |
| 519 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 520 } | |
| 2 | 521 show_times(thread_ft, ntest_threads, "Yield [no other] thread"); |
| 0 | 522 |
| 523 // Set my priority higher than any I plan to create | |
| 524 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 525 | |
| 526 // Recreate the test set | |
| 2 | 527 for (i = 0; i < ntest_threads; i++) { |
| 0 | 528 cyg_thread_create(10, // Priority - just a number |
| 529 test0, // entry | |
| 530 i, // index | |
| 531 thread_name("thread", i), // Name | |
| 532 &stacks[i][0], // Stack | |
| 533 STACK_SIZE, // Size | |
| 534 &threads[i], // Handle | |
| 535 &test_threads[i] // Thread data structure | |
| 536 ); | |
| 537 } | |
| 538 | |
| 539 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 540 for (i = 0; i < ntest_threads; i++) { |
| 541 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 542 cyg_thread_resume(threads[i]); | |
| 543 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 544 } | |
| 545 show_times(thread_ft, ntest_threads, "Resume [suspended low prio] thread"); | |
| 546 | |
| 547 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 548 for (i = 0; i < ntest_threads; i++) { | |
| 0 | 549 HAL_CLOCK_READ(&thread_ft[i].start); |
| 550 cyg_thread_resume(threads[i]); | |
| 551 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 552 } | |
| 2 | 553 show_times(thread_ft, ntest_threads, "Resume [runnable low prio] thread"); |
| 0 | 554 |
| 555 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 556 for (i = 0; i < ntest_threads; i++) { |
| 0 | 557 HAL_CLOCK_READ(&thread_ft[i].start); |
| 2 | 558 cyg_thread_suspend(threads[i]); |
| 0 | 559 HAL_CLOCK_READ(&thread_ft[i].end); |
| 560 } | |
| 2 | 561 show_times(thread_ft, ntest_threads, "Suspend [runnable] thread"); |
| 562 | |
| 0 | 563 |
| 564 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 565 for (i = 0; i < ntest_threads; i++) { |
| 566 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 567 cyg_thread_yield(); | |
| 568 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 569 } | |
| 570 show_times(thread_ft, ntest_threads, "Yield [only low prio] thread"); | |
| 571 | |
| 572 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 573 for (i = 0; i < ntest_threads; i++) { | |
| 0 | 574 HAL_CLOCK_READ(&thread_ft[i].start); |
| 575 cyg_thread_suspend(threads[i]); | |
| 576 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 577 } | |
| 2 | 578 show_times(thread_ft, ntest_threads, "Suspend [runnable->not runnable]"); |
| 579 for (i = 0; i < ntest_threads; i++) { | |
| 0 | 580 cyg_thread_resume(threads[i]); |
| 581 } | |
| 582 | |
| 583 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 584 for (i = 0; i < ntest_threads; i++) { |
| 0 | 585 HAL_CLOCK_READ(&thread_ft[i].start); |
| 586 cyg_thread_kill(threads[i]); | |
| 587 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 588 } | |
| 2 | 589 show_times(thread_ft, ntest_threads, "Kill [runnable] thread"); |
| 590 | |
| 591 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 592 for (i = 0; i < ntest_threads; i++) { | |
| 593 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 594 cyg_thread_delete(threads[i]); | |
| 595 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 596 } | |
| 597 show_times(thread_ft, ntest_threads, "Destroy [dead] thread"); | |
| 598 | |
| 599 // Recreate the test set | |
| 600 for (i = 0; i < ntest_threads; i++) { | |
| 601 cyg_thread_create(10, // Priority - just a number | |
| 602 test0, // entry | |
| 603 i, // index | |
| 604 thread_name("thread", i), // Name | |
| 605 &stacks[i][0], // Stack | |
| 606 STACK_SIZE, // Size | |
| 607 &threads[i], // Handle | |
| 608 &test_threads[i] // Thread data structure | |
| 609 ); | |
| 610 cyg_thread_resume(threads[i]); | |
| 611 } | |
| 612 | |
| 613 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 614 for (i = 0; i < ntest_threads; i++) { | |
| 615 HAL_CLOCK_READ(&thread_ft[i].start); | |
| 616 cyg_thread_delete(threads[i]); | |
| 617 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 618 } | |
| 619 show_times(thread_ft, ntest_threads, "Destroy [runnable] thread"); | |
| 620 | |
| 0 | 621 // Set my priority lower than any I plan to create |
| 622 cyg_thread_set_priority(cyg_thread_self(), 3); | |
| 623 | |
| 624 // Set up the end-of-threads synchronizer | |
| 625 cyg_semaphore_init(&synchro, 0); | |
| 626 | |
| 627 // Recreate the test set | |
| 2 | 628 for (i = 0; i < ntest_threads; i++) { |
| 0 | 629 cyg_thread_create(2, // Priority - just a number |
| 630 test1, // entry | |
| 631 i, // index | |
| 632 thread_name("thread", i), // Name | |
| 633 &stacks[i][0], // Stack | |
| 634 STACK_SIZE, // Size | |
| 635 &threads[i], // Handle | |
| 636 &test_threads[i] // Thread data structure | |
| 637 ); | |
| 638 } | |
| 639 | |
| 640 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 641 for (i = 0; i < ntest_threads; i++) { |
| 0 | 642 HAL_CLOCK_READ(&thread_ft[i].start); |
| 643 cyg_thread_resume(threads[i]); | |
| 644 HAL_CLOCK_READ(&thread_ft[i].end); | |
| 645 } | |
| 2 | 646 show_times(thread_ft, ntest_threads, "Resume [high priority] thread"); |
| 0 | 647 cyg_semaphore_wait(&synchro); // Wait for all threads to finish |
| 648 // Make sure they are all dead | |
| 2 | 649 for (i = 0; i < ntest_threads; i++) { |
| 650 cyg_thread_delete(threads[i]); | |
| 0 | 651 } |
| 652 | |
| 653 run_thread_switch_test(); | |
| 2 | 654 end_of_test_group(); |
| 0 | 655 } |
| 656 | |
| 657 void | |
| 658 run_thread_switch_test(void) | |
| 659 { | |
| 660 int i; | |
| 661 | |
| 662 // Set up for thread context switch | |
| 663 for (i = 0; i < 2; i++) { | |
| 664 cyg_thread_create(10, // Priority - just a number | |
| 665 test2, // entry | |
| 666 i, // index | |
| 667 thread_name("thread", i), // Name | |
| 668 &stacks[i][0], // Stack | |
| 669 STACK_SIZE, // Size | |
| 670 &threads[i], // Handle | |
| 671 &test_threads[i] // Thread data structure | |
| 672 ); | |
| 673 cyg_thread_resume(threads[i]); | |
| 674 } | |
| 675 // Set up the end-of-threads synchronizer | |
| 676 cyg_semaphore_init(&synchro, 0); | |
| 677 cyg_semaphore_wait(&synchro); | |
| 678 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 679 show_times(test2_ft, nthread_switches, "Thread switch"); |
| 0 | 680 // Clean up |
| 681 for (i = 0; i < 2; i++) { | |
| 2 | 682 cyg_thread_delete(threads[i]); |
| 0 | 683 } |
| 684 } | |
| 685 | |
| 686 void | |
| 687 run_mutex_tests(void) | |
| 688 { | |
| 689 int i; | |
| 690 | |
| 691 // Mutex primitives | |
| 692 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 693 for (i = 0; i < nmutexes; i++) { |
| 0 | 694 HAL_CLOCK_READ(&mutex_ft[i].start); |
| 695 cyg_mutex_init(&test_mutexes[i]); | |
| 696 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 697 } | |
| 2 | 698 show_times(mutex_ft, nmutexes, "Init mutex"); |
| 0 | 699 |
| 700 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 701 for (i = 0; i < nmutexes; i++) { |
| 0 | 702 HAL_CLOCK_READ(&mutex_ft[i].start); |
| 703 cyg_mutex_lock(&test_mutexes[i]); | |
| 704 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 705 } | |
| 2 | 706 show_times(mutex_ft, nmutexes, "Lock [unlocked] mutex"); |
| 0 | 707 |
| 708 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 709 for (i = 0; i < nmutexes; i++) { |
| 0 | 710 HAL_CLOCK_READ(&mutex_ft[i].start); |
| 711 cyg_mutex_unlock(&test_mutexes[i]); | |
| 712 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 713 } | |
| 2 | 714 show_times(mutex_ft, nmutexes, "Unlock [locked] mutex"); |
| 0 | 715 |
| 716 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 717 for (i = 0; i < nmutexes; i++) { |
| 0 | 718 HAL_CLOCK_READ(&mutex_ft[i].start); |
| 719 cyg_mutex_trylock(&test_mutexes[i]); | |
| 720 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 721 } | |
| 2 | 722 show_times(mutex_ft, nmutexes, "Trylock [unlocked] mutex"); |
| 0 | 723 |
| 724 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 725 for (i = 0; i < nmutexes; i++) { |
| 0 | 726 HAL_CLOCK_READ(&mutex_ft[i].start); |
| 727 cyg_mutex_trylock(&test_mutexes[i]); | |
| 728 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 729 } | |
| 2 | 730 show_times(mutex_ft, nmutexes, "Trylock [locked] mutex"); |
| 0 | 731 |
| 732 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 733 for (i = 0; i < nmutexes; i++) { |
| 0 | 734 HAL_CLOCK_READ(&mutex_ft[i].start); |
| 735 cyg_mutex_destroy(&test_mutexes[i]); | |
| 736 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 737 } | |
| 2 | 738 show_times(mutex_ft, nmutexes, "Destroy mutex"); |
| 0 | 739 run_mutex_circuit_test(); |
| 2 | 740 end_of_test_group(); |
| 0 | 741 } |
| 742 | |
| 743 void | |
| 744 run_mutex_circuit_test(void) | |
| 745 { | |
| 746 int i; | |
| 747 // Set my priority lower than any I plan to create | |
| 748 cyg_thread_set_priority(cyg_thread_self(), 4); | |
| 749 // Set up for full mutex unlock/lock test | |
| 750 cyg_mutex_init(&test_mutexes[0]); | |
| 751 cyg_semaphore_init(&synchro, 0); | |
| 752 cyg_thread_create(3, // Priority - just a number | |
| 753 mutex_test, // entry | |
| 754 0, // index | |
| 755 thread_name("thread", 0), // Name | |
| 756 &stacks[0][0], // Stack | |
| 757 STACK_SIZE, // Size | |
| 758 &mutex_test_thread_handle, // Handle | |
| 759 &mutex_test_thread // Thread data structure | |
| 760 ); | |
| 761 cyg_thread_resume(mutex_test_thread_handle); | |
| 762 // Need to raise priority so that this thread will block on the "lock" | |
| 763 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 2 | 764 for (i = 0; i < nmutexes; i++) { |
| 0 | 765 cyg_semaphore_post(&synchro); |
| 766 cyg_mutex_lock(&test_mutexes[0]); | |
| 767 HAL_CLOCK_READ(&mutex_ft[i].end); | |
| 768 cyg_mutex_unlock(&test_mutexes[0]); | |
| 769 cyg_semaphore_wait(&synchro); | |
| 770 } | |
| 2 | 771 cyg_thread_delete(mutex_test_thread_handle); |
| 772 show_times(mutex_ft, nmutexes, "Unlock/Lock mutex"); | |
| 0 | 773 } |
| 774 | |
| 775 void | |
| 776 run_mbox_tests(void) | |
| 777 { | |
| 778 int i, cnt; | |
| 779 void *item; | |
| 780 // Mailbox primitives | |
| 781 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 782 for (i = 0; i < nmboxes; i++) { |
| 0 | 783 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 784 cyg_mbox_create(&test_mbox_handles[i], &test_mboxes[i]); | |
| 785 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 786 } | |
| 2 | 787 show_times(mbox_ft, nmboxes, "Create mbox"); |
| 0 | 788 |
| 789 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 790 for (i = 0; i < nmboxes; i++) { |
| 0 | 791 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 792 cnt = cyg_mbox_peek(test_mbox_handles[i]); | |
| 793 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 794 } | |
| 2 | 795 show_times(mbox_ft, nmboxes, "Peek [empty] mbox"); |
| 0 | 796 |
| 2 | 797 #ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT |
| 0 | 798 wait_for_tick(); // Wait until the next clock tick to minimize aberations |
| 2 | 799 for (i = 0; i < nmboxes; i++) { |
| 0 | 800 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 801 cyg_mbox_put(test_mbox_handles[i], (void *)i); | |
| 802 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 803 } | |
| 2 | 804 show_times(mbox_ft, nmboxes, "Put [first] mbox"); |
| 0 | 805 |
| 806 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 807 for (i = 0; i < nmboxes; i++) { |
| 0 | 808 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 809 cnt = cyg_mbox_peek(test_mbox_handles[i]); | |
| 810 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 811 } | |
| 2 | 812 show_times(mbox_ft, nmboxes, "Peek [1 msg] mbox"); |
| 0 | 813 |
| 814 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 815 for (i = 0; i < nmboxes; i++) { |
| 816 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 817 cyg_mbox_put(test_mbox_handles[i], (void *)i); | |
| 818 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 819 } | |
| 820 show_times(mbox_ft, nmboxes, "Put [second] mbox"); | |
| 821 | |
| 822 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 823 for (i = 0; i < nmboxes; i++) { | |
| 824 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 825 cnt = cyg_mbox_peek(test_mbox_handles[i]); | |
| 826 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 827 } | |
| 828 show_times(mbox_ft, nmboxes, "Peek [2 msgs] mbox"); | |
| 829 | |
| 830 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 831 for (i = 0; i < nmboxes; i++) { | |
| 0 | 832 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 833 item = cyg_mbox_get(test_mbox_handles[i]); | |
| 834 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 835 } | |
| 2 | 836 show_times(mbox_ft, nmboxes, "Get [first] mbox"); |
| 0 | 837 |
| 838 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 839 for (i = 0; i < nmboxes; i++) { |
| 0 | 840 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 841 item = cyg_mbox_get(test_mbox_handles[i]); | |
| 842 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 843 } | |
| 2 | 844 show_times(mbox_ft, nmboxes, "Get [second] mbox"); |
| 845 #endif // ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT | |
| 0 | 846 |
| 847 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 848 for (i = 0; i < nmboxes; i++) { |
| 0 | 849 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 850 cyg_mbox_tryput(test_mbox_handles[i], (void *)i); | |
| 851 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 852 } | |
| 2 | 853 show_times(mbox_ft, nmboxes, "Tryput [first] mbox"); |
| 0 | 854 |
| 855 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 856 for (i = 0; i < nmboxes; i++) { |
| 0 | 857 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 858 item = cyg_mbox_peek_item(test_mbox_handles[i]); | |
| 859 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 860 } | |
| 2 | 861 show_times(mbox_ft, nmboxes, "Peek item [non-empty] mbox"); |
| 0 | 862 |
| 863 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 864 for (i = 0; i < nmboxes; i++) { |
| 0 | 865 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 866 item = cyg_mbox_tryget(test_mbox_handles[i]); | |
| 867 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 868 } | |
| 2 | 869 show_times(mbox_ft, nmboxes, "Tryget [non-empty] mbox"); |
| 0 | 870 |
| 871 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 872 for (i = 0; i < nmboxes; i++) { |
| 0 | 873 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 874 item = cyg_mbox_peek_item(test_mbox_handles[i]); | |
| 875 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 876 } | |
| 2 | 877 show_times(mbox_ft, nmboxes, "Peek item [empty] mbox"); |
| 0 | 878 |
| 879 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 880 for (i = 0; i < nmboxes; i++) { |
| 0 | 881 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 882 item = cyg_mbox_tryget(test_mbox_handles[i]); | |
| 883 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 884 } | |
| 2 | 885 show_times(mbox_ft, nmboxes, "Tryget [empty] mbox"); |
| 0 | 886 |
| 887 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 888 for (i = 0; i < nmboxes; i++) { |
| 0 | 889 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 890 cyg_mbox_waiting_to_get(test_mbox_handles[i]); | |
| 891 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 892 } | |
| 2 | 893 show_times(mbox_ft, nmboxes, "Waiting to get mbox"); |
| 0 | 894 |
| 895 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 896 for (i = 0; i < nmboxes; i++) { |
| 0 | 897 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 898 cyg_mbox_waiting_to_put(test_mbox_handles[i]); | |
| 899 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 900 } | |
| 2 | 901 show_times(mbox_ft, nmboxes, "Waiting to put mbox"); |
| 0 | 902 |
| 903 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 904 for (i = 0; i < nmboxes; i++) { |
| 0 | 905 HAL_CLOCK_READ(&mbox_ft[i].start); |
| 906 cyg_mbox_delete(test_mbox_handles[i]); | |
| 907 HAL_CLOCK_READ(&mbox_ft[i].end); | |
| 908 } | |
| 2 | 909 show_times(mbox_ft, nmboxes, "Delete mbox"); |
| 0 | 910 |
| 911 run_mbox_circuit_test(); | |
| 2 | 912 end_of_test_group(); |
| 0 | 913 } |
| 914 | |
| 915 void | |
| 916 run_mbox_circuit_test(void) | |
| 917 { | |
| 2 | 918 #ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT |
| 0 | 919 int i; |
| 920 // Set my priority lower than any I plan to create | |
| 921 cyg_thread_set_priority(cyg_thread_self(), 3); | |
| 922 // Set up for full mbox put/get test | |
| 923 cyg_mbox_create(&test_mbox_handles[0], &test_mboxes[0]); | |
| 924 cyg_semaphore_init(&synchro, 0); | |
| 925 cyg_thread_create(2, // Priority - just a number | |
| 926 mbox_test, // entry | |
| 927 0, // index | |
| 928 thread_name("thread", 0), // Name | |
| 929 &stacks[0][0], // Stack | |
| 930 STACK_SIZE, // Size | |
| 931 &mbox_test_thread_handle, // Handle | |
| 932 &mbox_test_thread // Thread data structure | |
| 933 ); | |
| 934 cyg_thread_resume(mbox_test_thread_handle); | |
| 2 | 935 for (i = 0; i < nmboxes; i++) { |
| 0 | 936 wait_for_tick(); // Wait until the next clock tick to minimize aberations |
| 937 HAL_CLOCK_READ(&mbox_ft[i].start); | |
| 938 cyg_mbox_put(test_mbox_handles[0], (void *)i); | |
| 939 cyg_semaphore_wait(&synchro); | |
| 940 } | |
| 2 | 941 cyg_thread_delete(mbox_test_thread_handle); |
| 942 show_times(mbox_ft, nmboxes, "Put/Get mbox"); | |
| 943 #endif | |
| 0 | 944 } |
| 945 | |
| 946 void | |
| 947 run_semaphore_tests(void) | |
| 948 { | |
| 949 int i; | |
| 2 | 950 cyg_count32 sem_val; |
| 0 | 951 // Semaphore primitives |
| 952 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 953 for (i = 0; i < nsemaphores; i++) { |
| 0 | 954 HAL_CLOCK_READ(&semaphore_ft[i].start); |
| 955 cyg_semaphore_init(&test_semaphores[i], 0); | |
| 956 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 957 } | |
| 2 | 958 show_times(semaphore_ft, nsemaphores, "Init semaphore"); |
| 0 | 959 |
| 960 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 961 for (i = 0; i < nsemaphores; i++) { |
| 0 | 962 HAL_CLOCK_READ(&semaphore_ft[i].start); |
| 963 cyg_semaphore_post(&test_semaphores[i]); | |
| 964 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 965 } | |
| 2 | 966 show_times(semaphore_ft, nsemaphores, "Post [0] semaphore"); |
| 0 | 967 |
| 968 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 969 for (i = 0; i < nsemaphores; i++) { |
| 0 | 970 HAL_CLOCK_READ(&semaphore_ft[i].start); |
| 971 cyg_semaphore_wait(&test_semaphores[i]); | |
| 972 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 973 } | |
| 2 | 974 show_times(semaphore_ft, nsemaphores, "Wait [1] semaphore"); |
| 0 | 975 |
| 976 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 977 for (i = 0; i < nsemaphores; i++) { |
| 0 | 978 HAL_CLOCK_READ(&semaphore_ft[i].start); |
| 979 cyg_semaphore_trywait(&test_semaphores[i]); | |
| 980 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 981 } | |
| 2 | 982 show_times(semaphore_ft, nsemaphores, "Trywait [0] semaphore"); |
| 0 | 983 |
| 984 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 985 for (i = 0; i < nsemaphores; i++) { |
| 0 | 986 cyg_semaphore_post(&test_semaphores[i]); |
| 987 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 988 cyg_semaphore_trywait(&test_semaphores[i]); | |
| 989 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 990 } | |
| 2 | 991 show_times(semaphore_ft, nsemaphores, "Trywait [1] semaphore"); |
| 0 | 992 |
| 993 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 994 for (i = 0; i < nsemaphores; i++) { |
| 0 | 995 HAL_CLOCK_READ(&semaphore_ft[i].start); |
| 996 cyg_semaphore_peek(&test_semaphores[i], &sem_val); | |
| 997 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 998 } | |
| 2 | 999 show_times(semaphore_ft, nsemaphores, "Peek semaphore"); |
| 0 | 1000 |
| 1001 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1002 for (i = 0; i < nsemaphores; i++) { |
| 0 | 1003 HAL_CLOCK_READ(&semaphore_ft[i].start); |
| 1004 cyg_semaphore_destroy(&test_semaphores[i]); | |
| 1005 HAL_CLOCK_READ(&semaphore_ft[i].end); | |
| 1006 } | |
| 2 | 1007 show_times(semaphore_ft, nsemaphores, "Destroy semaphore"); |
| 0 | 1008 |
| 1009 run_semaphore_circuit_test(); | |
| 2 | 1010 end_of_test_group(); |
| 0 | 1011 } |
| 1012 | |
| 1013 void | |
| 1014 run_semaphore_circuit_test(void) | |
| 1015 { | |
| 1016 int i; | |
| 1017 // Set my priority lower than any I plan to create | |
| 1018 cyg_thread_set_priority(cyg_thread_self(), 3); | |
| 1019 // Set up for full semaphore post/wait test | |
| 1020 cyg_semaphore_init(&test_semaphores[0], 0); | |
| 1021 cyg_semaphore_init(&synchro, 0); | |
| 1022 cyg_thread_create(2, // Priority - just a number | |
| 1023 semaphore_test, // entry | |
| 1024 0, // index | |
| 1025 thread_name("thread", 0), // Name | |
| 1026 &stacks[0][0], // Stack | |
| 1027 STACK_SIZE, // Size | |
| 1028 &semaphore_test_thread_handle, // Handle | |
| 1029 &semaphore_test_thread // Thread data structure | |
| 1030 ); | |
| 1031 cyg_thread_resume(semaphore_test_thread_handle); | |
| 2 | 1032 for (i = 0; i < nsemaphores; i++) { |
| 0 | 1033 wait_for_tick(); // Wait until the next clock tick to minimize aberations |
| 1034 HAL_CLOCK_READ(&semaphore_ft[i].start); | |
| 1035 cyg_semaphore_post(&test_semaphores[0]); | |
| 1036 cyg_semaphore_wait(&synchro); | |
| 1037 } | |
| 2 | 1038 cyg_thread_delete(semaphore_test_thread_handle); |
| 1039 show_times(semaphore_ft, nsemaphores, "Post/Wait semaphore"); | |
| 0 | 1040 } |
| 1041 | |
| 1042 void | |
| 1043 run_counter_tests(void) | |
| 1044 { | |
| 1045 int i; | |
| 2 | 1046 cyg_tick_count_t val=0; |
| 0 | 1047 |
| 1048 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1049 for (i = 0; i < ncounters; i++) { |
| 0 | 1050 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1051 cyg_counter_create(&counters[i], &test_counters[i]); | |
| 1052 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1053 } | |
| 2 | 1054 show_times(counter_ft, ncounters, "Create counter"); |
| 0 | 1055 |
| 1056 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1057 for (i = 0; i < ncounters; i++) { |
| 0 | 1058 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1059 val = cyg_counter_current_value(counters[i]); | |
| 1060 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1061 } | |
| 2 | 1062 show_times(counter_ft, ncounters, "Get counter value"); |
| 0 | 1063 |
| 1064 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1065 for (i = 0; i < ncounters; i++) { |
| 0 | 1066 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1067 cyg_counter_set_value(counters[i], val); | |
| 1068 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1069 } | |
| 2 | 1070 show_times(counter_ft, ncounters, "Set counter value"); |
| 0 | 1071 |
| 1072 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1073 for (i = 0; i < ncounters; i++) { |
| 0 | 1074 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1075 cyg_counter_tick(counters[i]); | |
| 1076 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1077 } | |
| 2 | 1078 show_times(counter_ft, ncounters, "Tick counter"); |
| 0 | 1079 |
| 1080 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1081 for (i = 0; i < ncounters; i++) { |
| 0 | 1082 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1083 cyg_counter_delete(counters[i]); | |
| 1084 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1085 } | |
| 2 | 1086 show_times(counter_ft, ncounters, "Delete counter"); |
| 1087 end_of_test_group(); | |
| 0 | 1088 } |
| 1089 | |
| 1090 // Alarm callback function | |
| 1091 void | |
| 1092 alarm_cb(cyg_handle_t alarm, cyg_addrword_t val) | |
| 1093 { | |
| 1094 // empty call back | |
| 1095 } | |
| 1096 | |
| 1097 // Callback used to test determinancy | |
| 1098 static volatile int alarm_cnt; | |
| 1099 void | |
| 1100 alarm_cb2(cyg_handle_t alarm, cyg_addrword_t indx) | |
| 1101 { | |
| 2 | 1102 if (alarm_cnt == nscheds) return; |
| 0 | 1103 sched_ft[alarm_cnt].start = 0; |
| 1104 HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end); | |
| 2 | 1105 if (alarm_cnt == nscheds) { |
| 0 | 1106 cyg_semaphore_post(&synchro); |
| 1107 } | |
| 1108 } | |
| 1109 | |
| 1110 // Null thread, used to keep scheduler busy | |
| 1111 void | |
| 1112 alarm_test(cyg_uint32 id) | |
| 1113 { | |
| 1114 while (true) { | |
| 1115 cyg_thread_yield(); | |
| 1116 } | |
| 1117 } | |
| 1118 | |
| 1119 void | |
| 1120 run_alarm_tests(void) | |
| 1121 { | |
| 1122 int i; | |
| 1123 cyg_tick_count_t init_val, step_val; | |
| 1124 cyg_handle_t rtc_handle; | |
| 1125 | |
| 1126 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1127 for (i = 0; i < ncounters; i++) { |
| 0 | 1128 cyg_counter_create(&counters[i], &test_counters[i]); |
| 1129 } | |
| 2 | 1130 for (i = 0; i < nalarms; i++) { |
| 0 | 1131 HAL_CLOCK_READ(&alarm_ft[i].start); |
| 1132 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]); | |
| 1133 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 1134 } | |
| 2 | 1135 show_times(alarm_ft, nalarms, "Create alarm"); |
| 0 | 1136 |
| 1137 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1138 init_val = 0; step_val = 0; | |
| 2 | 1139 for (i = 0; i < nalarms; i++) { |
| 0 | 1140 HAL_CLOCK_READ(&alarm_ft[i].start); |
| 1141 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 1142 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 1143 } | |
| 2 | 1144 show_times(alarm_ft, nalarms, "Initialize alarm"); |
| 0 | 1145 |
| 1146 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1147 init_val = 0; step_val = 0; | |
| 2 | 1148 for (i = 0; i < nalarms; i++) { |
| 0 | 1149 HAL_CLOCK_READ(&alarm_ft[i].start); |
| 1150 cyg_alarm_disable(alarms[i]); | |
| 1151 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 1152 } | |
| 2 | 1153 show_times(alarm_ft, nalarms, "Disable alarm"); |
| 0 | 1154 |
| 1155 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1156 init_val = 0; step_val = 0; | |
| 2 | 1157 for (i = 0; i < nalarms; i++) { |
| 0 | 1158 HAL_CLOCK_READ(&alarm_ft[i].start); |
| 1159 cyg_alarm_enable(alarms[i]); | |
| 1160 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 1161 } | |
| 2 | 1162 show_times(alarm_ft, nalarms, "Enable alarm"); |
| 0 | 1163 |
| 1164 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1165 for (i = 0; i < nalarms; i++) { |
| 0 | 1166 HAL_CLOCK_READ(&alarm_ft[i].start); |
| 1167 cyg_alarm_delete(alarms[i]); | |
| 1168 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 1169 } | |
| 2 | 1170 show_times(alarm_ft, nalarms, "Delete alarm"); |
| 0 | 1171 |
| 1172 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1173 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 1174 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]); | |
| 1175 init_val = 9999; step_val = 9999; | |
| 1176 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1177 cyg_alarm_enable(alarms[0]); | |
| 2 | 1178 for (i = 0; i < ncounters; i++) { |
| 0 | 1179 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1180 cyg_counter_tick(counters[0]); | |
| 1181 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1182 } | |
| 2 | 1183 show_times(counter_ft, ncounters, "Tick counter [1 alarm]"); |
| 0 | 1184 |
| 1185 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1186 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 2 | 1187 for (i = 0; i < nalarms; i++) { |
| 0 | 1188 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]); |
| 1189 init_val = 9999; step_val = 9999; | |
| 1190 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 1191 cyg_alarm_enable(alarms[i]); | |
| 1192 } | |
| 2 | 1193 for (i = 0; i < ncounters; i++) { |
| 0 | 1194 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1195 cyg_counter_tick(counters[0]); | |
| 1196 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1197 } | |
| 2 | 1198 show_times(counter_ft, ncounters, "Tick counter [many alarms]"); |
| 0 | 1199 |
| 1200 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1201 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 1202 cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]); | |
| 1203 init_val = 1; step_val = 1; | |
| 1204 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1205 cyg_alarm_enable(alarms[0]); | |
| 2 | 1206 for (i = 0; i < ncounters; i++) { |
| 0 | 1207 HAL_CLOCK_READ(&counter_ft[i].start); |
| 1208 cyg_counter_tick(counters[0]); | |
| 1209 HAL_CLOCK_READ(&counter_ft[i].end); | |
| 1210 } | |
| 2 | 1211 show_times(counter_ft, ncounters, "Tick & fire counter [1 alarm]"); |
| 0 | 1212 |
| 1213 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1214 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 2 | 1215 for (i = 0; i < nalarms; i++) { |
| 0 | 1216 cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]); |
| 1217 init_val = 1; step_val = 1; | |
| 1218 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 1219 cyg_alarm_enable(alarms[i]); | |
| 1220 } | |
| 2 | 1221 for (i = 0; i < nalarms; i++) { |
| 1222 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 0 | 1223 cyg_counter_tick(counters[0]); |
| 2 | 1224 HAL_CLOCK_READ(&alarm_ft[i].end); |
| 0 | 1225 } |
| 2 | 1226 for (i = 0; i < nalarms; i++) { |
| 0 | 1227 cyg_alarm_delete(alarms[i]); |
| 1228 } | |
| 2 | 1229 show_times(alarm_ft, nalarms, "Tick & fire counters [>1 together]"); |
| 1230 | |
| 1231 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1232 cyg_counter_create(&counters[0], &test_counters[0]); | |
| 1233 for (i = 0; i < nalarms; i++) { | |
| 1234 cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]); | |
| 1235 init_val = i+1; step_val = nalarms+1; | |
| 1236 cyg_alarm_initialize(alarms[i], init_val, step_val); | |
| 1237 cyg_alarm_enable(alarms[i]); | |
| 1238 } | |
| 1239 for (i = 0; i < nalarms; i++) { | |
| 1240 HAL_CLOCK_READ(&alarm_ft[i].start); | |
| 1241 cyg_counter_tick(counters[0]); | |
| 1242 HAL_CLOCK_READ(&alarm_ft[i].end); | |
| 1243 } | |
| 1244 for (i = 0; i < nalarms; i++) { | |
| 1245 cyg_alarm_delete(alarms[i]); | |
| 1246 } | |
| 1247 show_times(alarm_ft, nalarms, "Tick & fire counters [>1 separately]"); | |
| 0 | 1248 |
| 1249 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1250 cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); | |
| 1251 cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); | |
| 1252 init_val = 5; step_val = 5; alarm_cnt = 0; | |
| 1253 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1254 cyg_semaphore_init(&synchro, 0); | |
| 1255 cyg_alarm_enable(alarms[0]); | |
| 1256 cyg_semaphore_wait(&synchro); | |
| 1257 cyg_alarm_disable(alarms[0]); | |
| 1258 cyg_alarm_delete(alarms[0]); | |
| 2 | 1259 show_times(sched_ft, nscheds, "Alarm latency [0 threads]"); |
| 0 | 1260 |
| 1261 // Set my priority higher than any I plan to create | |
| 1262 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1263 for (i = 0; i < 2; i++) { | |
| 1264 cyg_thread_create(10, // Priority - just a number | |
| 1265 alarm_test, // entry | |
| 1266 i, // index | |
| 1267 thread_name("thread", i), // Name | |
| 1268 &stacks[i][0], // Stack | |
| 1269 STACK_SIZE, // Size | |
| 1270 &threads[i], // Handle | |
| 1271 &test_threads[i] // Thread data structure | |
| 1272 ); | |
| 1273 cyg_thread_resume(threads[i]); | |
| 1274 } | |
| 1275 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1276 cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); | |
| 1277 cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); | |
| 1278 init_val = 5; step_val = 5; alarm_cnt = 0; | |
| 1279 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1280 cyg_semaphore_init(&synchro, 0); | |
| 1281 cyg_alarm_enable(alarms[0]); | |
| 1282 cyg_semaphore_wait(&synchro); | |
| 1283 cyg_alarm_disable(alarms[0]); | |
| 1284 cyg_alarm_delete(alarms[0]); | |
| 2 | 1285 show_times(sched_ft, nscheds, "Alarm latency [2 threads]"); |
| 0 | 1286 for (i = 0; i < 2; i++) { |
| 1287 cyg_thread_suspend(threads[i]); | |
| 2 | 1288 cyg_thread_delete(threads[i]); |
| 0 | 1289 } |
| 1290 | |
| 1291 // Set my priority higher than any I plan to create | |
| 1292 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 2 | 1293 for (i = 0; i < ntest_threads; i++) { |
| 0 | 1294 cyg_thread_create(10, // Priority - just a number |
| 1295 alarm_test, // entry | |
| 1296 i, // index | |
| 1297 thread_name("thread", i), // Name | |
| 1298 &stacks[i][0], // Stack | |
| 1299 STACK_SIZE, // Size | |
| 1300 &threads[i], // Handle | |
| 1301 &test_threads[i] // Thread data structure | |
| 1302 ); | |
| 1303 cyg_thread_resume(threads[i]); | |
| 1304 } | |
| 1305 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 1306 cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); | |
| 1307 cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); | |
| 1308 init_val = 5; step_val = 5; alarm_cnt = 0; | |
| 1309 cyg_alarm_initialize(alarms[0], init_val, step_val); | |
| 1310 cyg_semaphore_init(&synchro, 0); | |
| 1311 cyg_alarm_enable(alarms[0]); | |
| 1312 cyg_semaphore_wait(&synchro); | |
| 1313 cyg_alarm_disable(alarms[0]); | |
| 1314 cyg_alarm_delete(alarms[0]); | |
| 2 | 1315 show_times(sched_ft, nscheds, "Alarm latency [many threads]"); |
| 1316 for (i = 0; i < ntest_threads; i++) { | |
| 0 | 1317 cyg_thread_suspend(threads[i]); |
| 2 | 1318 cyg_thread_delete(threads[i]); |
| 0 | 1319 } |
| 2 | 1320 end_of_test_group(); |
| 0 | 1321 } |
| 1322 | |
| 1323 void | |
| 1324 run_sched_tests(void) | |
| 1325 { | |
| 1326 int i; | |
| 1327 | |
| 1328 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1329 for (i = 0; i < nscheds; i++) { |
| 0 | 1330 HAL_CLOCK_READ(&sched_ft[i].start); |
| 1331 cyg_scheduler_lock(); | |
| 1332 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1333 cyg_scheduler_unlock(); | |
| 1334 } | |
| 2 | 1335 show_times(sched_ft, nscheds, "Scheduler lock"); |
| 0 | 1336 |
| 1337 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1338 for (i = 0; i < nscheds; i++) { |
| 0 | 1339 cyg_scheduler_lock(); |
| 1340 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1341 cyg_scheduler_unlock(); | |
| 1342 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1343 } | |
| 2 | 1344 show_times(sched_ft, nscheds, "Scheduler unlock [0 threads]"); |
| 0 | 1345 |
| 1346 // Set my priority higher than any I plan to create | |
| 1347 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 1348 for (i = 0; i < 1; i++) { | |
| 1349 cyg_thread_create(10, // Priority - just a number | |
| 1350 test0, // entry | |
| 1351 i, // index | |
| 1352 thread_name("thread", i), // Name | |
| 1353 &stacks[i][0], // Stack | |
| 1354 STACK_SIZE, // Size | |
| 1355 &threads[i], // Handle | |
| 1356 &test_threads[i] // Thread data structure | |
| 1357 ); | |
| 1358 } | |
| 1359 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1360 for (i = 0; i < nscheds; i++) { |
| 0 | 1361 cyg_scheduler_lock(); |
| 1362 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1363 cyg_scheduler_unlock(); | |
| 1364 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1365 } | |
| 2 | 1366 show_times(sched_ft, nscheds, "Scheduler unlock [1 suspended]"); |
| 0 | 1367 for (i = 0; i < 1; i++) { |
| 2 | 1368 cyg_thread_delete(threads[i]); |
| 0 | 1369 } |
| 1370 | |
| 1371 // Set my priority higher than any I plan to create | |
| 1372 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 2 | 1373 for (i = 0; i < ntest_threads; i++) { |
| 0 | 1374 cyg_thread_create(10, // Priority - just a number |
| 1375 test0, // entry | |
| 1376 i, // index | |
| 1377 thread_name("thread", i), // Name | |
| 1378 &stacks[i][0], // Stack | |
| 1379 STACK_SIZE, // Size | |
| 1380 &threads[i], // Handle | |
| 1381 &test_threads[i] // Thread data structure | |
| 1382 ); | |
| 1383 } | |
| 1384 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1385 for (i = 0; i < nscheds; i++) { |
| 0 | 1386 cyg_scheduler_lock(); |
| 1387 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1388 cyg_scheduler_unlock(); | |
| 1389 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1390 } | |
| 2 | 1391 show_times(sched_ft, nscheds, "Scheduler unlock [many suspended]"); |
| 1392 for (i = 0; i < ntest_threads; i++) { | |
| 1393 cyg_thread_delete(threads[i]); | |
| 0 | 1394 } |
| 1395 | |
| 1396 // Set my priority higher than any I plan to create | |
| 1397 cyg_thread_set_priority(cyg_thread_self(), 2); | |
| 2 | 1398 for (i = 0; i < ntest_threads; i++) { |
| 0 | 1399 cyg_thread_create(10, // Priority - just a number |
| 1400 test0, // entry | |
| 1401 i, // index | |
| 1402 thread_name("thread", i), // Name | |
| 1403 &stacks[i][0], // Stack | |
| 1404 STACK_SIZE, // Size | |
| 1405 &threads[i], // Handle | |
| 1406 &test_threads[i] // Thread data structure | |
| 1407 ); | |
| 1408 cyg_thread_resume(threads[i]); | |
| 1409 } | |
| 1410 wait_for_tick(); // Wait until the next clock tick to minimize aberations | |
| 2 | 1411 for (i = 0; i < nscheds; i++) { |
| 0 | 1412 cyg_scheduler_lock(); |
| 1413 HAL_CLOCK_READ(&sched_ft[i].start); | |
| 1414 cyg_scheduler_unlock(); | |
| 1415 HAL_CLOCK_READ(&sched_ft[i].end); | |
| 1416 } | |
| 2 | 1417 show_times(sched_ft, nscheds, "Scheduler unlock [many low prio]"); |
| 1418 for (i = 0; i < ntest_threads; i++) { | |
| 1419 cyg_thread_delete(threads[i]); | |
| 0 | 1420 } |
| 2 | 1421 end_of_test_group(); |
| 0 | 1422 } |
| 1423 | |
| 1424 void | |
| 1425 run_all_tests(CYG_ADDRESS id) | |
| 1426 { | |
| 2 | 1427 int i, j; |
| 1428 cyg_uint32 tv[nsamples], tv0, tv1; | |
| 1429 cyg_uint32 min_stack, max_stack, total_stack, actual_stack; | |
| 1430 cyg_tick_count_t ticks, tick0, tick1; | |
| 0 | 1431 #ifdef CYG_SCHEDULER_LOCK_TIMINGS |
| 1432 cyg_uint32 lock_ave, lock_max; | |
| 1433 #endif | |
| 1434 #ifdef HAL_CLOCK_LATENCY | |
| 1435 cyg_int32 clock_ave; | |
| 1436 #endif | |
| 1437 | |
| 2 | 1438 disable_clock_latency_measurement(); |
| 1439 diag_printf("\neCos Kernel Timings\n"); | |
| 1440 diag_printf("Notes: all times are in microseconds (.000001) unless otherwise stated\n"); | |
| 1441 #ifdef STATS_WITHOUT_FIRST_SAMPLE | |
| 1442 diag_printf(" second line of results have first sample removed\n"); | |
| 1443 #endif | |
| 1444 | |
| 1445 cyg_thread_delay(2); // Make sure the clock is actually running | |
| 1446 | |
| 1447 ns_per_system_clock = 1000000/rtc_resolution[1]; | |
| 1448 | |
| 1449 for (i = 0; i < nsamples; i++) { | |
| 0 | 1450 HAL_CLOCK_READ(&tv[i]); |
| 1451 } | |
| 1452 tv0 = 0; | |
| 2 | 1453 for (i = 1; i < nsamples; i++) { |
| 1454 tv0 += tv[i] - tv[i-1]; | |
| 0 | 1455 } |
| 2 | 1456 end_of_test_group(); |
| 0 | 1457 |
| 2 | 1458 overhead = tv0 / (nsamples-1); |
| 1459 diag_printf("Reading the hardware clock takes %d 'ticks' overhead\n", overhead); | |
| 1460 diag_printf("... this value will be factored out of all other measurements\n"); | |
| 0 | 1461 |
| 1462 // Try and measure how long the clock interrupt handling takes | |
| 2 | 1463 for (i = 0; i < nsamples; i++) { |
| 1464 tick0 = cyg_current_time(); | |
| 1465 while (true) { | |
| 1466 tick1 = cyg_current_time(); | |
| 1467 if (tick0 != tick1) break; | |
| 1468 } | |
| 1469 HAL_CLOCK_READ(&tv[i]); | |
| 0 | 1470 } |
| 2 | 1471 tv1 = 0; |
| 1472 for (i = 0; i < nsamples; i++) { | |
| 1473 tv1 += tv[i] * 1000; | |
| 1474 } | |
| 1475 tv1 = tv1 / nsamples; | |
| 0 | 1476 tv1 -= overhead; // Adjust out the cost of getting the timer value |
| 2 | 1477 diag_printf("Clock interrupt took"); |
| 1478 show_ticks_in_us(tv1); | |
| 1479 diag_printf(" microseconds (%d raw clock ticks)\n", tv1/1000); | |
| 1480 enable_clock_latency_measurement(); | |
| 0 | 1481 |
| 1482 ticks = cyg_current_time(); | |
| 1483 | |
| 1484 show_test_parameters(); | |
| 1485 show_times_hdr(); | |
| 1486 | |
| 2 | 1487 reset_clock_latency_measurement(); |
| 1488 | |
| 0 | 1489 run_thread_tests(); |
| 1490 run_sched_tests(); | |
| 1491 run_mutex_tests(); | |
| 1492 run_mbox_tests(); | |
| 1493 run_semaphore_tests(); | |
| 1494 run_counter_tests(); | |
| 1495 run_alarm_tests(); | |
| 1496 | |
| 1497 #ifdef CYG_SCHEDULER_LOCK_TIMINGS | |
| 1498 Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max); | |
| 2 | 1499 diag_printf("\nMax lock:"); |
| 1500 show_ticks_in_us(lock_max); | |
| 1501 diag_printf(", Ave lock:"); | |
| 1502 show_ticks_in_us(lock_ave); | |
| 1503 diag_printf("\n"); | |
| 0 | 1504 #endif |
| 1505 | |
| 1506 #ifdef HAL_CLOCK_LATENCY | |
| 2 | 1507 // Display latency figures in same format as all other numbers |
| 1508 disable_clock_latency_measurement(); | |
| 1509 clock_ave = (total_clock_latency*1000) / total_clock_interrupts; | |
| 1510 show_ticks_in_us(clock_ave); | |
| 1511 show_ticks_in_us(min_clock_latency*1000); | |
| 1512 show_ticks_in_us(max_clock_latency*1000); | |
| 1513 show_ticks_in_us(0); | |
| 1514 diag_printf(" Clock/interrupt latency\n\n"); | |
| 1515 enable_clock_latency_measurement(); | |
| 0 | 1516 #endif |
| 1517 | |
| 2 | 1518 disable_clock_latency_measurement(); |
| 1519 min_stack = STACK_SIZE; | |
| 1520 max_stack = 0; | |
| 1521 total_stack = 0; | |
| 1522 for (i = 0; i < NTEST_THREADS; i++) { | |
| 1523 for (j = 0; j < STACK_SIZE; j++) { | |
| 1524 if (stacks[i][j]) break; | |
| 1525 } | |
| 1526 actual_stack = STACK_SIZE-j; | |
| 1527 if (actual_stack < min_stack) min_stack = actual_stack; | |
| 1528 if (actual_stack > max_stack) max_stack = actual_stack; | |
| 1529 total_stack += actual_stack; | |
| 1530 } | |
| 1531 for (j = 0; j < STACKSIZE; j++) { | |
| 1532 if (stack[j]) break; | |
| 1533 } | |
| 1534 diag_printf("%5d %5d %5d (main stack: %5d) Thread stack used (%d total)\n", | |
| 1535 total_stack/NTEST_THREADS, min_stack, max_stack, | |
| 1536 STACKSIZE - j, STACK_SIZE); | |
| 1537 enable_clock_latency_measurement(); | |
| 1538 | |
| 0 | 1539 ticks = cyg_current_time(); |
| 2 | 1540 diag_printf("\nTiming complete - %d ms total\n\n", (int)((ticks*ns_per_system_clock)/1000)); |
| 0 | 1541 |
| 1542 CYG_TEST_PASS_FINISH("Basic timing OK"); | |
| 1543 } | |
| 1544 | |
| 1545 void tm_basic_main( void ) | |
| 1546 { | |
| 1547 CYG_TEST_INIT(); | |
| 1548 | |
| 2 | 1549 if (cyg_test_is_simulator) { |
| 1550 nsamples = NSAMPLES_SIM; | |
| 1551 ntest_threads = NTEST_THREADS_SIM; | |
| 1552 nthread_switches = NTHREAD_SWITCHES_SIM; | |
| 1553 nmutexes = NMUTEXES_SIM; | |
| 1554 nmboxes = NMBOXES_SIM; | |
| 1555 nsemaphores = NSEMAPHORES_SIM; | |
| 1556 nscheds = NSCHEDS_SIM; | |
| 1557 ncounters = NCOUNTERS_SIM; | |
| 1558 nalarms = NALARMS_SIM; | |
| 1559 } else { | |
| 1560 nsamples = NSAMPLES; | |
| 1561 ntest_threads = NTEST_THREADS; | |
| 1562 nthread_switches = NTHREAD_SWITCHES; | |
| 1563 nmutexes = NMUTEXES; | |
| 1564 nmboxes = NMBOXES; | |
| 1565 nsemaphores = NSEMAPHORES; | |
| 1566 nscheds = NSCHEDS; | |
| 1567 ncounters = NCOUNTERS; | |
| 1568 nalarms = NALARMS; | |
| 1569 } | |
| 1570 | |
| 0 | 1571 new_thread(run_all_tests, 0); |
| 1572 | |
| 1573 Cyg_Scheduler::scheduler.start(); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
1574 |
| 0 | 1575 } |
| 1576 | |
| 1577 externC void | |
| 1578 cyg_start( void ) | |
| 1579 { | |
| 1580 tm_basic_main(); | |
| 1581 } | |
| 2 | 1582 |
| 1583 #else // CYGFUN_KERNEL_API_C | |
| 1584 | |
| 1585 externC void | |
| 1586 cyg_start( void ) | |
| 1587 { | |
| 1588 CYG_TEST_INIT(); | |
| 1589 CYG_TEST_PASS_FINISH("Timing tests require:\n" | |
| 1590 "CYGFUN_KERNEL_API_C && \n" | |
| 1591 "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n" | |
| 1592 "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n" | |
| 1593 "!CYGPKG_HAL_I386_LINUX &&\n" | |
| 1594 "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n"); | |
| 1595 } | |
| 1596 #endif // CYGFUN_KERNEL_API_C, etc. | |
| 1597 | |
| 0 | 1598 // EOF tm_basic.cxx |
