memory: Support debug tracking of memory usage

New function coap_dump_memory_type_counts().

Requires COAP_MEMORY_TYPE_TRACK to be defined as 1.
This commit is contained in:
Jon Shallow authored and Jon Shallow committed 2023-10-24 12:43:13 +01:00
1 parent 7688258c39
commit 17e44c73df
5 files changed
+161 -8

No files matched your search

+12
View File
@@ -64,6 +64,7 @@ typedef enum {
COAP_OSCORE_EP,
COAP_OSCORE_BUF,
COAP_COSE,
COAP_MEM_TAG_LAST
} coap_memory_tag_t;
#ifndef WITH_LWIP
@@ -106,6 +107,15 @@ void *coap_realloc_type(coap_memory_tag_t type, void *p, size_t size);
*/
void coap_free_type(coap_memory_tag_t type, void *p);
/**
* Dumps the current usage of malloc'd memory types.
*
* Requires COAP_MEMORY_TYPE_TRACK to be defined to 1.
*
* @param log_level The logging level to use.
*/
void coap_dump_memory_type_counts(coap_log_t log_level);
/**
* Wrapper function to coap_malloc_type() for backwards compatibility.
*/
@@ -161,6 +171,8 @@ coap_free(void *pointer) {
LWIP_ASSERT("coap_free must not be used in lwIP", 0);
}
#define coap_dump_memory_type_counts(l) coap_lwip_dump_memory_pools(l)
#endif /* WITH_LWIP */
#endif /* COAP_MEM_H_ */
+1
View File
@@ -83,6 +83,7 @@ global:
coap_dtls_psk_is_supported;
coap_dtls_rpk_is_supported;
coap_dtls_set_log_level;
coap_dump_memory_type_counts;
coap_encode_var_safe8;
coap_encode_var_safe;
coap_endpoint_set_default_mtu;
+1
View File
@@ -81,6 +81,7 @@ coap_dtls_pki_is_supported
coap_dtls_psk_is_supported
coap_dtls_rpk_is_supported
coap_dtls_set_log_level
coap_dump_memory_type_counts
coap_encode_var_safe
coap_encode_var_safe8
coap_endpoint_set_default_mtu
+146 -5
View File
@@ -15,6 +15,14 @@
#include "coap3/coap_internal.h"
#ifndef WITH_LWIP
#if COAP_MEMORY_TYPE_TRACK
static int track_counts[COAP_MEM_TAG_LAST];
static int peak_counts[COAP_MEM_TAG_LAST];
static int fail_counts[COAP_MEM_TAG_LAST];
#endif /* COAP_MEMORY_TYPE_TRACK */
#endif /* ! WITH_LWIP */
#if defined(RIOT_VERSION) && defined(MODULE_MEMARRAY)
#include <memarray.h>
@@ -423,11 +431,26 @@ coap_malloc_type(coap_memory_tag_t type, size_t size) {
if (!ptr)
coap_log_warn("coap_malloc_type: Failure (no free blocks) for type %d\n",
type);
#if COAP_MEMORY_TYPE_TRACK
assert(type < COAP_MEM_TAG_LAST);
if (ptr) {
track_counts[type]++;
if (track_counts[type] > peak_counts[type])
peak_counts[type] = track_counts[type];
} else {
fail_counts[type]++;
}
#endif /* COAP_MEMORY_TYPE_TRACK */
return ptr;
}
void
coap_free_type(coap_memory_tag_t type, void *object) {
#if COAP_MEMORY_TYPE_TRACK
assert(type < COAP_MEM_TAG_LAST);
if (object)
track_counts[type]--;
#endif /* COAP_MEMORY_TYPE_TRACK */
if (object != NULL)
memarray_free(get_container(type), object);
}
@@ -452,8 +475,9 @@ coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
return p;
}
return coap_malloc_type(type, size);
}
#else /* ! RIOT_VERSION */
#else /* ! RIOT_VERSION && ! MODULE_MEMARRAY */
#if defined(HAVE_MALLOC) || defined(__MINGW32__)
#include <stdlib.h>
@@ -464,19 +488,51 @@ coap_memory_init(void) {
void *
coap_malloc_type(coap_memory_tag_t type, size_t size) {
void *ptr;
(void)type;
return malloc(size);
ptr = malloc(size);
#if COAP_MEMORY_TYPE_TRACK
assert(type < COAP_MEM_TAG_LAST);
if (ptr) {
track_counts[type]++;
if (track_counts[type] > peak_counts[type])
peak_counts[type] = track_counts[type];
} else {
fail_counts[type]++;
}
#endif /* COAP_MEMORY_TYPE_TRACK */
return ptr;
}
void *
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
void *ptr;
(void)type;
return realloc(p, size);
ptr = realloc(p, size);
#if COAP_MEMORY_TYPE_TRACK
if (ptr) {
assert(type < COAP_MEM_TAG_LAST);
if (!p)
track_counts[type]++;
if (track_counts[type] > peak_counts[type])
peak_counts[type] = track_counts[type];
} else {
fail_counts[type]++;
}
#endif /* COAP_MEMORY_TYPE_TRACK */
return ptr;
}
void
coap_free_type(coap_memory_tag_t type, void *p) {
(void)type;
#if COAP_MEMORY_TYPE_TRACK
assert(type < COAP_MEM_TAG_LAST);
if (p)
track_counts[type]--;
#endif /* COAP_MEMORY_TYPE_TRACK */
free(p);
}
@@ -491,20 +547,105 @@ coap_memory_init(void) {
void *
coap_malloc_type(coap_memory_tag_t type, size_t size) {
return heapmem_alloc(size);
void *ptr = heapmem_alloc(size);
#if COAP_MEMORY_TYPE_TRACK
assert(type < COAP_MEM_TAG_LAST);
if (ptr) {
track_counts[type]++;
if (track_counts[type] > peak_counts[type])
peak_counts[type] = track_counts[type];
} else {
fail_counts[type]++;
}
#endif /* COAP_MEMORY_TYPE_TRACK */
return ptr;
}
void *
coap_realloc_type(coap_memory_tag_t type, void *p, size_t size) {
return heapmem_realloc(p, size);
void *ptr = heapmem_realloc(p, size);
#if COAP_MEMORY_TYPE_TRACK
if (ptr) {
assert(type < COAP_MEM_TAG_LAST);
if (!p)
track_counts[type]++;
if (track_counts[type] > peak_counts[type])
peak_counts[type] = track_counts[type];
} else {
fail_counts[type]++;
}
#endif /* COAP_MEMORY_TYPE_TRACK */
return ptr;
}
void
coap_free_type(coap_memory_tag_t type, void *ptr) {
#if COAP_MEMORY_TYPE_TRACK
assert(type < COAP_MEM_TAG_LAST);
if (ptr)
track_counts[type]--;
#endif /* COAP_MEMORY_TYPE_TRACK */
heapmem_free(ptr);
}
#endif /* WITH_CONTIKI */
#endif /* ! HAVE_MALLOC */
#endif /* ! RIOT_VERSION */
#ifndef WITH_LWIP
#define MAKE_CASE(n) case n: name = #n; break
void
coap_dump_memory_type_counts(coap_log_t level) {
#if COAP_MEMORY_TYPE_TRACK
int i;
coap_log(level, "* Memory type counts\n");
for (i = 0; i < COAP_MEM_TAG_LAST; i++) {
const char *name = "?";
switch (i) {
MAKE_CASE(COAP_STRING);
MAKE_CASE(COAP_ATTRIBUTE_NAME);
MAKE_CASE(COAP_ATTRIBUTE_VALUE);
MAKE_CASE(COAP_PACKET);
MAKE_CASE(COAP_NODE);
MAKE_CASE(COAP_CONTEXT);
MAKE_CASE(COAP_ENDPOINT);
MAKE_CASE(COAP_PDU);
MAKE_CASE(COAP_PDU_BUF);
MAKE_CASE(COAP_RESOURCE);
MAKE_CASE(COAP_RESOURCEATTR);
MAKE_CASE(COAP_DTLS_SESSION);
MAKE_CASE(COAP_SESSION);
MAKE_CASE(COAP_OPTLIST);
MAKE_CASE(COAP_CACHE_KEY);
MAKE_CASE(COAP_CACHE_ENTRY);
MAKE_CASE(COAP_LG_XMIT);
MAKE_CASE(COAP_LG_CRCV);
MAKE_CASE(COAP_LG_SRCV);
MAKE_CASE(COAP_DIGEST_CTX);
MAKE_CASE(COAP_SUBSCRIPTION);
MAKE_CASE(COAP_DTLS_CONTEXT);
MAKE_CASE(COAP_OSCORE_COM);
MAKE_CASE(COAP_OSCORE_SEN);
MAKE_CASE(COAP_OSCORE_REC);
MAKE_CASE(COAP_OSCORE_EX);
MAKE_CASE(COAP_OSCORE_EP);
MAKE_CASE(COAP_OSCORE_BUF);
MAKE_CASE(COAP_COSE);
case COAP_MEM_TAG_LAST:
default:
break;
}
coap_log(level, "* %-20s in-use %3d peak %3d failed %2d\n",
name, track_counts[i], peak_counts[i], fail_counts[i]);
}
#else /* COAP_MEMORY_TYPE_TRACK */
(void)level;
#endif /* COAP_MEMORY_TYPE_TRACK */
}
#endif /* !WITH_LWIP */
+1 -3
View File
@@ -665,9 +665,7 @@ coap_free_context(coap_context_t *context) {
#endif /* COAP_SERVER_SUPPORT */
coap_free_type(COAP_CONTEXT, context);
#ifdef WITH_LWIP
coap_lwip_dump_memory_pools(COAP_LOG_DEBUG);
#endif /* WITH_LWIP */
coap_dump_memory_type_counts(COAP_LOG_DEBUG);
}
int