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