#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; }