#ifdef UMM_INTEGRITY_CHECK
#include <stdint.h>
#include <stdbool.h>
bool umm_integrity_check(void) {
UMM_CRITICAL_DECL(id_integrity);
bool ok = true;
uint16_t prev;
uint16_t cur;
UMM_CHECK_INITIALIZED();
prev = 0;
UMM_CRITICAL_ENTRY(id_integrity);
while (1) {
cur = UMM_NFREE(prev);
if (cur >= UMM_NUMBLOCKS) {
DBGLOG_CRITICAL("Heap integrity broken: too large next free num: %d "
"(in block %d, addr 0x%08x)\n",
cur, prev, DBGLOG_32_BIT_PTR(&UMM_NBLOCK(prev)));
ok = false;
goto clean;
}
if (cur == 0) {
break;
}
if (UMM_PFREE(cur) != prev) {
DBGLOG_CRITICAL("Heap integrity broken: free links don't match: "
"%d -> %d, but %d -> %d\n",
prev, cur, cur, UMM_PFREE(cur));
ok = false;
goto clean;
}
UMM_PBLOCK(cur) |= UMM_FREELIST_MASK;
prev = cur;
}
prev = 0;
while (1) {
cur = UMM_NBLOCK(prev) & UMM_BLOCKNO_MASK;
if (cur >= UMM_NUMBLOCKS) {
DBGLOG_CRITICAL("Heap integrity broken: too large next block num: %d "
"(in block %d, addr 0x%08x)\n",
cur, prev, DBGLOG_32_BIT_PTR(&UMM_NBLOCK(prev)));
ok = false;
goto clean;
}
if (cur == 0) {
break;
}
if ((UMM_NBLOCK(cur) & UMM_FREELIST_MASK)
!= (UMM_PBLOCK(cur) & UMM_FREELIST_MASK)) {
DBGLOG_CRITICAL("Heap integrity broken: mask wrong at addr 0x%08x: n=0x%x, p=0x%x\n",
DBGLOG_32_BIT_PTR(&UMM_NBLOCK(cur)),
(UMM_NBLOCK(cur) & UMM_FREELIST_MASK),
(UMM_PBLOCK(cur) & UMM_FREELIST_MASK));
ok = false;
goto clean;
}
if (cur <= prev) {
DBGLOG_CRITICAL("Heap integrity broken: next block %d is before prev this one "
"(in block %d, addr 0x%08x)\n",
cur, prev, DBGLOG_32_BIT_PTR(&UMM_NBLOCK(prev)));
ok = false;
goto clean;
}
UMM_PBLOCK(cur) &= UMM_BLOCKNO_MASK;
if (UMM_PBLOCK(cur) != prev) {
DBGLOG_CRITICAL("Heap integrity broken: block links don't match: "
"%d -> %d, but %d -> %d\n",
prev, cur, cur, UMM_PBLOCK(cur));
ok = false;
goto clean;
}
prev = cur;
}
clean:
UMM_CRITICAL_EXIT(id_integrity);
if (!ok) {
UMM_HEAP_CORRUPTION_CB();
}
return ok;
}
#endif