24UMM_HEAP_INFO ummHeapInfo;
26void compute_usage_metric(
void) {
27 if (0 == ummHeapInfo.freeBlocks) {
28 ummHeapInfo.usage_metric = -1;
30 ummHeapInfo.usage_metric = (int)((ummHeapInfo.usedBlocks * 100) / (ummHeapInfo.freeBlocks));
34void compute_fragmentation_metric(
void) {
35 if (0 == ummHeapInfo.freeBlocks) {
36 ummHeapInfo.fragmentation_metric = 0;
38 ummHeapInfo.fragmentation_metric = 100 - (((uint32_t)(sqrtf(ummHeapInfo.freeBlocksSquared)) * 100) / (ummHeapInfo.freeBlocks));
42void *umm_info(
void *ptr,
bool force) {
45 UMM_CRITICAL_DECL(id_info);
47 UMM_CHECK_INITIALIZED();
50 UMM_CRITICAL_ENTRY(id_info);
56 memset(&ummHeapInfo, 0,
sizeof(ummHeapInfo));
58 DBGLOG_FORCE(force,
"\n");
59 DBGLOG_FORCE(force,
"+----------+-------+--------+--------+-------+--------+--------+\n");
60 DBGLOG_FORCE(force,
"|0x%08x|B %5i|NB %5i|PB %5i|Z %5i|NF %5i|PF %5i|\n",
61 DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
63 UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
65 (UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK) - blockNo,
75 blockNo = UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK;
77 while (UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK) {
78 size_t curBlocks = (UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK) - blockNo;
80 ++ummHeapInfo.totalEntries;
81 ummHeapInfo.totalBlocks += curBlocks;
85 if (UMM_NBLOCK(blockNo) & UMM_FREELIST_MASK) {
86 ++ummHeapInfo.freeEntries;
87 ummHeapInfo.freeBlocks += curBlocks;
88 ummHeapInfo.freeBlocksSquared += (curBlocks * curBlocks);
90 if (ummHeapInfo.maxFreeContiguousBlocks < curBlocks) {
91 ummHeapInfo.maxFreeContiguousBlocks = curBlocks;
94 DBGLOG_FORCE(force,
"|0x%08x|B %5i|NB %5i|PB %5i|Z %5u|NF %5i|PF %5i|\n",
95 DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
97 UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
105 if (ptr == &UMM_BLOCK(blockNo)) {
107 UMM_CRITICAL_EXIT(id_info);
112 ++ummHeapInfo.usedEntries;
113 ummHeapInfo.usedBlocks += curBlocks;
115 DBGLOG_FORCE(force,
"|0x%08x|B %5i|NB %5i|PB %5i|Z %5u| |\n",
116 DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
118 UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
120 (uint16_t)curBlocks);
123 blockNo = UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK;
133 DBGLOG_FORCE(force,
"|0x%08x|B %5i|NB %5i|PB %5i|Z %5i|NF %5i|PF %5i|\n",
134 DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
136 UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
138 UMM_NUMBLOCKS - blockNo,
142 DBGLOG_FORCE(force,
"+----------+-------+--------+--------+-------+--------+--------+\n");
144 DBGLOG_FORCE(force,
"Total Entries %5i Used Entries %5i Free Entries %5i\n",
145 ummHeapInfo.totalEntries,
146 ummHeapInfo.usedEntries,
147 ummHeapInfo.freeEntries);
149 DBGLOG_FORCE(force,
"Total Blocks %5i Used Blocks %5i Free Blocks %5i\n",
150 ummHeapInfo.totalBlocks,
151 ummHeapInfo.usedBlocks,
152 ummHeapInfo.freeBlocks);
154 DBGLOG_FORCE(force,
"+--------------------------------------------------------------+\n");
156 compute_usage_metric();
157 DBGLOG_FORCE(force,
"Usage Metric: %5i\n", ummHeapInfo.usage_metric);
159 compute_fragmentation_metric();
160 DBGLOG_FORCE(force,
"Fragmentation Metric: %5i\n", ummHeapInfo.fragmentation_metric);
162 DBGLOG_FORCE(force,
"+--------------------------------------------------------------+\n");
165 UMM_CRITICAL_EXIT(id_info);
172size_t umm_free_heap_size(
void) {
173#ifndef UMM_INLINE_METRICS
174 umm_info(NULL,
false);
176 return (
size_t)ummHeapInfo.freeBlocks * UMM_BLOCKSIZE;
179size_t umm_max_free_block_size(
void) {
180 umm_info(NULL,
false);
181 return ummHeapInfo.maxFreeContiguousBlocks *
sizeof(umm_block);
184int umm_usage_metric(
void) {
185#ifdef UMM_INLINE_METRICS
186 compute_usage_metric();
188 umm_info(NULL,
false);
190 DBGLOG_DEBUG(
"usedBlocks %i totalBlocks %i\n", ummHeapInfo.usedBlocks, ummHeapInfo.totalBlocks);
192 return ummHeapInfo.usage_metric;
195int umm_fragmentation_metric(
void) {
196#ifdef UMM_INLINE_METRICS
197 compute_fragmentation_metric();
199 umm_info(NULL,
false);
201 DBGLOG_DEBUG(
"freeBlocks %i freeBlocksSquared %i\n", ummHeapInfo.freeBlocks, ummHeapInfo.freeBlocksSquared);
203 return ummHeapInfo.fragmentation_metric;
206#ifdef UMM_INLINE_METRICS
207static void umm_fragmentation_metric_init(
void) {
208 ummHeapInfo.freeBlocks = UMM_NUMBLOCKS - 2;
209 ummHeapInfo.freeBlocksSquared = ummHeapInfo.freeBlocks * ummHeapInfo.freeBlocks;
212static void umm_fragmentation_metric_add(uint16_t c) {
213 uint16_t blocks = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) - c;
215 DBGLOG_DEBUG(
"Add block %i size %i to free metric\n", c, blocks);
216 ummHeapInfo.freeBlocks += blocks;
217 ummHeapInfo.freeBlocksSquared += (blocks * blocks);
220static void umm_fragmentation_metric_remove(uint16_t c) {
221 uint16_t blocks = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) - c;
223 DBGLOG_DEBUG(
"Remove block %i size %i from free metric\n", c, blocks);
224 ummHeapInfo.freeBlocks -= blocks;
225 ummHeapInfo.freeBlocksSquared -= (blocks * blocks);