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