File: sbfragment.c

package info (click to toggle)
valgrind 1%3A3.12.0~svn20160714-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 120,428 kB
  • ctags: 70,855
  • sloc: ansic: 674,645; exp: 26,134; xml: 21,574; asm: 7,570; cpp: 7,567; makefile: 7,380; sh: 6,188; perl: 5,855; haskell: 195
file content (104 lines) | stat: -rw-r--r-- 3,207 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <stdlib.h>
#include <stdio.h>
#include "../../config.h"
#if defined(HAVE_MALLINFO)
#include <malloc.h>
#endif

#define BIGINCREASE 32000
int debug = 0;

void stats(char *msg)
{
#if defined(HAVE_MALLINFO)
  struct mallinfo mallinfo_result;
  mallinfo_result = mallinfo();
#endif

  /* from /usr/include/malloc.h */
  printf("%s\n", msg);

#if defined(HAVE_MALLINFO)
  printf("%10d int arena;    /* non-mmapped space allocated from system */\n", mallinfo_result.arena);
  printf("%10d int ordblks;  /* number of free chunks */\n", mallinfo_result.ordblks);
  printf("%10d int smblks;   /* number of fastbin blocks */\n", mallinfo_result.smblks);
  printf("%10d int hblks;    /* number of mmapped regions */\n", mallinfo_result.hblks);
  printf("%10d int hblkhd;   /* space in mmapped regions */\n", mallinfo_result.hblkhd);
  printf("%10d int usmblks;  /* maximum total allocated space */\n", mallinfo_result.usmblks);
  printf("%10d int fsmblks;  /* space available in freed fastbin blocks */\n", mallinfo_result.fsmblks);
  printf("%10d int uordblks; /* total allocated space */\n", mallinfo_result.uordblks);
  printf("%10d int fordblks; /* total free space */\n", mallinfo_result.fordblks);
  printf("%10d int keepcost; /* top-most, releasable (via malloc_trim) space */\n", mallinfo_result.keepcost);
  printf("\n");
#endif
}

int main(int argc, char *argv[])
{

  char *big = NULL;

  char *newbig;
  int malloc_failure = 0;
  unsigned long bigsize = 8; // current size of the (reallocated) big block.
  int i;
  int loop;

  // two optional arguments: [nr of loop] [debug]
  if (argc > 1)
     loop = atoi(argv[1]);
  else
     loop = 3000;

  if (argc > 2)
     debug = 1;

  bigsize += BIGINCREASE;
  big = malloc (bigsize);
  if (big == NULL)
     printf ("failure %d could not allocate size %lu\n",
             ++malloc_failure, bigsize);
  if (debug)
     printf("big 0x%p\n", big);

  for (i = 0; i < loop; i++)
    {
      bigsize += BIGINCREASE;
      newbig = malloc(bigsize);
      if (newbig == NULL)
         printf ("failure %d could not allocate size %lu\n",
                 ++malloc_failure, bigsize);
      free (big);
      big = newbig;
      if (debug)
         printf("big 0x%p\n", big);
    }

  printf ("after %d loops, last size block requested %lu\n", loop, bigsize);
  // verify if superblock fragmentation occurred
  // We consider that an arena of up to 3 times more than bigsize is ok.
  {
#if defined(HAVE_MALLINFO)
     struct mallinfo mallinfo_result;
     mallinfo_result = mallinfo();
     // Under valgrind, hblkhd is 0 : all the space is in arena.
     // Under native linux, some space is counted hblkhd.
     if (malloc_failure > 0)
        printf ("%d mallocs failed, below output is doubful\n", malloc_failure);
     if (mallinfo_result.arena + mallinfo_result.hblkhd > 3 * bigsize)
        printf("unexpected heap fragmentation %lu\n",
               (unsigned long) mallinfo_result.arena 
               + (unsigned long) mallinfo_result.hblkhd);
     else
#endif
        printf("reasonable heap usage\n");
  }

  if (debug)
     stats ("before freeing last block");
  free (big);
  if (debug)
     stats ("after freeing last block");

  return 0;
}