• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "../../config.h"
4 #if defined(HAVE_MALLINFO)
5 #include <malloc.h>
6 #endif
7 
8 #define BIGINCREASE 32000
9 int debug = 0;
10 
stats(char * msg)11 void stats(char *msg)
12 {
13 #if defined(HAVE_MALLINFO)
14   struct mallinfo mallinfo_result;
15   mallinfo_result = mallinfo();
16 #endif
17 
18   /* from /usr/include/malloc.h */
19   printf("%s\n", msg);
20 
21 #if defined(HAVE_MALLINFO)
22   printf("%10d int arena;    /* non-mmapped space allocated from system */\n", mallinfo_result.arena);
23   printf("%10d int ordblks;  /* number of free chunks */\n", mallinfo_result.ordblks);
24   printf("%10d int smblks;   /* number of fastbin blocks */\n", mallinfo_result.smblks);
25   printf("%10d int hblks;    /* number of mmapped regions */\n", mallinfo_result.hblks);
26   printf("%10d int hblkhd;   /* space in mmapped regions */\n", mallinfo_result.hblkhd);
27   printf("%10d int usmblks;  /* maximum total allocated space */\n", mallinfo_result.usmblks);
28   printf("%10d int fsmblks;  /* space available in freed fastbin blocks */\n", mallinfo_result.fsmblks);
29   printf("%10d int uordblks; /* total allocated space */\n", mallinfo_result.uordblks);
30   printf("%10d int fordblks; /* total free space */\n", mallinfo_result.fordblks);
31   printf("%10d int keepcost; /* top-most, releasable (via malloc_trim) space */\n", mallinfo_result.keepcost);
32   printf("\n");
33 #endif
34 }
35 
main(int argc,char * argv[])36 int main(int argc, char *argv[])
37 {
38 
39   char *big = NULL;
40 
41   char *newbig;
42   int malloc_failure = 0;
43   unsigned long bigsize = 8; // current size of the (reallocated) big block.
44   int i;
45   int loop;
46 
47   // two optional arguments: [nr of loop] [debug]
48   if (argc > 1)
49      loop = atoi(argv[1]);
50   else
51      loop = 3000;
52 
53   if (argc > 2)
54      debug = 1;
55 
56   bigsize += BIGINCREASE;
57   big = malloc (bigsize);
58   if (big == NULL)
59      printf ("failure %d could not allocate size %lu\n",
60              ++malloc_failure, bigsize);
61   if (debug)
62      printf("big 0x%p\n", big);
63 
64   for (i = 0; i < loop; i++)
65     {
66       bigsize += BIGINCREASE;
67       newbig = malloc(bigsize);
68       if (newbig == NULL)
69          printf ("failure %d could not allocate size %lu\n",
70                  ++malloc_failure, bigsize);
71       free (big);
72       big = newbig;
73       if (debug)
74          printf("big 0x%p\n", big);
75     }
76 
77   printf ("after %d loops, last size block requested %lu\n", loop, bigsize);
78   // verify if superblock fragmentation occurred
79   // We consider that an arena of up to 3 times more than bigsize is ok.
80   {
81 #if defined(HAVE_MALLINFO)
82      struct mallinfo mallinfo_result;
83      mallinfo_result = mallinfo();
84      // Under valgrind, hblkhd is 0 : all the space is in arena.
85      // Under native linux, some space is counted hblkhd.
86      if (malloc_failure > 0)
87         printf ("%d mallocs failed, below output is doubful\n", malloc_failure);
88      if (mallinfo_result.arena + mallinfo_result.hblkhd > 3 * bigsize)
89         printf("unexpected heap fragmentation %lu\n",
90                (unsigned long) mallinfo_result.arena
91                + (unsigned long) mallinfo_result.hblkhd);
92      else
93 #endif
94         printf("reasonable heap usage\n");
95   }
96 
97   if (debug)
98      stats ("before freeing last block");
99   free (big);
100   if (debug)
101      stats ("after freeing last block");
102 
103   return 0;
104 }
105