1 /**
2 * @file stack.h
3 * Stack usage analysis helpers
4 */
5
6 /*
7 * Copyright (c) 2015 Intel Corporation
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12 #ifndef _MISC_STACK_H_
13 #define _MISC_STACK_H_
14
15 #include <misc/printk.h>
16
17 #if defined(CONFIG_INIT_STACKS)
stack_unused_space_get(const char * stack,size_t size)18 static inline size_t stack_unused_space_get(const char *stack, size_t size)
19 {
20 size_t unused = 0;
21 int i;
22
23 /* TODO Currently all supported platforms have stack growth down and
24 * there is no Kconfig option to configure it so this always build
25 * "else" branch. When support for platform with stack direction up
26 * (or configurable direction) is added this check should be confirmed
27 * that correct Kconfig option is used.
28 */
29 #if defined(STACK_GROWS_UP)
30 for (i = size - 1; i >= 0; i--) {
31 if ((unsigned char)stack[i] == 0xaa) {
32 unused++;
33 } else {
34 break;
35 }
36 }
37 #else
38 for (i = 0; i < size; i++) {
39 if ((unsigned char)stack[i] == 0xaa) {
40 unused++;
41 } else {
42 break;
43 }
44 }
45 #endif
46 return unused;
47 }
48 #else
stack_unused_space_get(const char * stack,size_t size)49 static inline size_t stack_unused_space_get(const char *stack, size_t size)
50 {
51 return 0;
52 }
53 #endif
54
55 #if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK)
stack_analyze(const char * name,const char * stack,unsigned int size)56 static inline void stack_analyze(const char *name, const char *stack,
57 unsigned int size)
58 {
59 unsigned int pcnt, unused = 0;
60
61 unused = stack_unused_space_get(stack, size);
62
63 /* Calculate the real size reserved for the stack */
64 pcnt = ((size - unused) * 100) / size;
65
66 printk("%s (real size %u):\tunused %u\tusage %u / %u (%u %%)\n", name,
67 size, unused, size - unused, size, pcnt);
68 }
69 #else
stack_analyze(const char * name,const char * stack,unsigned int size)70 static inline void stack_analyze(const char *name, const char *stack,
71 unsigned int size)
72 {
73 }
74 #endif
75
76 #define STACK_ANALYZE(name, sym) \
77 stack_analyze(name, K_THREAD_STACK_BUFFER(sym), \
78 K_THREAD_STACK_SIZEOF(sym))
79
80 #endif /* _MISC_STACK_H_ */
81