comparison packages/kernel/current/tests/stress_threads.c @ 10:d3fbcdfa1b2f ecos-sw-1999-05-29

Merge from eCos master repository on 1999-05-29-00:13:11-BST
author jlarmour
date Fri, 28 May 1999 16:43:09 +0000
parents ece80412419a
children 53104bbd5f99
comparison
equal deleted inserted replaced
9:95cc44ea0068 10:d3fbcdfa1b2f
67 #if defined(CYGPKG_LIBM) 67 #if defined(CYGPKG_LIBM)
68 68
69 #include <math.h> 69 #include <math.h>
70 #include <assert.h> 70 #include <assert.h>
71 71
72 #include <cyg/kernel/test/stackmon.h>
73
72 #if defined(CYGFUN_KERNEL_THREADS_TIMER) 74 #if defined(CYGFUN_KERNEL_THREADS_TIMER)
73 #if defined(CYGPKG_LIBC_MALLOC) 75 #if defined(CYGPKG_LIBC_MALLOC)
74 76
75 /* if TIME_LIMIT is defined, it represents the number of seconds this 77 /* if TIME_LIMIT is defined, it represents the number of seconds this
76 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 */
77 #define DEATH_TIME_LIMIT 20 79 #define DEATH_TIME_LIMIT 20
78 /* #undef DEATH_TIME_LIMIT */ 80 /* #undef DEATH_TIME_LIMIT */
79 81
80 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL) 82 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL)
81 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL) 83 #define STACK_SIZE2 (8*1024 + CYGNUM_HAL_STACK_SIZE_TYPICAL)
82 84
83 /* Allocate priorities in this order. This ensures that handlers 85 /* Allocate priorities in this order. This ensures that handlers
131 /* a global variable with which the client and server coordinate */ 133 /* a global variable with which the client and server coordinate */
132 int client_makes_request = 0; 134 int client_makes_request = 0;
133 135
134 /* indicates that it's time to print out a report */ 136 /* indicates that it's time to print out a report */
135 int time_to_report = 0; 137 int time_to_report = 0;
138 /* print status after a delay of this many secs. */
139 int time_report_delay;
136 140
137 /*** now application-specific variables ***/ 141 /*** now application-specific variables ***/
138 /* an array that stores whether the handler threads are in use */ 142 /* an array that stores whether the handler threads are in use */
139 int handler_thread_in_use[MAX_HANDLERS]; 143 int handler_thread_in_use[MAX_HANDLERS];
140 144
141 /***** statistics-gathering variables *****/ 145 /***** statistics-gathering variables *****/
142 struct s_statistics { 146 struct s_statistics {
143 /* store the number of times each handler has been invoked */ 147 /* store the number of times each handler has been invoked */
144 unsigned long handler_invocation_histogram[MAX_HANDLERS]; 148 unsigned long handler_invocation_histogram[MAX_HANDLERS];
145 149
146 /* store how many times malloc has been attempted and how many times 150 /* store how many times malloc has been attempted and how many times
147 it has failed */ 151 it has failed */
148 unsigned long malloc_tries, malloc_failures; 152 unsigned long malloc_tries, malloc_failures;
149 153
150 /* how many threads have been created */ 154 /* how many threads have been created */
151 unsigned long thread_creations, thread_exits; 155 unsigned long thread_creations, thread_exits;
152 }; 156 };
153 157
154 struct s_statistics statistics; 158 struct s_statistics statistics;
155 159
156 /* some function prototypes; those with the sc_ prefix are 160 /* some function prototypes; those with the sc_ prefix are
169 int get_handler_slot(cyg_handle_t current_threadH); 173 int get_handler_slot(cyg_handle_t current_threadH);
170 void perform_stressful_tasks(void); 174 void perform_stressful_tasks(void);
171 void permute_array(char a[], int size, int seed); 175 void permute_array(char a[], int size, int seed);
172 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, 176 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
173 cyg_alarm *death_alarm_p, int *killed_p); 177 cyg_alarm *death_alarm_p, int *killed_p);
174 void print_statistics(void); 178 void print_statistics(int print_full);
175 179
176 /* we need to declare the alarm handling function (which is defined 180 /* we need to declare the alarm handling function (which is defined
177 below), so that we can pass it to cyg_alarm_initialize() */ 181 below), so that we can pass it to cyg_alarm_initialize() */
178 cyg_alarm_t report_alarm_func, death_alarm_func; 182 cyg_alarm_t report_alarm_func, death_alarm_func;
179 183
252 256
253 cyg_alarm_create(counterH, report_alarm_func, 257 cyg_alarm_create(counterH, report_alarm_func,
254 (cyg_addrword_t) 4000, 258 (cyg_addrword_t) 4000,
255 &report_alarmH, &report_alarm); 259 &report_alarmH, &report_alarm);
256 if (cyg_test_is_simulator) { 260 if (cyg_test_is_simulator) {
257 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200, 200); 261 time_report_delay = 2;
258 } else { 262 } else {
259 cyg_alarm_initialize(report_alarmH, cyg_current_time()+300, 4000); 263 time_report_delay = 30;
260 } 264 }
265
266 cyg_alarm_initialize(report_alarmH, cyg_current_time()+200,
267 time_report_delay*100);
261 } 268 }
262 269
263 /* main_program() -- frees resources and prints status. */ 270 /* main_program() -- frees resources and prints status. */
264 void main_program(cyg_addrword_t data) 271 void main_program(cyg_addrword_t data)
265 { 272 {
310 } 317 }
311 318
312 // Print status if time. 319 // Print status if time.
313 if (time_to_report) { 320 if (time_to_report) {
314 time_to_report = 0; 321 time_to_report = 0;
315 print_statistics(); 322 print_statistics(0);
316 } 323 }
317 324
318 #ifdef DEATH_TIME_LIMIT 325 #ifdef DEATH_TIME_LIMIT
319 // Stop test if time. 326 // Stop test if time.
320 if (is_dead) { 327 if (is_dead) {
321 print_statistics(); 328 print_statistics(1);
322 CYG_TEST_PASS_FINISH("Kernel thread stress test OK"); 329 CYG_TEST_PASS_FINISH("Kernel thread stress test OK");
323 } 330 }
324 #endif /* DEATH_TIME_LIMIT */ 331 #endif /* DEATH_TIME_LIMIT */
325 332
326 cyg_thread_delay(3); 333 cyg_thread_delay(3);
520 void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) 527 void report_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
521 { 528 {
522 time_to_report = 1; 529 time_to_report = 1;
523 } 530 }
524 531
532 #ifdef DEATH_TIME_LIMIT
525 /* this sets up death alarms. it gets the handle and alarm from the 533 /* this sets up death alarms. it gets the handle and alarm from the
526 caller, since they must persist for the life of the alarm */ 534 caller, since they must persist for the life of the alarm */
527 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp, 535 void setup_death_alarm(cyg_addrword_t data, cyg_handle_t *deathHp,
528 cyg_alarm *death_alarm_p, int *killed_p) 536 cyg_alarm *death_alarm_p, int *killed_p)
529 { 537 {
551 #endif 559 #endif
552 560
553 cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0); 561 cyg_alarm_initialize(*deathHp, cyg_current_time() + tick_delay, 0);
554 } 562 }
555 } 563 }
564 #endif
556 565
557 /* death_alarm_func() is the alarm handler that kills the current 566 /* death_alarm_func() is the alarm handler that kills the current
558 thread after a specified timeout. It does so by setting a flag the 567 thread after a specified timeout. It does so by setting a flag the
559 thread is constantly checking. */ 568 thread is constantly checking. */
560 void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data) 569 void death_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
581 ++statistics.thread_creations; 590 ++statistics.thread_creations;
582 cyg_thread_create(sched_info, entry, entry_data, name, 591 cyg_thread_create(sched_info, entry, entry_data, name,
583 stack_base, stack_size, handle, thread); 592 stack_base, stack_size, handle, thread);
584 } 593 }
585 594
586 void print_statistics(void) 595
596 void print_statistics(int print_full)
587 { 597 {
588 int i; 598 int i;
599 static int print_count = 0;
600
601 printf("State dump %d (time %02d.%02d.%02d)\n",
602 print_count,
603 print_count*time_report_delay / (60*60), // hours
604 (print_count*time_report_delay / 60) % 60, // minutes
605 (print_count*time_report_delay ) % 60); // seconds
606 print_count++;
589 607
590 cyg_mutex_lock(&statistics_print_lock); { 608 cyg_mutex_lock(&statistics_print_lock); {
591 printf("Handler-invocations: "); 609 printf(" Handler-invocations: ");
592 for (i = 0; i < MAX_HANDLERS; ++i) { 610 for (i = 0; i < MAX_HANDLERS; ++i) {
593 printf("%4lu ", statistics.handler_invocation_histogram[i]); 611 printf("%4lu ", statistics.handler_invocation_histogram[i]);
594 } 612 }
595 printf("\n"); 613 printf("\n");
596 printf("malloc()-tries/failures: -- %7lu %7lu\n", 614 printf(" malloc()-tries/failures: -- %7lu %7lu\n",
597 statistics.malloc_tries, statistics.malloc_failures); 615 statistics.malloc_tries, statistics.malloc_failures);
598 printf("client_makes_request: %d\n", client_makes_request); 616 printf(" client_makes_request: %d\n", client_makes_request);
599 } cyg_mutex_unlock(&statistics_print_lock); 617 } cyg_mutex_unlock(&statistics_print_lock);
618
619 // Add: Also occasionally dump individual threads' stack status.
620 if (0 == print_count % 5 || print_full) {
621 cyg_test_dump_interrupt_stack_stats( " Status" );
622 cyg_test_dump_idlethread_stack_stats( " Status" );
623 }
600 } 624 }
601 625
602 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */ 626 #else /* (CYGNUM_KERNEL_SCHED_PRIORITIES >= */
603 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */ 627 /* (N_MAIN+N_CLIENTS+N_LISTENERS+MAX_HANDLERS)) */
604 #define N_A_MSG "not enough priorities available" 628 #define N_A_MSG "not enough priorities available"