mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-07 16:01:30 +00:00
Merge pull request #3747 from cesanta/memory-report
Add heap/stack reporting for mdash
This commit is contained in:
177 files changed
+247892
-17
No files matched your search
+86
@@ -3855,8 +3855,89 @@ struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close, p_read,
|
||||
#endif
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if MG_ENABLE_HEALTH
|
||||
#if !MG_ENABLE_CUSTOM_USAGE
|
||||
size_t mg_usage(int task, int metric) {
|
||||
// FreeRTOS: call NUM_TASKS first to snapshot tasks and copy their names
|
||||
// Indices and names stay valid until the next refresh, preventing duplicate
|
||||
// or mismatched entries. STACK_FREE is minimum-ever free; STACK_TOTAL is 0
|
||||
#if MG_ENABLE_FREERTOS
|
||||
if (metric == MG_USAGE_HEAP_FREE) return xPortGetFreeHeapSize();
|
||||
#ifdef configTOTAL_HEAP_SIZE
|
||||
if (metric == MG_USAGE_HEAP_TOTAL) return configTOTAL_HEAP_SIZE;
|
||||
#endif
|
||||
#if configUSE_TRACE_FACILITY == 1
|
||||
static TaskStatus_t *tasks;
|
||||
static UBaseType_t count;
|
||||
if (metric == MG_USAGE_NUM_TASKS) {
|
||||
size_t size = sizeof(*tasks) + configMAX_TASK_NAME_LEN;
|
||||
vTaskSuspendAll();
|
||||
if (tasks != NULL) {
|
||||
mg_free(tasks);
|
||||
tasks = NULL;
|
||||
}
|
||||
count = 0;
|
||||
UBaseType_t n = uxTaskGetNumberOfTasks();
|
||||
if (n > 0 && (size_t) n <= INT_MAX && (size_t) n <= SIZE_MAX / size) {
|
||||
tasks = (TaskStatus_t *) mg_calloc((size_t) n, size);
|
||||
if (tasks != NULL) {
|
||||
count = uxTaskGetSystemState(tasks, n, NULL);
|
||||
if (count == n) {
|
||||
for (UBaseType_t i = 0; i < count; i++) {
|
||||
char *name = (char *) (tasks + n) + (size_t) i * configMAX_TASK_NAME_LEN;
|
||||
mg_snprintf(name, configMAX_TASK_NAME_LEN, "%s", tasks[i].pcTaskName);
|
||||
tasks[i].pcTaskName = name;
|
||||
}
|
||||
} else {
|
||||
mg_free(tasks);
|
||||
tasks = NULL;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void) xTaskResumeAll();
|
||||
return (size_t) count;
|
||||
}
|
||||
if (task >= 0 && (size_t) task < (size_t) count) {
|
||||
if (metric == MG_USAGE_TASK_NAME) return (size_t) tasks[task].pcTaskName;
|
||||
if (metric == MG_USAGE_STACK_FREE)
|
||||
return (size_t) tasks[task].usStackHighWaterMark * sizeof(StackType_t);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
(void) task;
|
||||
(void) metric;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static size_t print_stacks(mg_pfn_t fn, void *arg, va_list *ap) {
|
||||
int i;
|
||||
int count = (int) mg_usage(-1, MG_USAGE_NUM_TASKS);
|
||||
size_t len = mg_xprintf(fn, arg, "[");
|
||||
for (i = 0; i < count; i++) {
|
||||
const char *name = (const char *) mg_usage(i, MG_USAGE_TASK_NAME);
|
||||
len += mg_xprintf(fn, arg, "%s{%m:%m,%m:%zu,%m:%zu}",
|
||||
i == 0 ? "" : ",", MG_ESC("name"),
|
||||
MG_ESC(name == NULL ? "" : name), MG_ESC("free"),
|
||||
(size_t) mg_usage(i, MG_USAGE_STACK_FREE), MG_ESC("total"),
|
||||
(size_t) mg_usage(i, MG_USAGE_STACK_TOTAL));
|
||||
}
|
||||
(void) ap;
|
||||
return len + mg_xprintf(fn, arg, "]");
|
||||
}
|
||||
|
||||
size_t mg_print_mem_stats(mg_pfn_t fn, void *arg, va_list *ap) {
|
||||
size_t heap_total = (size_t) mg_usage(0, MG_USAGE_HEAP_TOTAL);
|
||||
size_t heap_free = (size_t) mg_usage(0, MG_USAGE_HEAP_FREE);
|
||||
(void) ap;
|
||||
return mg_xprintf(fn, arg, "{%m:%zu,%m:%zu,%m:%M}",
|
||||
MG_ESC("heap_total"), heap_total, MG_ESC("heap_free"),
|
||||
heap_free, MG_ESC("stacks"), print_stacks);
|
||||
}
|
||||
|
||||
#if MG_ARCH == MG_ARCH_ESP32
|
||||
// reusable for other platforms, currently ESP32-only
|
||||
struct mg_health_coredump {
|
||||
@@ -8204,6 +8285,10 @@ static void mg_mdash_rpc_get_info(struct mg_rpc_req *r) {
|
||||
MG_ESC("crash"), mg_print_crash_record);
|
||||
}
|
||||
|
||||
static void mg_mdash_rpc_mem_stats(struct mg_rpc_req *r) {
|
||||
mg_rpc_ok(r, "%M", mg_print_mem_stats);
|
||||
}
|
||||
|
||||
static void mg_mdash_rpc_ota_begin(struct mg_rpc_req *r) {
|
||||
size_t total = (size_t) mg_json_get_long(r->frame, "$.params.size", -1);
|
||||
if (mg_ota_begin(total)) {
|
||||
@@ -8278,6 +8363,7 @@ void mg_mdash_init(struct mg_mgr *mgr) {
|
||||
MG_INFO(("Initialising mdash agent, key [%s]", MG_MDASH_KEY));
|
||||
mg_rpc_add(&mgr->rpcs, mg_str("RPC.List"), mg_rpc_list, NULL);
|
||||
mg_rpc_add(&mgr->rpcs, mg_str("Sys.GetInfo"), mg_mdash_rpc_get_info, NULL);
|
||||
mg_rpc_add(&mgr->rpcs, mg_str("Sys.MemStats"), mg_mdash_rpc_mem_stats, NULL);
|
||||
mg_rpc_add(&mgr->rpcs, mg_str("OTA.Begin"), mg_mdash_rpc_ota_begin, NULL);
|
||||
mg_rpc_add(&mgr->rpcs, mg_str("OTA.Write"), mg_mdash_rpc_ota_write, NULL);
|
||||
mg_rpc_add(&mgr->rpcs, mg_str("OTA.End"), mg_mdash_rpc_ota_end, NULL);
|
||||
|
||||
Reference in new issue
Block a user