Skip to content

Commit 8f8a196

Browse files
Merge branch 'master' into gcc9.1
2 parents 803bcf8 + 448486a commit 8f8a196

33 files changed

+733
-299
lines changed

cores/esp8266/CallBackList.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class CallBackList
6464
}
6565

6666
template<typename... Args>
67-
void execute(Args... params) {
67+
int execute(Args... params) {
6868
for(auto it = std::begin(callBackEventList); it != std::end(callBackEventList); ) {
6969
CallBackHandler &handler = *it;
7070
if (handler->allowRemove() && handler.unique()) {
@@ -75,6 +75,7 @@ class CallBackList
7575
++it;
7676
}
7777
}
78+
return callBackEventList.size();
7879
}
7980
};
8081

cores/esp8266/Esp-frag.cpp

+14-6
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,28 @@ void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag)
2929
// Having getFreeHeap()=sum(hole-size), fragmentation is given by
3030
// 100 * (1 - sqrt(sum(hole-size²)) / sum(hole-size))
3131

32-
umm_info(NULL, 0);
32+
umm_info(NULL, false);
3333
uint8_t block_size = umm_block_size();
34-
uint32_t fh = ummHeapInfo.freeBlocks * block_size;
3534
if (hfree)
36-
*hfree = fh;
35+
*hfree = ummHeapInfo.freeBlocks * block_size;
3736
if (hmax)
38-
*hmax = ummHeapInfo.maxFreeContiguousBlocks * block_size;
39-
if (hfrag)
40-
*hfrag = 100 - (sqrt32(ummHeapInfo.freeSize2) * 100) / fh;
37+
*hmax = (uint16_t)ummHeapInfo.maxFreeContiguousBlocks * block_size;
38+
if (hfrag) {
39+
if (ummHeapInfo.freeBlocks) {
40+
*hfrag = 100 - (sqrt32(ummHeapInfo.freeBlocksSquared) * 100) / ummHeapInfo.freeBlocks;
41+
} else {
42+
*hfrag = 0;
43+
}
44+
}
4145
}
4246

4347
uint8_t EspClass::getHeapFragmentation()
4448
{
49+
#ifdef UMM_INLINE_METRICS
50+
return (uint8_t)umm_fragmentation_metric();
51+
#else
4552
uint8_t hfrag;
4653
getHeapStats(nullptr, nullptr, &hfrag);
4754
return hfrag;
55+
#endif
4856
}

cores/esp8266/core_esp8266_postmortem.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ static void ets_printf_P(const char *str, ...) {
9393
}
9494
}
9595

