diff options
Diffstat (limited to 'cpukit/libmisc/stackchk/check.c')
-rw-r--r-- | cpukit/libmisc/stackchk/check.c | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c index 974d0eb5e5..abbd0e0845 100644 --- a/cpukit/libmisc/stackchk/check.c +++ b/cpukit/libmisc/stackchk/check.c @@ -60,7 +60,7 @@ /* * Variable to indicate when the stack checker has been initialized. */ -static int Stack_check_Initialized = 0; +static bool Stack_check_Initialized; /* * The "magic pattern" used to mark the end of the stack. @@ -137,7 +137,11 @@ static inline bool Stack_check_Frame_pointer_in_range( #define Stack_check_usable_stack_size(_the_stack) \ ((_the_stack)->size - PATTERN_SIZE_BYTES) -static Stack_Control Stack_check_Interrupt_stack; +#if defined(RTEMS_SMP) +static Stack_Control Stack_check_Interrupt_stack[ CPU_MAXIMUM_PROCESSORS ]; +#else +static Stack_Control Stack_check_Interrupt_stack[ 1 ]; +#endif /* * Fill an entire stack area with BYTE_PATTERN. This will be used @@ -146,30 +150,6 @@ static Stack_Control Stack_check_Interrupt_stack; #define Stack_check_Dope_stack(_stack) \ memset((_stack)->area, BYTE_PATTERN, (_stack)->size) -/* - * Stack_check_Initialize - */ -static void Stack_check_Initialize( void ) -{ - if ( Stack_check_Initialized ) - return; - - /* - * If appropriate, setup the interrupt stack for high water testing - * also. - */ - #if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) - if (_CPU_Interrupt_stack_low && _CPU_Interrupt_stack_high) { - Stack_check_Interrupt_stack.area = _CPU_Interrupt_stack_low; - Stack_check_Interrupt_stack.size = (char *) _CPU_Interrupt_stack_high - - (char *) _CPU_Interrupt_stack_low; - Stack_check_Dope_stack(&Stack_check_Interrupt_stack); - } - #endif - - Stack_check_Initialized = 1; -} - static bool Stack_check_Is_pattern_valid(const Thread_Control *the_thread) { return memcmp( @@ -187,9 +167,9 @@ bool rtems_stack_checker_create_extension( Thread_Control *the_thread ) { - Stack_check_Initialize(); - Stack_check_Dope_stack(&the_thread->Start.Initial_stack); + Stack_check_Initialized = true; + Stack_check_Dope_stack(&the_thread->Start.Initial_stack); memcpy( Stack_check_Get_pattern(&the_thread->Start.Initial_stack), Stack_check_Pattern, @@ -199,6 +179,44 @@ bool rtems_stack_checker_create_extension( return true; } +void rtems_stack_checker_begin_extension( Thread_Control *executing ) +{ +#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) + Per_CPU_Control *cpu_self; + uint32_t cpu_self_index; + Stack_Control *stack; + + /* + * If appropriate, set up the interrupt stack of the current processor for + * high water testing also. This must be done after multi-threading started, + * since the initialization stacks may reuse the interrupt stacks. Disable + * thread dispatching in SMP configurations to prevent thread migration. + * Writing to the interrupt stack is only safe if done from the corresponding + * processor in thread context. + */ + +#if defined(RTEMS_SMP) + cpu_self = _Thread_Dispatch_disable(); +#else + cpu_self = _Per_CPU_Get(); +#endif + + cpu_self_index = _Per_CPU_Get_index( cpu_self ); + stack = &Stack_check_Interrupt_stack[ cpu_self_index ]; + + if ( stack->area == NULL ) { + stack->area = cpu_self->interrupt_stack_low; + stack->size = (size_t) ( (char *) cpu_self->interrupt_stack_high - + (char *) cpu_self->interrupt_stack_low ); + Stack_check_Dope_stack( stack ); + } + +#if defined(RTEMS_SMP) + _Thread_Dispatch_enable( cpu_self ); +#endif +#endif +} + /* * Stack_check_report_blown_task * @@ -365,10 +383,10 @@ static bool Stack_check_Dump_stack_usage( size ); - if (Stack_check_Initialized == 0) { - rtems_printf( printer, "N/A\n" ); - } else { + if (Stack_check_Initialized) { rtems_printf( printer, "%6" PRId32 "\n", used ); + } else { + rtems_printf( printer, "N/A\n" ); } return false; @@ -396,14 +414,15 @@ static bool Stack_check_Dump_threads_usage( static void Stack_check_Dump_interrupt_stack_usage( const Stack_Control *stack, + uint32_t id, const rtems_printer *printer ) { Stack_check_Dump_stack_usage( stack, NULL, - "INTR", - 0xffffffff, + "Interrupt Stack", + id, printer ); } @@ -416,6 +435,9 @@ void rtems_stack_checker_report_usage_with_plugin( const rtems_printer* printer ) { + uint32_t cpu_max; + uint32_t cpu_index; + rtems_printf( printer, " STACK USAGE BY THREAD\n" @@ -428,10 +450,15 @@ void rtems_stack_checker_report_usage_with_plugin( RTEMS_DECONST( rtems_printer *, printer ) ); - Stack_check_Dump_interrupt_stack_usage( - &Stack_check_Interrupt_stack, - printer - ); + cpu_max = rtems_get_processor_count(); + + for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) { + Stack_check_Dump_interrupt_stack_usage( + &Stack_check_Interrupt_stack[ cpu_index ], + cpu_index, + printer + ); + } } void rtems_stack_checker_report_usage( void ) |