1#include "tests/malloc.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h> // getopt()
5#include "../config.h"
6
7
8static int s_quiet = 0;
9
10
11#if defined(HAVE_MALLINFO)
12static size_t check(size_t min, size_t max)
13{
14  struct mallinfo mi;
15  size_t used;
16
17  mi = mallinfo();
18
19  if (! s_quiet)
20  {
21    printf("arena = %d\n", mi.arena);	    /* non-mmapped space allocated from system */
22    printf("ordblks = %d\n", mi.ordblks);   /* number of free chunks */
23    printf("smblks = %d\n", mi.smblks);	    /* number of fastbin blocks */
24    printf("hblks = %d\n", mi.hblks);	    /* number of mmapped regions */
25    printf("hblkhd = %d\n", mi.hblkhd);	    /* space in mmapped regions */
26    printf("usmblks = %d\n", mi.usmblks);   /* maximum total allocated space */
27    printf("fsmblks = %d\n", mi.fsmblks);   /* space available in freed fastbin blocks */
28    printf("uordblks = %d\n", mi.uordblks); /* total allocated space */
29    printf("fordblks = %d\n", mi.fordblks); /* total free space */
30    printf("keepcost = %d\n", mi.keepcost); /* top-most, releasable (via malloc_trim) space */
31    printf("(min = %zu, max = %zu)\n", min, max);
32    printf("\n");
33  }
34
35  // size checks
36  used = mi.uordblks + mi.hblkhd;
37  if (used < min)
38    exit(1);
39
40  if (used > max)
41    exit(2);
42
43  // used should be reasonably close to min
44  // define "reasonably" as within 20%
45  if (used/5*4 > min)
46    exit(3);
47
48  // sanity checks
49  if ((mi.ordblks == 0) != (mi.fordblks == 0))
50    exit(10);
51
52  if ((mi.smblks == 0) != (mi.fsmblks == 0))
53    exit(11);
54
55  if ((mi.hblks == 0) != (mi.hblkhd == 0))
56    exit(12);
57
58  if (mi.keepcost > mi.fordblks)
59    exit(13);
60
61  if (mi.fsmblks > mi.fordblks)
62    exit(14);
63
64  // arena should be reasonably close to fordblks + uordblks
65  if (mi.arena < mi.fordblks + mi.uordblks)
66    exit(15);
67
68  if (mi.arena/5*4 > mi.fordblks + mi.uordblks)
69    exit(16);
70
71  return used;
72}
73#else
74static size_t check(size_t min, size_t max)
75{
76  if (! s_quiet)
77  {
78    printf("mallinfo() is not supported on this platform.\n");
79    printf("\n");
80  }
81  return 0;
82}
83#endif
84
85int main(int argc, char** argv)
86{
87  void* ptr[40];
88  int i;
89  size_t min, max;
90  int optchar;
91
92  while ((optchar = getopt(argc, argv, "q")) != EOF)
93  {
94    switch (optchar)
95    {
96    case 'q':
97      s_quiet = 1;
98      break;
99    default:
100      fprintf(stderr, "Usage: %s [-q].\n", argv[0]);
101      return 1;
102    }
103  }
104
105  min = 0;
106  for (i = 1; i <= 40; i++)
107  {
108    int size = i * i * 8;
109    min += size;
110    ptr[i - 1] = malloc(size);
111  };
112
113  max = check(min, (size_t)-1);
114
115  for (i = 1; i <= 20; i++)
116  {
117    int size = i * i * 8;
118    min -= size;
119    max -= size;
120    free(ptr[i - 1]);
121  };
122
123  check(min, max);
124
125  for ( ; i <= 40; i++)
126  {
127    free(ptr[i - 1]);
128  }
129
130  fprintf(stderr, "Success.\n");
131
132  return 0;
133}
134