Home | History | Annotate | Download | only in tests
      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)
     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
     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 
     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