Browse Source

kernel: profiling: Expose an API call to analyze call stacks

The main, idle, interrupt and workqueue call stack definitions are not available
to applications to call stack_analyze() on, but they often require to be
measured empirically to tune their sizes in particular applications and
use cases.
This exposes a new k_call_stacks_analyze() API call that allows the
application to measure the used call stack space for the 4
kernel-defined call stacks.
Additionally for the ARC architecture the FIRQ stack is also profiled.

Change-id: I0cde149c7366cb6c4bbe8f9b0ab1cc5b56a36ed9
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
pull/3/head
Carles Cufi 9 years ago committed by Anas Nashif
parent
commit
cb0cf9f5f4
  1. 28
      include/kernel.h
  2. 23
      kernel/init.c
  3. 2
      kernel/system_work_q.c

28
include/kernel.h

@ -102,6 +102,34 @@ enum execution_context_types { @@ -102,6 +102,34 @@ enum execution_context_types {
K_PREEMPT_THREAD,
};
/**
* @defgroup profiling_apis Profiling APIs
* @ingroup kernel_apis
* @{
*/
/**
* @brief Analyze the main, idle, interrupt and system workqueue call stacks
*
* This routine calls @ref stack_analyze on the 4 call stacks declared and
* maintained by the kernel. The sizes of those 4 call stacks are defined by:
*
* CONFIG_MAIN_STACK_SIZE
* CONFIG_IDLE_STACK_SIZE
* CONFIG_ISR_STACK_SIZE
* CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE
*
* @note CONFIG_INIT_STACKS and CONFIG_PRINTK must be set for this function to
* produce output.
*
* @return N/A
*/
extern void k_call_stacks_analyze(void);
/**
* @} end defgroup profiling_apis
*/
/**
* @defgroup thread_apis Thread APIs
* @ingroup kernel_apis

23
kernel/init.c

@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
#include <offsets_short.h>
#include <kernel.h>
#include <misc/printk.h>
#include <misc/stack.h>
#include <drivers/rand32.h>
#include <sections.h>
#include <toolchain.h>
@ -118,6 +119,28 @@ char __noinit __stack _interrupt_stack[CONFIG_ISR_STACK_SIZE]; @@ -118,6 +119,28 @@ char __noinit __stack _interrupt_stack[CONFIG_ISR_STACK_SIZE];
extern void idle(void *unused1, void *unused2, void *unused3);
void k_call_stacks_analyze(void)
{
#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK)
extern char sys_work_q_stack[CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE];
#if defined(CONFIG_ARC)
extern char _firq_stack[CONFIG_FIRQ_STACK_SIZE];
#endif /* CONFIG_ARC */
printk("Kernel stacks:\n");
stack_analyze("main ", _main_stack, sizeof(_main_stack));
stack_analyze("idle ", _idle_stack, sizeof(_idle_stack));
#if defined(CONFIG_ARC)
stack_analyze("firq ", _firq_stack, sizeof(_firq_stack));
#endif /* CONFIG_ARC */
stack_analyze("interrupt", _interrupt_stack,
sizeof(_interrupt_stack));
stack_analyze("workqueue", sys_work_q_stack,
sizeof(sys_work_q_stack));
#endif /* CONFIG_INIT_STACKS && CONFIG_PRINTK */
}
/**
*
* @brief Clear BSS

2
kernel/system_work_q.c

@ -24,7 +24,7 @@ @@ -24,7 +24,7 @@
#include <kernel.h>
#include <init.h>
static char __stack sys_work_q_stack[CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE];
char __noinit __stack sys_work_q_stack[CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE];
struct k_work_q k_sys_work_q;

Loading…
Cancel
Save