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)) */