1 #include "tests/malloc.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <unistd.h> // getopt()
5 #include "../config.h"
6 
7 
8 static int s_quiet = 0;
9 
10 
11 #if defined(HAVE_MALLINFO)
check(size_t min,size_t max)12 static 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
check(size_t min,size_t max)74 static 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 
main(int argc,char ** argv)85 int 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