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