File size: 4,255 Bytes
78d2150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* Benchmarks for the pagealign_alloc module.
   Copyright (C) 2025 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* This benchmark focuses on the amount of allocated memory, in order
   to minimize wasted memory.  */

#include <config.h>

/* Specification.  */
#include "pagealign_alloc.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "resource-ext.h"

static size_t pagesize;

/* Does a few pagealign_alloc invocations.  */
static int
allocate_some_pages (void)
{
  int i;

  for (i = 1; i <= 9; i++)
    if (pagealign_alloc (pagesize) == NULL)
      return -1;
  for (i = 1; i <= 2; i++)
    if (pagealign_alloc (2 * pagesize) == NULL)
      return -1;
  for (i = 1; i <= 1; i++)
    if (pagealign_alloc (3 * pagesize) == NULL)
      return -1;

  return 0;
}

/* Returns the total size requested by allocate_some_pages ().  */
static size_t
size_of_some_pages (void)
{
  return 16 * pagesize;
}

static void
show_stats (intptr_t initial_as, intptr_t initial_data, int count)
{
  if (count == 0)
    printf ("Allocation failed.\n");
  else
    {
      intptr_t requested = count * size_of_some_pages ();
      intptr_t as_increase = get_rusage_as () - initial_as;
      intptr_t data_increase = get_rusage_data () - initial_data;
      printf ("count = %5d: requested: %6ld pages, "
              "allocated AS: %6ld pages (%.2f%%), "
              "allocated DATA: %6ld pages (%.2f%%)\n",
              count,
              (long int) (requested / pagesize),
              (long int) (as_increase / pagesize),
              100 * (double) as_increase / (double) requested,
              (long int) (data_increase / pagesize),
              100 * (double) data_increase / (double) requested);
    }
}

static void
do_test (void)
{
  intptr_t initial_as = get_rusage_as ();
  intptr_t initial_data = get_rusage_data ();
  int count;
  for (count = 0; count <= 10000; count++)
    {
      if (count == 10 || count == 30 || count == 90 || count == 270
          || count == 810 || count == 2430 || count == 7290)
        show_stats (initial_as, initial_data, count);

      if (allocate_some_pages () < 0)
        break;
    }
  show_stats (initial_as, initial_data, count);
}

int
main (int argc, char *argv[])
{
  if (argc != 2)
    {
      fprintf (stderr, "Usage: %s TESTS\n", argv[0]);
      fprintf (stderr, "Example: %s {a|b|c|d|e|f}\n", argv[0]);
      exit (1);
    }

  const char *tests = argv[1];

  pagesize = getpagesize ();

  /* Execute each test.  */
  size_t i;
  for (i = 0; i < strlen (tests); i++)
    {
      char test = tests[i];

      switch (test)
        {
        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
          pagealign_impl = test - 'a';
          do_test ();
          break;
        default:
          /* Ignore.  */
          ;
        }
    }

  return 0;
}

/* Results:

                   b         c         d         e         f

glibc            176%      101%      175%       ---       ---
musl libc        198%      101%      197%       ---       ---
macOS            190%      100%      195%       ---       ---
FreeBSD          190%      100%      380%       ---       ---
NetBSD           185%      101%      379%       ---       ---
OpenBSD          177%      101%      101%       ---       ---
AIX              177%      101%      176%       ---       ---
Solaris 11.4     176%      101%      175%       ---       ---
Cygwin           181%      100%      181%       ---       ---
native Windows   184%       ---       ---      180%      100%
Android          182%      101%      181%       ---       ---
*/