183b62cbbab29bde83eba40231f307c2a311e73c8njn#include "tests/malloc.h"
268d9fab043fd61616f975de0be3b006d65fa4aadbart#include <stdio.h>
368d9fab043fd61616f975de0be3b006d65fa4aadbart#include <stdlib.h>
4bee023b2712a1cd943a53f8485e348554f9b8dcfbart#include <unistd.h> // getopt()
55a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart#include "../config.h"
668d9fab043fd61616f975de0be3b006d65fa4aadbart
768d9fab043fd61616f975de0be3b006d65fa4aadbart
8bee023b2712a1cd943a53f8485e348554f9b8dcfbartstatic int s_quiet = 0;
9bee023b2712a1cd943a53f8485e348554f9b8dcfbart
105a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart
115a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart#if defined(HAVE_MALLINFO)
12bee023b2712a1cd943a53f8485e348554f9b8dcfbartstatic size_t check(size_t min, size_t max)
1368d9fab043fd61616f975de0be3b006d65fa4aadbart{
1468d9fab043fd61616f975de0be3b006d65fa4aadbart  struct mallinfo mi;
15bee023b2712a1cd943a53f8485e348554f9b8dcfbart  size_t used;
1668d9fab043fd61616f975de0be3b006d65fa4aadbart
1768d9fab043fd61616f975de0be3b006d65fa4aadbart  mi = mallinfo();
18bee023b2712a1cd943a53f8485e348554f9b8dcfbart
19bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (! s_quiet)
20bee023b2712a1cd943a53f8485e348554f9b8dcfbart  {
21bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("arena = %d\n", mi.arena);	    /* non-mmapped space allocated from system */
22bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("ordblks = %d\n", mi.ordblks);   /* number of free chunks */
23bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("smblks = %d\n", mi.smblks);	    /* number of fastbin blocks */
24bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("hblks = %d\n", mi.hblks);	    /* number of mmapped regions */
25bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("hblkhd = %d\n", mi.hblkhd);	    /* space in mmapped regions */
26bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("usmblks = %d\n", mi.usmblks);   /* maximum total allocated space */
27bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("fsmblks = %d\n", mi.fsmblks);   /* space available in freed fastbin blocks */
28bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("uordblks = %d\n", mi.uordblks); /* total allocated space */
29bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("fordblks = %d\n", mi.fordblks); /* total free space */
30bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("keepcost = %d\n", mi.keepcost); /* top-most, releasable (via malloc_trim) space */
31bee023b2712a1cd943a53f8485e348554f9b8dcfbart    printf("(min = %zu, max = %zu)\n", min, max);
325a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart    printf("\n");
33bee023b2712a1cd943a53f8485e348554f9b8dcfbart  }
34bee023b2712a1cd943a53f8485e348554f9b8dcfbart
35bee023b2712a1cd943a53f8485e348554f9b8dcfbart  // size checks
36bee023b2712a1cd943a53f8485e348554f9b8dcfbart  used = mi.uordblks + mi.hblkhd;
37bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (used < min)
38bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(1);
39bee023b2712a1cd943a53f8485e348554f9b8dcfbart
40bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (used > max)
41bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(2);
42bee023b2712a1cd943a53f8485e348554f9b8dcfbart
43bee023b2712a1cd943a53f8485e348554f9b8dcfbart  // used should be reasonably close to min
44bee023b2712a1cd943a53f8485e348554f9b8dcfbart  // define "reasonably" as within 20%
45bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (used/5*4 > min)
46bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(3);
47bee023b2712a1cd943a53f8485e348554f9b8dcfbart
48bee023b2712a1cd943a53f8485e348554f9b8dcfbart  // sanity checks
49bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if ((mi.ordblks == 0) != (mi.fordblks == 0))
50bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(10);
51bee023b2712a1cd943a53f8485e348554f9b8dcfbart
52bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if ((mi.smblks == 0) != (mi.fsmblks == 0))
53bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(11);
54bee023b2712a1cd943a53f8485e348554f9b8dcfbart
55bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if ((mi.hblks == 0) != (mi.hblkhd == 0))
56bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(12);
57bee023b2712a1cd943a53f8485e348554f9b8dcfbart
58bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (mi.keepcost > mi.fordblks)
59bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(13);
60bee023b2712a1cd943a53f8485e348554f9b8dcfbart
61bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (mi.fsmblks > mi.fordblks)
62bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(14);
63bee023b2712a1cd943a53f8485e348554f9b8dcfbart
64bee023b2712a1cd943a53f8485e348554f9b8dcfbart  // arena should be reasonably close to fordblks + uordblks
65bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (mi.arena < mi.fordblks + mi.uordblks)
66bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(15);
67bee023b2712a1cd943a53f8485e348554f9b8dcfbart
68bee023b2712a1cd943a53f8485e348554f9b8dcfbart  if (mi.arena/5*4 > mi.fordblks + mi.uordblks)
69bee023b2712a1cd943a53f8485e348554f9b8dcfbart    exit(16);
70bee023b2712a1cd943a53f8485e348554f9b8dcfbart
71bee023b2712a1cd943a53f8485e348554f9b8dcfbart  return used;
72bee023b2712a1cd943a53f8485e348554f9b8dcfbart}
735a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart#else
745a4fb83ec433ffe99bd118b5c42469ea4b131c4bbartstatic size_t check(size_t min, size_t max)
755a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart{
765a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart  if (! s_quiet)
775a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart  {
785a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart    printf("mallinfo() is not supported on this platform.\n");
795a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart    printf("\n");
805a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart  }
815a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart  return 0;
825a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart}
835a4fb83ec433ffe99bd118b5c42469ea4b131c4bbart#endif
84bee023b2712a1cd943a53f8485e348554f9b8dcfbart
85bee023b2712a1cd943a53f8485e348554f9b8dcfbartint main(int argc, char** argv)
86bee023b2712a1cd943a53f8485e348554f9b8dcfbart{
87bee023b2712a1cd943a53f8485e348554f9b8dcfbart  void* ptr[40];
88bee023b2712a1cd943a53f8485e348554f9b8dcfbart  int i;
89bee023b2712a1cd943a53f8485e348554f9b8dcfbart  size_t min, max;
90bee023b2712a1cd943a53f8485e348554f9b8dcfbart  int optchar;
91bee023b2712a1cd943a53f8485e348554f9b8dcfbart
92bee023b2712a1cd943a53f8485e348554f9b8dcfbart  while ((optchar = getopt(argc, argv, "q")) != EOF)
93bee023b2712a1cd943a53f8485e348554f9b8dcfbart  {
94bee023b2712a1cd943a53f8485e348554f9b8dcfbart    switch (optchar)
95bee023b2712a1cd943a53f8485e348554f9b8dcfbart    {
96bee023b2712a1cd943a53f8485e348554f9b8dcfbart    case 'q':
97bee023b2712a1cd943a53f8485e348554f9b8dcfbart      s_quiet = 1;
98bee023b2712a1cd943a53f8485e348554f9b8dcfbart      break;
99bee023b2712a1cd943a53f8485e348554f9b8dcfbart    default:
100bee023b2712a1cd943a53f8485e348554f9b8dcfbart      fprintf(stderr, "Usage: %s [-q].\n", argv[0]);
101bee023b2712a1cd943a53f8485e348554f9b8dcfbart      return 1;
102bee023b2712a1cd943a53f8485e348554f9b8dcfbart    }
103bee023b2712a1cd943a53f8485e348554f9b8dcfbart  }
104bee023b2712a1cd943a53f8485e348554f9b8dcfbart
105bee023b2712a1cd943a53f8485e348554f9b8dcfbart  min = 0;
106bee023b2712a1cd943a53f8485e348554f9b8dcfbart  for (i = 1; i <= 40; i++)
107bee023b2712a1cd943a53f8485e348554f9b8dcfbart  {
108bee023b2712a1cd943a53f8485e348554f9b8dcfbart    int size = i * i * 8;
109bee023b2712a1cd943a53f8485e348554f9b8dcfbart    min += size;
110bee023b2712a1cd943a53f8485e348554f9b8dcfbart    ptr[i - 1] = malloc(size);
111bee023b2712a1cd943a53f8485e348554f9b8dcfbart  };
112bee023b2712a1cd943a53f8485e348554f9b8dcfbart
113bee023b2712a1cd943a53f8485e348554f9b8dcfbart  max = check(min, (size_t)-1);
114bee023b2712a1cd943a53f8485e348554f9b8dcfbart
115bee023b2712a1cd943a53f8485e348554f9b8dcfbart  for (i = 1; i <= 20; i++)
116bee023b2712a1cd943a53f8485e348554f9b8dcfbart  {
117bee023b2712a1cd943a53f8485e348554f9b8dcfbart    int size = i * i * 8;
118bee023b2712a1cd943a53f8485e348554f9b8dcfbart    min -= size;
119bee023b2712a1cd943a53f8485e348554f9b8dcfbart    max -= size;
120bee023b2712a1cd943a53f8485e348554f9b8dcfbart    free(ptr[i - 1]);
121bee023b2712a1cd943a53f8485e348554f9b8dcfbart  };
122bee023b2712a1cd943a53f8485e348554f9b8dcfbart
123bee023b2712a1cd943a53f8485e348554f9b8dcfbart  check(min, max);
124bee023b2712a1cd943a53f8485e348554f9b8dcfbart
12505ef357be4f1a09045307f5008e607b8f8ff8d3bbart  for ( ; i <= 40; i++)
12605ef357be4f1a09045307f5008e607b8f8ff8d3bbart  {
12705ef357be4f1a09045307f5008e607b8f8ff8d3bbart    free(ptr[i - 1]);
12805ef357be4f1a09045307f5008e607b8f8ff8d3bbart  }
12905ef357be4f1a09045307f5008e607b8f8ff8d3bbart
130bee023b2712a1cd943a53f8485e348554f9b8dcfbart  fprintf(stderr, "Success.\n");
13168d9fab043fd61616f975de0be3b006d65fa4aadbart
13268d9fab043fd61616f975de0be3b006d65fa4aadbart  return 0;
13368d9fab043fd61616f975de0be3b006d65fa4aadbart}
134