/** * @file stack.h * Stack usage analysis helpers */ /* * Copyright (c) 2015 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK) #include #include static inline void stack_analyze(const char *name, const char *stack, unsigned size) { unsigned i, stack_offset, pcnt, unused = 0; /* The TCS is always placed on a 4-byte aligned boundary - if * the stack beginning doesn't match that there will be some * unused bytes in the beginning. */ stack_offset = __tTCS_SIZEOF + ((4 - ((unsigned)stack % 4)) % 4); /* TODO * Currently all supported platforms have stack growth down and there is no * Kconfig option to configure it so this always build "else" branch. * When support for platform with stack direction up (or configurable direction) * is added this check should be confirmed that correct Kconfig option is used. */ #if defined(CONFIG_STACK_GROWS_UP) for (i = size - 1; i >= stack_offset; i--) { if ((unsigned char)stack[i] == 0xaa) { unused++; } else { break; } } #else for (i = stack_offset; i < size; i++) { if ((unsigned char)stack[i] == 0xaa) { unused++; } else { break; } } #endif /* Calculate the real size reserved for the stack */ size -= stack_offset; pcnt = ((size - unused) * 100) / size; printk("%s (real size %u):\tunused %u\tusage %u / %u (%u %%)\n", name, size + stack_offset, unused, size - unused, size, pcnt); } #else static inline void stack_analyze(const char *name, const char *stack, unsigned size) { } #endif