#include #include #include "../../config.h" #if defined(HAVE_MALLINFO) #include #endif #define BIGINCREASE 32000 int debug = 0; void stats(char *msg) { #if defined(HAVE_MALLINFO) struct mallinfo mallinfo_result; mallinfo_result = mallinfo(); #endif /* from /usr/include/malloc.h */ printf("%s\n", msg); #if defined(HAVE_MALLINFO) printf("%10d int arena; /* non-mmapped space allocated from system */\n", mallinfo_result.arena); printf("%10d int ordblks; /* number of free chunks */\n", mallinfo_result.ordblks); printf("%10d int smblks; /* number of fastbin blocks */\n", mallinfo_result.smblks); printf("%10d int hblks; /* number of mmapped regions */\n", mallinfo_result.hblks); printf("%10d int hblkhd; /* space in mmapped regions */\n", mallinfo_result.hblkhd); printf("%10d int usmblks; /* maximum total allocated space */\n", mallinfo_result.usmblks); printf("%10d int fsmblks; /* space available in freed fastbin blocks */\n", mallinfo_result.fsmblks); printf("%10d int uordblks; /* total allocated space */\n", mallinfo_result.uordblks); printf("%10d int fordblks; /* total free space */\n", mallinfo_result.fordblks); printf("%10d int keepcost; /* top-most, releasable (via malloc_trim) space */\n", mallinfo_result.keepcost); printf("\n"); #endif } int main(int argc, char *argv[]) { char *big = NULL; char *newbig; int malloc_failure = 0; unsigned long bigsize = 8; // current size of the (reallocated) big block. int i; int loop; // two optional arguments: [nr of loop] [debug] if (argc > 1) loop = atoi(argv[1]); else loop = 3000; if (argc > 2) debug = 1; bigsize += BIGINCREASE; big = malloc (bigsize); if (big == NULL) printf ("failure %d could not allocate size %lu\n", ++malloc_failure, bigsize); if (debug) printf("big 0x%p\n", big); for (i = 0; i < loop; i++) { bigsize += BIGINCREASE; newbig = malloc(bigsize); if (newbig == NULL) printf ("failure %d could not allocate size %lu\n", ++malloc_failure, bigsize); free (big); big = newbig; if (debug) printf("big 0x%p\n", big); } printf ("after %d loops, last size block requested %lu\n", loop, bigsize); // verify if superblock fragmentation occurred // We consider that an arena of up to 3 times more than bigsize is ok. { #if defined(HAVE_MALLINFO) struct mallinfo mallinfo_result; mallinfo_result = mallinfo(); // Under valgrind, hblkhd is 0 : all the space is in arena. // Under native linux, some space is counted hblkhd. if (malloc_failure > 0) printf ("%d mallocs failed, below output is doubful\n", malloc_failure); if (mallinfo_result.arena + mallinfo_result.hblkhd > 3 * bigsize) printf("unexpected heap fragmentation %lu\n", (unsigned long) mallinfo_result.arena + (unsigned long) mallinfo_result.hblkhd); else #endif printf("reasonable heap usage\n"); } if (debug) stats ("before freeing last block"); free (big); if (debug) stats ("after freeing last block"); return 0; }