#include "tests/malloc.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // getopt()
#include "../config.h"
static int s_quiet = 0;
#if defined(HAVE_MALLINFO)
static size_t check(size_t min, size_t max)
{
struct mallinfo mi;
size_t used;
mi = mallinfo();
if (! s_quiet)
{
printf("arena = %d\n", mi.arena); /* non-mmapped space allocated from system */
printf("ordblks = %d\n", mi.ordblks); /* number of free chunks */
printf("smblks = %d\n", mi.smblks); /* number of fastbin blocks */
printf("hblks = %d\n", mi.hblks); /* number of mmapped regions */
printf("hblkhd = %d\n", mi.hblkhd); /* space in mmapped regions */
printf("usmblks = %d\n", mi.usmblks); /* maximum total allocated space */
printf("fsmblks = %d\n", mi.fsmblks); /* space available in freed fastbin blocks */
printf("uordblks = %d\n", mi.uordblks); /* total allocated space */
printf("fordblks = %d\n", mi.fordblks); /* total free space */
printf("keepcost = %d\n", mi.keepcost); /* top-most, releasable (via malloc_trim) space */
printf("(min = %zu, max = %zu)\n", min, max);
printf("\n");
}
// size checks
used = mi.uordblks + mi.hblkhd;
if (used < min)
exit(1);
if (used > max)
exit(2);
// used should be reasonably close to min
// define "reasonably" as within 20%
if (used/5*4 > min)
exit(3);
// sanity checks
if ((mi.ordblks == 0) != (mi.fordblks == 0))
exit(10);
if ((mi.smblks == 0) != (mi.fsmblks == 0))
exit(11);
if ((mi.hblks == 0) != (mi.hblkhd == 0))
exit(12);
if (mi.keepcost > mi.fordblks)
exit(13);
if (mi.fsmblks > mi.fordblks)
exit(14);
// arena should be reasonably close to fordblks + uordblks
if (mi.arena < mi.fordblks + mi.uordblks)
exit(15);
if (mi.arena/5*4 > mi.fordblks + mi.uordblks)
exit(16);
return used;
}
#else
static size_t check(size_t min, size_t max)
{
if (! s_quiet)
{
printf("mallinfo() is not supported on this platform.\n");
printf("\n");
}
return 0;
}
#endif
int main(int argc, char** argv)
{
void* ptr[40];
int i;
size_t min, max;
int optchar;
while ((optchar = getopt(argc, argv, "q")) != EOF)
{
switch (optchar)
{
case 'q':
s_quiet = 1;
break;
default:
fprintf(stderr, "Usage: %s [-q].\n", argv[0]);
return 1;
}
}
min = 0;
for (i = 1; i <= 40; i++)
{
int size = i * i * 8;
min += size;
ptr[i - 1] = malloc(size);
};
max = check(min, (size_t)-1);
for (i = 1; i <= 20; i++)
{
int size = i * i * 8;
min -= size;
max -= size;
free(ptr[i - 1]);
};
check(min, max);
for ( ; i <= 40; i++)
{
free(ptr[i - 1]);
}
fprintf(stderr, "Success.\n");
return 0;
}