1 /*
2  * Copyright (c) 2019 - 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef __STACK_SIZE_ANALYZER_H
8 #define __STACK_SIZE_ANALYZER_H
9 
10 #include <stddef.h>
11 #include <zephyr/kernel/thread.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /** @defgroup thread_analyzer Thread analyzer
18  *  @ingroup debug
19  *  @brief Module for analyzing threads
20  *
21  *  This module implements functions and the configuration that simplifies
22  *  thread analysis.
23  *  @{
24  */
25 
26 struct thread_analyzer_info {
27 	/** The name of the thread or stringified address of the thread handle
28 	 * if name is not set.
29 	 */
30 	const char *name;
31 	/** The total size of the stack*/
32 	size_t stack_size;
33 	/** Stack size in used */
34 	size_t stack_used;
35 
36 #ifdef CONFIG_THREAD_RUNTIME_STATS
37 	unsigned int utilization;
38 #ifdef CONFIG_SCHED_THREAD_USAGE
39 	k_thread_runtime_stats_t  usage;
40 #endif
41 #endif
42 
43 #ifdef CONFIG_THREAD_ANALYZER_STACK_SAFETY
44 	uint32_t stack_safety;
45 #endif
46 
47 #ifdef CONFIG_THREAD_ANALYZER_PRIV_STACK_USAGE
48 	/** Total size of privileged stack */
49 	size_t priv_stack_size;
50 
51 	/** Privileged stack size in used */
52 	size_t priv_stack_used;
53 #endif
54 };
55 
56 /** Stack safety issue codes */
57 
58 /* No stack safety issues detected */
59 #define THREAD_ANALYZE_STACK_SAFETY_NO_ISSUES 0
60 
61 /* Unused stack space is below the defined threshold */
62 #define THREAD_ANALYZE_STACK_SAFETY_THRESHOLD_EXCEEDED 1
63 
64 /* No unused stack space is left */
65 #define THREAD_ANALYZE_STACK_SAFETY_AT_LIMIT 2
66 
67 /* Stack overflow detected */
68 #define THREAD_ANALYZE_STACK_SAFETY_OVERFLOW 3
69 
70 /** @brief Thread analyzer stack safety callback function
71  *
72  *  Stack safety callback function.
73  *
74  *  @param thread Pointer to the thread being analyzed.
75  *  @param unused_space Amount of unused stack space.
76  *  @param stack_issue Pointer to variable to store stack safety issue code
77  */
78 typedef void (*thread_analyzer_stack_safety_handler)(struct k_thread *thread,
79 						     size_t unused_space,
80 						     uint32_t *stack_issue);
81 
82 /** @brief Change the thread analyzer stack safety callback function
83  *
84  *  This function changes the thread analyzer's stack safety handler. This
85  *  allows an application to customize behavior when a thread's unused stack
86  *  drops below its configured threshold.
87  *
88  *  @param handler Function pointer to the new handler (NULL for default)
89  */
90 void thread_analyzer_stack_safety_handler_set(thread_analyzer_stack_safety_handler handler);
91 
92 
93 
94 /** @brief Thread analyzer stack size callback function
95  *
96  *  Callback function with thread analysis information.
97  *
98  *  @param info Thread analysis information.
99  */
100 typedef void (*thread_analyzer_cb)(struct thread_analyzer_info *info);
101 
102 /** @brief Run the thread analyzer and provide information to the callback
103  *
104  *  This function analyzes the current state for all threads and calls
105  *  a given callback on every thread found. In the special case when Kconfig
106  *  option THREAD_ANALYZER_AUTO_SEPARATE_CORES is set, the function analyzes
107  *  only the threads running on the specified cpu.
108  *
109  *  @param cb The callback function handler
110  *  @param cpu cpu to analyze, ignored if THREAD_ANALYZER_AUTO_SEPARATE_CORES=n
111  */
112 void thread_analyzer_run(thread_analyzer_cb cb, unsigned int cpu);
113 
114 /** @brief Run the thread analyzer and print stack size statistics.
115  *
116  *  This function runs the thread analyzer and prints the output in
117  *  standard form. In the special case when Kconfig option
118  *  THREAD_ANALYZER_AUTO_SEPARATE_CORES is set, the function analyzes
119  *  only the threads running on the specified cpu.
120  *
121  *  @param cpu cpu to analyze, ignored if THREAD_ANALYZER_AUTO_SEPARATE_CORES=n
122  */
123 void thread_analyzer_print(unsigned int cpu);
124 
125 /** @} */
126 
127 #ifdef __cplusplus
128 }
129 #endif
130 
131 #endif /* __STACK_SIZE_ANALYZER_H */
132