diff --git a/platform/mbed_alloc_wrappers.cpp b/platform/mbed_alloc_wrappers.cpp index 4cf9a3a2cf..aaa9d95539 100644 --- a/platform/mbed_alloc_wrappers.cpp +++ b/platform/mbed_alloc_wrappers.cpp @@ -57,6 +57,9 @@ static mbed_stats_heap_t heap_stats = {0, 0, 0, 0, 0}; void mbed_stats_heap_get(mbed_stats_heap_t *stats) { #ifdef MBED_HEAP_STATS_ENABLED + extern uint32_t mbed_heap_size; + heap_stats.reserved_size = mbed_heap_size; + malloc_stats_mutex->lock(); memcpy(stats, &heap_stats, sizeof(mbed_stats_heap_t)); malloc_stats_mutex->unlock(); diff --git a/platform/mbed_stats.c b/platform/mbed_stats.c new file mode 100644 index 0000000000..9c05b5a05d --- /dev/null +++ b/platform/mbed_stats.c @@ -0,0 +1,69 @@ +#include "mbed_stats.h" +#include + +#if MBED_CONF_RTOS_PRESENT +#include "cmsis_os.h" +#endif + +// note: mbed_stats_heap_get defined in mbed_alloc_wrappers.cpp + +void mbed_stats_stack_get(mbed_stats_stack_t *stats) +{ + memset(stats, 0, sizeof(mbed_stats_stack_t)); + +#if MBED_STACK_STATS_ENABLED && MBED_CONF_RTOS_PRESENT + osThreadEnumId enumid = _osThreadsEnumStart(); + osThreadId threadid; + + while ((threadid = _osThreadEnumNext(enumid))) { + osEvent e; + + e = _osThreadGetInfo(threadid, osThreadInfoStackMax); + if (e.status == osOK) { + stats->max_size += (uint32_t)e.value.p; + } + + e = _osThreadGetInfo(threadid, osThreadInfoStackSize); + if (e.status == osOK) { + stats->reserved_size += (uint32_t)e.value.p; + } + + stats->stack_cnt += 1; + } +#endif +} + +size_t mbed_stats_stack_get_each(mbed_stats_stack_t *stats, size_t count) +{ + memset(stats, 0, count*sizeof(mbed_stats_stack_t)); + size_t i = 0; + +#if MBED_STACK_STATS_ENABLED && MBED_CONF_RTOS_PRESENT + osThreadEnumId enumid = _osThreadsEnumStart(); + osThreadId threadid; + + while ((threadid = _osThreadEnumNext(enumid)) && i < count) { + osEvent e; + + e = _osThreadGetInfo(threadid, osThreadInfoStackMax); + if (e.status == osOK) { + stats[i].max_size = (uint32_t)e.value.p; + } + + e = _osThreadGetInfo(threadid, osThreadInfoStackSize); + if (e.status == osOK) { + stats[i].reserved_size = (uint32_t)e.value.p; + } + + stats[i].thread_id = (uint32_t)threadid; + stats[i].stack_cnt = 1; + i += 1; + } +#endif + + return i; +} + +#if MBED_STACK_STATS_ENABLED && !MBED_CONF_RTOS_PRESENT +#warning Stack statistics are currently not supported without the rtos. +#endif diff --git a/platform/mbed_stats.h b/platform/mbed_stats.h index c9f4765550..4e9dd62999 100644 --- a/platform/mbed_stats.h +++ b/platform/mbed_stats.h @@ -18,6 +18,8 @@ */ #ifndef MBED_STATS_H #define MBED_STATS_H +#include +#include #ifdef __cplusplus extern "C" { @@ -27,15 +29,43 @@ typedef struct { uint32_t current_size; /**< Bytes allocated currently. */ uint32_t max_size; /**< Max bytes allocated at a given time. */ uint32_t total_size; /**< Cumulative sum of bytes ever allocated. */ + uint32_t reserved_size; /**< Current number of bytes allocated for the heap. */ uint32_t alloc_cnt; /**< Current number of allocations. */ uint32_t alloc_fail_cnt; /**< Number of failed allocations. */ } mbed_stats_heap_t; /** - * Fill the passed in structure with heap stats. + * Fill the passed in heap stat structure with heap stats. + * + * @param stats A pointer to the mbed_stats_heap_t structure to fill */ void mbed_stats_heap_get(mbed_stats_heap_t *stats); +typedef struct { + uint32_t thread_id; /**< Identifier for thread that owns the stack. */ + uint32_t max_size; /**< Sum of the maximum number of bytes used in each stack. */ + uint32_t reserved_size; /**< Current number of bytes allocated for all stacks. */ + uint32_t stack_cnt; /**< Number of stacks currently allocated. */ +} mbed_stats_stack_t; + +/** + * Fill the passed in structure with stack stats. + * + * @param stats A pointer to the mbed_stats_stack_t structure to fill + */ +void mbed_stats_stack_get(mbed_stats_stack_t *stats); + +/** + * Fill the passed array of stat structures with the stack stats + * for each available stack. + * + * @param stats A pointer to an array of mbed_stats_stack_t structures to fill + * @param count The number of mbed_stats_stack_t structures in the provided array + * @return The number of mbed_stats_stack_t structures that have been filled, + * this is equal to the number of stacks on the system. + */ +size_t mbed_stats_stack_get_each(mbed_stats_stack_t *stats, size_t count); + #ifdef __cplusplus } #endif