Sooooo.... Now I'm finding the mallinfo structure is not telling me what I thought it was....
I wrote this little test program:
#include <malloc.h>
extern "C" char *sbrk(int i);
uint32_t Initialarena = 0;
uint32_t Initialfordblks = 0;
uint32_t Initialkeepcost = 0;
uint32_t Initialordblks = 0;
uint32_t Initialuordblks = 0;
uint32_t TotalSize = 0;
uint16_t TotalBufs = 0;
const int maxBufs = 1000;
const int maxSize = 75;
struct mBlk
{
void *p;
uint16_t size;
};
mBlk Bufs[maxBufs];
int cnt = 0;
void setup()
{
Serial.begin(115200);
for (int i = 0; i < 100; i++)
{
Bufs[i].p = NULL;
Bufs[i].size = 0;
}
showStats();
// Partially fill the array
int max = random(1, 2 * maxBufs / 3);
int icnt = 0;
while (icnt < max)
{
int i;
while (1)
{
i = random(0, maxBufs);
if (Bufs[i].p)
continue;
uint16_t size = random(1, maxSize);
Bufs[i].p = (void *)malloc(size);
Bufs[i].size = size;
TotalSize += size;
TotalBufs++;
break;
}
icnt++;
}
}
void showStats(void)
{
struct mallinfo mi = mallinfo();
if (Initialarena == 0)
{
Initialarena = (uint32_t)mi.arena;
Initialfordblks = (uint32_t)mi.fordblks;
Initialkeepcost = (uint32_t)mi.keepcost;
Initialordblks = (uint32_t)mi.ordblks;
Initialuordblks = (uint32_t)mi.uordblks;
}
char *heapend = sbrk(0);
register char * stackptr asm("sp");
Serial.printf("\n");
Serial.printf("Total Size: %5lu in %d Buffers\n", TotalSize, TotalBufs);
Serial.printf(" arena: %5lu/%5lu\tTotal space allocated from system\n", (uint32_t)mi.arena, Initialarena);
Serial.printf(" fordblks: %5lu/%5lu\tTotal non-inuse space\n", (uint32_t)mi.fordblks, Initialfordblks);
Serial.printf(" keepcost: %5lu/%5lu\tTop-most releasable space\n", (uint32_t)mi.keepcost, Initialkeepcost);
Serial.printf(" ordblks: %5lu/%5lu\tNumber of non-inuse chunks\n", (uint32_t)mi.ordblks, Initialordblks);
Serial.printf(" uordblks: %5lu/%5lu\tTotal allocated space\n", (uint32_t)mi.uordblks, Initialuordblks);
Serial.printf(" heapend: 0x%08lx\n", (uint32_t)heapend);
Serial.printf(" stackptr: 0x%08lx\n", (uint32_t)stackptr);
Serial.printf("\n");
}
void loop()
{
int nallocs = 0;
while (nallocs < 100000)
{
int i = random(1, maxBufs * 13 / 10);
int size = random(1, maxSize);
if (i >= maxBufs)
{
// Randomly de-allocate a buffer
i = random(1, maxBufs);
if (Bufs[i].p)
{
free(Bufs[i].p);
Bufs[i].p = NULL;
TotalSize -= Bufs[i].size;
Bufs[i].size = 0;
TotalBufs--;
}
}
else
{
// Randomly allocate or re-allocate a buffer
if (Bufs[i].p)
{
free(Bufs[i].p);
Bufs[i].p = NULL;
TotalSize -= Bufs[i].size;
Bufs[i].size = 0;
TotalBufs--;
}
Bufs[i].p = (void *)malloc(size);
Bufs[i].size = size;
TotalSize += size;
TotalBufs++;
nallocs++;
}
}
showStats();
Serial.iprintf("\n\n");
}
It creates a whole lotta random-sized buffers using malloc, then randomly adds, deletes and replaces buffers with new, freshly malloc'd buffers, trying to thrash memory as much as possible. After it's created 100,000 buffers, it prints the mallinfo statistics, which don't make a lot of sense to me.
Here's an example of the output:
Total Size: 29732 in 786 Buffers
Arena: 41912/41912 Total space allocated from system
fordblks: 5136/ 6216 Total non-inuse space
keepcost: 2952/ 3008 Top-most releasable space
ordblks: 43/ 42 Number of non-inuse chunks
uordblks: 36776/35696 Total allocated space
heapend: 0x20085000
stackptr: 0x20087f78
For the fields with two numbers, the first is the current value, the second is the value at the start of the program, before any buffers are allocated. Total Size is the total size of all currently allocated buffers (by simply summing the malloc arguments).
None of these numbers make any sense to me. There is 96K of RAM, yet this seems to show a total of only ~77K allocated. keepcost, ordblks, and uordbks are nearly unchanged, despite almost 30K or RAM having been allocated thorugh malloc!
Can anyone make sense of this?
Regards,
Ray L.