Mercurial > ecos-v2_0-branch
comparison packages/kernel/current/tests/stress_threads.c @ 36:e97d78785e2d ecos-sw-1999-09-12
Merge from eCos master repository on 1999-09-12-15:40:34-BST
| author | jlarmour |
|---|---|
| date | Sun, 12 Sep 1999 15:26:05 +0000 |
| parents | 18ee5a9c102e |
| children | e7ba79f6d3a8 |
comparison
equal
deleted
inserted
replaced
| 35:d722a005a6c3 | 36:e97d78785e2d |
|---|---|
| 78 test should last; if it is undefined the test will go forever */ | 78 test should last; if it is undefined the test will go forever */ |
| 79 #define DEATH_TIME_LIMIT 20 | 79 #define DEATH_TIME_LIMIT 20 |
| 80 /* #undef DEATH_TIME_LIMIT */ | 80 /* #undef DEATH_TIME_LIMIT */ |
| 81 | 81 |
| 82 // STACK_SIZE is typical +2kB for printf family calls which use big | 82 // STACK_SIZE is typical +2kB for printf family calls which use big |
| 83 // auto variables. | 83 // auto variables. Add more for handler which calls perform_stressful_tasks() |
| 84 #define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) | 84 #define STACK_SIZE (2*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) |
| 85 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) | 85 #define STACK_SIZE_HANDLER (4*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) |
| 86 | 86 |
| 87 // The number of instances in each thread class | |
| 88 #define N_MAIN 1 | 87 #define N_MAIN 1 |
| 88 | |
| 89 //----------------------------------------------------------------------- | |
| 90 // Some targets need to define a smaller number of handlers due to | |
| 91 // memory restrictions. | |
| 92 #ifdef CYGPKG_HAL_ARM_AEB | |
| 93 #define MAX_HANDLERS 4 | |
| 94 #define N_LISTENERS 1 | |
| 95 #define N_CLIENTS 1 | |
| 96 #define N_THREADS (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS) | |
| 97 | |
| 98 #undef STACK_SIZE | |
| 99 #undef STACK_SIZE_HANDLER | |
| 100 #define STACK_SIZE (1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) | |
| 101 #define STACK_SIZE_HANDLER (1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) | |
| 102 #endif | |
| 103 | |
| 104 //----------------------------------------------------------------------- | |
| 105 // If no target specific definitions, use defaults | |
| 106 #ifndef MAX_HANDLERS | |
| 89 #define MAX_HANDLERS 19 | 107 #define MAX_HANDLERS 19 |
| 90 #define N_LISTENERS 4 | 108 #define N_LISTENERS 4 |
| 91 #define N_CLIENTS 4 | 109 #define N_CLIENTS 4 |
| 92 #define N_THREADS (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS) | 110 #define N_THREADS (N_MAIN+MAX_HANDLERS+N_LISTENERS+N_CLIENTS) |
| 111 #endif | |
| 93 | 112 |
| 94 /* Allocate priorities in this order. This ensures that handlers | 113 /* Allocate priorities in this order. This ensures that handlers |
| 95 (which are the ones using the CPU) get enough CPU time to actually | 114 (which are the ones using the CPU) get enough CPU time to actually |
| 96 complete their tasks. */ | 115 complete their tasks. */ |
| 97 //#define P_MAIN 0 // This is defined by libc | 116 //#define P_MAIN 0 // This is defined by libc |
| 115 cyg_thread listener_thread_s[N_LISTENERS]; | 134 cyg_thread listener_thread_s[N_LISTENERS]; |
| 116 cyg_thread client_thread_s[N_CLIENTS]; | 135 cyg_thread client_thread_s[N_CLIENTS]; |
| 117 | 136 |
| 118 /* space for stacks for all threads */ | 137 /* space for stacks for all threads */ |
| 119 char main_stack[STACK_SIZE]; | 138 char main_stack[STACK_SIZE]; |
| 120 char handler_stack[MAX_HANDLERS][STACK_SIZE2]; | 139 char handler_stack[MAX_HANDLERS][STACK_SIZE_HANDLER]; |
| 121 char listener_stack[N_LISTENERS][STACK_SIZE]; | 140 char listener_stack[N_LISTENERS][STACK_SIZE]; |
| 122 char client_stack[N_CLIENTS][STACK_SIZE]; | 141 char client_stack[N_CLIENTS][STACK_SIZE]; |
| 123 | 142 |
| 124 /* now the handles for the threads */ | 143 /* now the handles for the threads */ |
| 125 cyg_handle_t mainH; | 144 cyg_handle_t mainH; |
| 270 (cyg_addrword_t) 4000, | 289 (cyg_addrword_t) 4000, |
| 271 &report_alarmH, &report_alarm); | 290 &report_alarmH, &report_alarm); |
| 272 if (cyg_test_is_simulator) { | 291 if (cyg_test_is_simulator) { |
| 273 time_report_delay = 2; | 292 time_report_delay = 2; |
| 274 } else { | 293 } else { |
| 275 time_report_delay = 30; | 294 time_report_delay = 60; |
| 276 } | 295 } |
| 277 | 296 |
| 278 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, | 297 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, |
| 279 time_report_delay*100); | 298 time_report_delay*100); |
| 280 | 299 |
| 395 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); | 414 CYG_ASSERT(0 == priority_in_use[prio], "Priority already in use!"); |
| 396 priority_in_use[prio]++; | 415 priority_in_use[prio]++; |
| 397 sc_thread_create(prio, handler_program, | 416 sc_thread_create(prio, handler_program, |
| 398 (cyg_addrword_t) handler_slot, | 417 (cyg_addrword_t) handler_slot, |
| 399 name, (void *) handler_stack[handler_slot], | 418 name, (void *) handler_stack[handler_slot], |
| 400 STACK_SIZE2, &handlerH[handler_slot], | 419 STACK_SIZE_HANDLER, &handlerH[handler_slot], |
| 401 &handler_thread_s[handler_slot]); | 420 &handler_thread_s[handler_slot]); |
| 402 cyg_thread_resume(handlerH[handler_slot]); | 421 cyg_thread_resume(handlerH[handler_slot]); |
| 403 ++statistics.handler_invocation_histogram[handler_slot]; | 422 ++statistics.handler_invocation_histogram[handler_slot]; |
| 404 } | 423 } |
| 405 | 424 |
| 599 CYG_ASSERT(cyg_thread_get_priority(*handle) == (cyg_priority_t) sched_info, | 618 CYG_ASSERT(cyg_thread_get_priority(*handle) == (cyg_priority_t) sched_info, |
| 600 "Didn't get requested priority!"); | 619 "Didn't get requested priority!"); |
| 601 } | 620 } |
| 602 | 621 |
| 603 | 622 |
| 623 #define MINS_HOUR (60) | |
| 624 #define MINS_DAY (60*24) | |
| 625 externC void *cyg_libc_get_pool( void ); | |
| 626 | |
| 604 void print_statistics(int print_full) | 627 void print_statistics(int print_full) |
| 605 { | 628 { |
| 606 int i; | 629 int i; |
| 630 static int stat_dumps = 0; | |
| 607 static int print_count = 0; | 631 static int print_count = 0; |
| 608 | 632 static int shift_count = 0; |
| 609 printf("State dump %d (time %02d.%02d.%02d)\n", | 633 int minutes; |
| 610 print_count, | 634 |
| 611 print_count*time_report_delay / (60*60), // hours | 635 stat_dumps++; |
| 612 (print_count*time_report_delay / 60) % 60, // minutes | 636 |
| 613 (print_count*time_report_delay ) % 60); // seconds | 637 // Find number of minutes. |
| 614 print_count++; | 638 minutes = time_report_delay*stat_dumps / 60; |
| 639 | |
| 640 if (!print_full) { | |
| 641 // Return if time/minutes not integer. | |
| 642 if ((time_report_delay*stat_dumps % 60) != 0) | |
| 643 return; | |
| 644 | |
| 645 // After the first day, only dump stat once per day. Do print | |
| 646 // a . on the hour though. | |
| 647 if ((minutes > MINS_DAY) && ((minutes % MINS_DAY) != 0)) { | |
| 648 if ((minutes % MINS_HOUR) == 0) | |
| 649 printf("."); | |
| 650 return; | |
| 651 } | |
| 652 | |
| 653 // After the first hour of the first day, only dump stat once | |
| 654 // per hour. Do print . each minute though. | |
| 655 if ((minutes < MINS_DAY) && (minutes > MINS_HOUR) | |
| 656 && ((minutes % MINS_HOUR) != 0)) { | |
| 657 printf("."); | |
| 658 return; | |
| 659 } | |
| 660 } | |
| 661 | |
| 662 printf("\nState dump %d (%d hours, %d minutes) [numbers >>%d]\n", | |
| 663 ++print_count, minutes / MINS_HOUR, minutes, shift_count); | |
| 615 | 664 |
| 616 cyg_mutex_lock(&statistics_print_lock); { | 665 cyg_mutex_lock(&statistics_print_lock); { |
| 666 //-------------------------------- | |
| 667 // Information private to this test: | |
| 617 printf(" Handler-invocations: "); | 668 printf(" Handler-invocations: "); |
| 618 for (i = 0; i < MAX_HANDLERS; ++i) { | 669 for (i = 0; i < MAX_HANDLERS; ++i) { |
| 619 printf("%4lu ", statistics.handler_invocation_histogram[i]); | 670 printf("%4lu ", statistics.handler_invocation_histogram[i]); |
| 620 } | 671 } |
| 621 printf("\n"); | 672 printf("\n"); |
| 622 printf(" malloc()-tries/failures: -- %7lu %7lu\n", | 673 printf(" malloc()-tries/failures: -- %7lu %7lu\n", |
| 623 statistics.malloc_tries, statistics.malloc_failures); | 674 statistics.malloc_tries, statistics.malloc_failures); |
| 624 printf(" client_makes_request: %d\n", client_makes_request); | 675 printf(" client_makes_request: %d\n", client_makes_request); |
| 676 | |
| 677 // Check for big numbers and reduce if getting close to overflow | |
| 678 if (statistics.malloc_tries > 0x40000000) { | |
| 679 shift_count++; | |
| 680 for (i = 0; i < MAX_HANDLERS; ++i) { | |
| 681 statistics.handler_invocation_histogram[i] >>= 1; | |
| 682 } | |
| 683 statistics.malloc_tries >>= 1; | |
| 684 statistics.malloc_failures >>= 1; | |
| 685 } | |
| 686 | |
| 687 //-------------------------------- | |
| 688 // System information | |
| 689 #if 0 | |
| 690 // We want to (occasionally) pause the test so all memory is | |
| 691 // freed. Otherwise it's hard to tell if there's a malloc | |
| 692 // leak. | |
| 693 { | |
| 694 cyg_mempool_info mem_info; | |
| 695 | |
| 696 cyg_mempool_var_get_info((cyg_handle_t) cyg_libc_get_pool(), | |
| 697 &mem_info); | |
| 698 printf(" Memory system: Total=0x%08x Free=0x%08x Max=0x%08x\n", | |
| 699 mem_info.totalmem, mem_info.freemem, mem_info.maxfree); | |
| 700 } | |
| 701 #endif | |
| 702 | |
| 625 } cyg_mutex_unlock(&statistics_print_lock); | 703 } cyg_mutex_unlock(&statistics_print_lock); |
| 626 | 704 |
| 627 // Add: Also occasionally dump individual threads' stack status. | 705 // Dump stack status |
| 628 if (0 == print_count % 5 || print_full) { | 706 printf(" Stack usage:\n"); |
| 629 cyg_test_dump_interrupt_stack_stats( " Status" ); | 707 cyg_test_dump_interrupt_stack_stats( " Interrupt" ); |
| 630 cyg_test_dump_idlethread_stack_stats( " Status" ); | 708 cyg_test_dump_idlethread_stack_stats( " Idle" ); |
| 709 | |
| 710 cyg_test_dump_stack_stats(" Main", main_stack, | |
| 711 main_stack + sizeof(main_stack)); | |
| 712 for (i = 0; i < MAX_HANDLERS; i++) { | |
| 713 cyg_test_dump_stack_stats(" Handler", handler_stack[i], | |
| 714 handler_stack[i] + sizeof(handler_stack[i])); | |
| 715 } | |
| 716 for (i = 0; i < N_LISTENERS; i++) { | |
| 717 cyg_test_dump_stack_stats(" Listener", listener_stack[i], | |
| 718 listener_stack[i] + sizeof(listener_stack[i])); | |
| 719 } | |
| 720 for (i = 0; i < N_CLIENTS; i++) { | |
| 721 cyg_test_dump_stack_stats(" Client", client_stack[i], | |
| 722 client_stack[i] + sizeof(client_stack[i])); | |
| 631 } | 723 } |
| 632 } | 724 } |
| 633 | 725 |
| 634 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ | 726 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ |
| 635 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ | 727 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ |
