diff --git a/core/include/thread.h b/core/include/thread.h index 023626c9869f7..cfce0fea27eef 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -454,11 +454,13 @@ static inline const char *thread_getname(kernel_pid_t pid) * * Only works if the thread was created with the flag THREAD_CREATE_STACKTEST. * - * @param[in] stack the stack you want to measure. Try `thread_get_stackstart(thread_get_active())` + * @param[in] stack the stack you want to measure. Try + * `thread_get_stackstart(thread_get_active())` + * @param[in] size size of @p stack in bytes * - * @return the amount of unused space of the thread's stack + * @return the amount of unused space of the thread's stack */ -uintptr_t thread_measure_stack_free(const char *stack); +uintptr_t thread_measure_stack_free(const char *stack, size_t size); /** * @brief Get the number of bytes used on the ISR stack diff --git a/core/thread.c b/core/thread.c index 6ce6042e2dbf0..9bf523048caf2 100644 --- a/core/thread.c +++ b/core/thread.c @@ -171,15 +171,18 @@ void thread_add_to_list(list_node_t *list, thread_t *thread) list->next = new_node; } -uintptr_t thread_measure_stack_free(const char *stack) +uintptr_t thread_measure_stack_free(const char *stack, size_t size) { /* Alignment of stack has been fixed (if needed) by thread_create(), so * we can silence -Wcast-align here */ uintptr_t *stackp = (uintptr_t *)(uintptr_t)stack; + uintptr_t end = (uintptr_t)stack + size; + + /* better be safe than sorry: align end of stack just in case */ + end &= (sizeof(uintptr_t) - 1); - /* assume that the comparison fails before or after end of stack */ /* assume that the stack grows "downwards" */ - while (*stackp == (uintptr_t)stackp) { + while (((uintptr_t)stackp < end) && (*stackp == (uintptr_t)stackp)) { stackp++; } diff --git a/cpu/esp_common/freertos/task.c b/cpu/esp_common/freertos/task.c index 2c3c8b12a59bc..16dac367daa45 100644 --- a/cpu/esp_common/freertos/task.c +++ b/cpu/esp_common/freertos/task.c @@ -197,7 +197,8 @@ UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask) thread_t *thread = thread_get((xTask == NULL) ? (uint32_t)thread_getpid() : (uint32_t)xTask); assert(thread != NULL); - return thread_measure_stack_free(thread->stack_start); + return thread_measure_stack_free(thread_get_stacksize(thread), + thread_get_stacksize(thread)); } void *pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, diff --git a/cpu/esp_common/thread_arch.c b/cpu/esp_common/thread_arch.c index d9bb7d4c37e0c..6a0382a4cfa35 100644 --- a/cpu/esp_common/thread_arch.c +++ b/cpu/esp_common/thread_arch.c @@ -92,10 +92,9 @@ void thread_isr_stack_init(void) int thread_isr_stack_usage(void) { - /* cppcheck-suppress comparePointers - * (reason: comes from ESP-SDK, so should be valid) */ - return &port_IntStackTop - &port_IntStack - - thread_measure_stack_free((char*)&port_IntStack); + size_t stack_size = (uintptr_t)&port_IntStackTop - (uintptr_t)&port_IntStack; + return stack_size - + thread_measure_stack_free((char *)&port_IntStack, stack_size); } void *thread_isr_stack_pointer(void) diff --git a/sys/ps/ps.c b/sys/ps/ps.c index 5663bdd29dc1e..759857ea4a1fc 100644 --- a/sys/ps/ps.c +++ b/sys/ps/ps.c @@ -98,7 +98,7 @@ void ps(void) #ifdef DEVELHELP int stacksz = thread_get_stacksize(p); /* get stack size */ overall_stacksz += stacksz; - int stack_free = thread_measure_stack_free(thread_get_stackstart(p)); + int stack_free = thread_measure_stack_free(thread_get_stackstart(p), stacksz); stacksz -= stack_free; overall_used += stacksz; #endif diff --git a/sys/test_utils/print_stack_usage/print_stack_usage.c b/sys/test_utils/print_stack_usage/print_stack_usage.c index b4e8f7c7761ef..6181326553de1 100644 --- a/sys/test_utils/print_stack_usage/print_stack_usage.c +++ b/sys/test_utils/print_stack_usage/print_stack_usage.c @@ -34,7 +34,7 @@ void print_stack_usage_metric(const char *name, void *stack, unsigned max_size) { - unsigned free = thread_measure_stack_free(stack); + unsigned free = thread_measure_stack_free(stack, max_size); if ((LOG_LEVEL >= LOG_INFO) && (thread_get_stacksize(thread_get_active()) >= MIN_SIZE)) {