96+
static void cut_here() {
97+
ets_putc('\n');
98+
for (auto i = 0; i < 15; i++ ) {
99+
ets_putc('-');
100+
}
101+
ets_printf_P(PSTR(" CUT HERE FOR EXCEPTION DECODER "));
102+
for (auto i = 0; i < 15; i++ ) {
103+
ets_putc('-');
104+
}
105+
ets_putc('\n');
106+
}
107+
96108
void __wrap_system_restart_local() {
97109
register uint32_t sp asm("a1");
98110
uint32_t sp_dump = sp;
@@ -114,6 +126,8 @@ void __wrap_system_restart_local() {
114126

115127
ets_install_putc1(&uart_write_char_d);
116128

129+
cut_here();
130+
117131
if (s_panic_line) {
118132
ets_printf_P(PSTR("\nPanic %S:%d %S"), s_panic_file, s_panic_line, s_panic_func);
119133
if (s_panic_what) {
@@ -197,6 +211,8 @@ void __wrap_system_restart_local() {
197211
#endif
198212
}
199213

214+
cut_here();
215+
200216
custom_crash_callback( &rst_info, sp_dump + offset, stack_end );
201217

202218
ets_delay_us(10000);

cores/esp8266/heap.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ size_t ICACHE_RAM_ATTR xPortWantedSizeAlign(size_t size)
314314

315315
void system_show_malloc(void)
316316
{
317-
umm_info(NULL, 1);
317+
umm_info(NULL, true);
318318
}
319319

320320
};

cores/esp8266/umm_malloc/dbglog/dbglog.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* ----------------------------------------------------------------------------
1212
* NOTE WELL that this file may be included multiple times - this allows you
1313
* to set the trace level #define DBGLOG_LEVEL x
14-
*
14+
*
1515
* To update which of the DBGLOG macros are compiled in, you must redefine the
1616
* DBGLOG_LEVEL macro and the inlcude the dbglog.h file again, like this:
1717
*
@@ -57,6 +57,8 @@
5757
# define DBGLOG_FUNCTION printf
5858
#endif
5959

60+
#define DBGLOG_32_BIT_PTR(x) ((uint32_t)(((uintptr_t)(x)) & 0xffffffff))
61+
6062
/* ------------------------------------------------------------------------- */
6163

6264
#if DBGLOG_LEVEL >= 6

cores/esp8266/umm_malloc/umm_info.c

+88-29
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
#ifdef UMM_INFO
44

5+
#include <stdint.h>
6+
#include <stddef.h>
7+
#include <stdbool.h>
8+
9+
#include <math.h>
10+
511
/* ----------------------------------------------------------------------------
612
* One of the coolest things about this little library is that it's VERY
713
* easy to get debug information about the memory heap by simply iterating
@@ -19,15 +25,15 @@
1925

2026
UMM_HEAP_INFO ummHeapInfo;
2127

22-
void *umm_info( void *ptr, int force ) {
28+
void *umm_info( void *ptr, bool force ) {
2329
UMM_CRITICAL_DECL(id_info);
2430

25-
unsigned short int blockNo = 0;
26-
27-
if (umm_heap == NULL) {
31+
if(umm_heap == NULL) {
2832
umm_init();
2933
}
3034

35+
uint16_t blockNo = 0;
36+
3137
/* Protect the critical section... */
3238
UMM_CRITICAL_ENTRY(id_info);
3339

@@ -40,7 +46,7 @@ void *umm_info( void *ptr, int force ) {
4046
DBGLOG_FORCE( force, "\n" );
4147
DBGLOG_FORCE( force, "+----------+-------+--------+--------+-------+--------+--------+\n" );
4248
DBGLOG_FORCE( force, "|0x%08lx|B %5d|NB %5d|PB %5d|Z %5d|NF %5d|PF %5d|\n",
43-
(unsigned long)(&UMM_BLOCK(blockNo)),
49+
DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
4450
blockNo,
4551
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
4652
UMM_PBLOCK(blockNo),
@@ -67,21 +73,18 @@ void *umm_info( void *ptr, int force ) {
6773
if( UMM_NBLOCK(blockNo) & UMM_FREELIST_MASK ) {
6874
++ummHeapInfo.freeEntries;
6975
ummHeapInfo.freeBlocks += curBlocks;
70-
ummHeapInfo.freeSize2 += (unsigned int)curBlocks
71-
* (unsigned int)sizeof(umm_block)
72-
* (unsigned int)curBlocks
73-
* (unsigned int)sizeof(umm_block);
76+
ummHeapInfo.freeBlocksSquared += (curBlocks * curBlocks);
7477

7578
if (ummHeapInfo.maxFreeContiguousBlocks < curBlocks) {
7679
ummHeapInfo.maxFreeContiguousBlocks = curBlocks;
7780
}
7881

7982
DBGLOG_FORCE( force, "|0x%08lx|B %5d|NB %5d|PB %5d|Z %5u|NF %5d|PF %5d|\n",
80-
(unsigned long)(&UMM_BLOCK(blockNo)),
83+
DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
8184
blockNo,
8285
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
8386
UMM_PBLOCK(blockNo),
84-
(unsigned int)curBlocks,
87+
(uint16_t)curBlocks,
8588
UMM_NFREE(blockNo),
8689
UMM_PFREE(blockNo) );
8790

@@ -99,33 +102,25 @@ void *umm_info( void *ptr, int force ) {
99102
ummHeapInfo.usedBlocks += curBlocks;
100103

101104
DBGLOG_FORCE( force, "|0x%08lx|B %5d|NB %5d|PB %5d|Z %5u|\n",
102-
(unsigned long)(&UMM_BLOCK(blockNo)),
105+
DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
103106
blockNo,
104107
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
105108
UMM_PBLOCK(blockNo),
106-
(unsigned int)curBlocks );
109+
(uint16_t)curBlocks );
107110
}
108111

109112
blockNo = UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK;
110113
}
111114

112115
/*
113-
* Update the accounting totals with information from the last block, the
114-
* rest must be free!
116+
* The very last block is used as a placeholder to indicate that
117+
* there are no more blocks in the heap, so it cannot be used
118+
* for anything - at the same time, the size of this block must
119+
* ALWAYS be exactly 1 !
115120
*/
116121

117-
{
118-
size_t curBlocks = UMM_NUMBLOCKS-blockNo;
119-
ummHeapInfo.freeBlocks += curBlocks;
120-
ummHeapInfo.totalBlocks += curBlocks;
121-
122-
if (ummHeapInfo.maxFreeContiguousBlocks < curBlocks) {
123-
ummHeapInfo.maxFreeContiguousBlocks = curBlocks;
124-
}
125-
}
126-
127122
DBGLOG_FORCE( force, "|0x%08lx|B %5d|NB %5d|PB %5d|Z %5d|NF %5d|PF %5d|\n",
128-
(unsigned long)(&UMM_BLOCK(blockNo)),
123+
DBGLOG_32_BIT_PTR(&UMM_BLOCK(blockNo)),
129124
blockNo,
130125
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
131126
UMM_PBLOCK(blockNo),
@@ -147,7 +142,13 @@ void *umm_info( void *ptr, int force ) {
147142

148143
DBGLOG_FORCE( force, "+--------------------------------------------------------------+\n" );
149144

145+
DBGLOG_FORCE( force, "Usage Metric: %5d\n", umm_usage_metric());
146+
DBGLOG_FORCE( force, "Fragmentation Metric: %5d\n", umm_fragmentation_metric());
147+
148+
DBGLOG_FORCE( force, "+--------------------------------------------------------------+\n" );
149+
150150
#if defined(UMM_STATS) || defined(UMM_STATS_FULL)
151+
#if !defined(UMM_INLINE_METRICS)
151152
if (ummHeapInfo.freeBlocks == ummStats.free_blocks) {
152153
DBGLOG_FORCE( force, "heap info Free blocks and heap statistics Free blocks match.\n");
153154
} else {
@@ -156,6 +157,7 @@ void *umm_info( void *ptr, int force ) {
156157
ummStats.free_blocks );
157158
}
158159
DBGLOG_FORCE( force, "+--------------------------------------------------------------+\n" );
160+
#endif
159161

160162
print_stats(force);
161163
#endif
@@ -169,17 +171,74 @@ void *umm_info( void *ptr, int force ) {
169171
/* ------------------------------------------------------------------------ */
170172

171173
size_t umm_free_heap_size( void ) {
172-
umm_info(NULL, 0);
174+
#ifndef UMM_INLINE_METRICS
175+
umm_info(NULL, false);
176+
#endif
173177
return (size_t)ummHeapInfo.freeBlocks * sizeof(umm_block);
174178
}
175179

180+
//C Breaking change in upstream umm_max_block_size() was changed to
181+
//C umm_max_free_block_size() keeping old function name for (dot) releases.
182+
//C TODO: update at next major release.
183+
//C size_t umm_max_free_block_size( void ) {
176184
size_t umm_max_block_size( void ) {
177-
umm_info(NULL, 0);
185+
umm_info(NULL, false);
178186
return ummHeapInfo.maxFreeContiguousBlocks * sizeof(umm_block);
179187
}
180188

181-
/* ------------------------------------------------------------------------ */
189+
/*
190+
Without build option UMM_INLINE_METRICS, calls to umm_usage_metric() or
191+
umm_fragmentation_metric() must to be preceeded by a call to umm_info(NULL, false)
192+
for updated results.
193+
*/
194+
int umm_usage_metric( void ) {
195+
#ifndef UMM_INLINE_METRICS
196+
umm_info(NULL, false);
197+
#endif
198+
DBGLOG_DEBUG( "usedBlocks %d totalBlocks %d\n", umm_metrics.usedBlocks, ummHeapInfo.totalBlocks);
199+
if (ummHeapInfo.freeBlocks)
200+
return (int)((ummHeapInfo.usedBlocks * 100)/(ummHeapInfo.freeBlocks));
182201

202+
return -1; // no freeBlocks
203+
}
204+
205+
uint32_t sqrt32 (uint32_t n);
206+
207+
int umm_fragmentation_metric( void ) {
208+
#ifndef UMM_INLINE_METRICS
209+
umm_info(NULL, false);
210+
#endif
211+
DBGLOG_DEBUG( "freeBlocks %d freeBlocksSquared %d\n", umm_metrics.freeBlocks, ummHeapInfo.freeBlocksSquared);
212+
if (0 == ummHeapInfo.freeBlocks) {
213+
return 0;
214+
} else {
215+
//upstream version: return (100 - (((uint32_t)(sqrtf(ummHeapInfo.freeBlocksSquared)) * 100)/(ummHeapInfo.freeBlocks)));
216+
return (100 - (((uint32_t)(sqrt32(ummHeapInfo.freeBlocksSquared)) * 100)/(ummHeapInfo.freeBlocks)));
217+
}
218+
}
219+
220+
#ifdef UMM_INLINE_METRICS
221+
static void umm_fragmentation_metric_init( void ) {
222+
ummHeapInfo.freeBlocks = UMM_NUMBLOCKS - 2;
223+
ummHeapInfo.freeBlocksSquared = ummHeapInfo.freeBlocks * ummHeapInfo.freeBlocks;
224+
}
225+
226+
static void umm_fragmentation_metric_add( uint16_t c ) {
227+
uint16_t blocks = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) - c;
228+
DBGLOG_DEBUG( "Add block %d size %d to free metric\n", c, blocks);
229+
ummHeapInfo.freeBlocks += blocks;
230+
ummHeapInfo.freeBlocksSquared += (blocks * blocks);
231+
}
232+
233+
static void umm_fragmentation_metric_remove( uint16_t c ) {
234+
uint16_t blocks = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) - c;
235+
DBGLOG_DEBUG( "Remove block %d size %d from free metric\n", c, blocks);
236+
ummHeapInfo.freeBlocks -= blocks;
237+
ummHeapInfo.freeBlocksSquared -= (blocks * blocks);
238+
}
239+
#endif // UMM_INLINE_METRICS
240+
241+
/* ------------------------------------------------------------------------ */
183242
#endif
184243

185244
#endif // defined(BUILD_UMM_MALLOC_C)

0 commit comments

Comments
 (0)