hs-test: more debug output in http3 test
[vpp.git] / extras / deprecated / vppinfra / test_mheap.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16   Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17
18   Permission is hereby granted, free of charge, to any person obtaining
19   a copy of this software and associated documentation files (the
20   "Software"), to deal in the Software without restriction, including
21   without limitation the rights to use, copy, modify, merge, publish,
22   distribute, sublicense, and/or sell copies of the Software, and to
23   permit persons to whom the Software is furnished to do so, subject to
24   the following conditions:
25
26   The above copyright notice and this permission notice shall be
27   included in all copies or substantial portions of the Software.
28
29   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37
38 #ifdef CLIB_LINUX_KERNEL
39 #include <linux/unistd.h>
40 #endif
41
42 #ifdef CLIB_UNIX
43 #include <unistd.h>
44 #include <stdlib.h>
45 #include <stdio.h>              /* scanf */
46 #endif
47
48 #include <vppinfra/format.h>
49 #include <vppinfra/random.h>
50 #include <vppinfra/time.h>
51
52 static int verbose = 0;
53 #define if_verbose(format,args...) \
54   if (verbose) { clib_warning(format, ## args); }
55
56 int
57 test1 (void)
58 {
59   clib_time_t clib_time;
60   void *h_mem = clib_mem_alloc (2ULL << 30);
61   void *h;
62   uword *objects = 0;
63   int i;
64   f64 before, after;
65
66   clib_time_init (&clib_time);
67
68   vec_validate (objects, 2000000 - 1);
69
70   h = mheap_alloc (h_mem, (uword) (2 << 30));
71
72   before = clib_time_now (&clib_time);
73
74   for (i = 0; i < vec_len (objects); i++)
75     {
76       h = mheap_get_aligned (h, 24 /* size */ ,
77                              64 /* align */ ,
78                              16 /* align at offset */ , &objects[i]);
79     }
80
81   after = clib_time_now (&clib_time);
82
83   fformat (stdout, "alloc: %u objects in %.2f seconds, %.2f objects/second\n",
84            vec_len (objects), (after - before),
85            ((f64) vec_len (objects)) / (after - before));
86
87   return 0;
88 }
89
90
91 int
92 test_mheap_main (unformat_input_t * input)
93 {
94   int i, j, k, n_iterations;
95   void *h, *h_mem;
96   uword *objects = 0;
97   u32 objects_used, really_verbose, n_objects, max_object_size;
98   u32 check_mask, seed, trace, use_vm;
99   u32 print_every = 0;
100   u32 *data;
101   mheap_t *mh;
102
103   /* Validation flags. */
104   check_mask = 0;
105 #define CHECK_VALIDITY 1
106 #define CHECK_DATA     2
107 #define CHECK_ALIGN    4
108 #define TEST1          8
109
110   n_iterations = 10;
111   seed = 0;
112   max_object_size = 100;
113   n_objects = 1000;
114   trace = 0;
115   really_verbose = 0;
116   use_vm = 0;
117
118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
119     {
120       if (0 == unformat (input, "iter %d", &n_iterations)
121           && 0 == unformat (input, "count %d", &n_objects)
122           && 0 == unformat (input, "size %d", &max_object_size)
123           && 0 == unformat (input, "seed %d", &seed)
124           && 0 == unformat (input, "print %d", &print_every)
125           && 0 == unformat (input, "validdata %|",
126                             &check_mask, CHECK_DATA | CHECK_VALIDITY)
127           && 0 == unformat (input, "valid %|",
128                             &check_mask, CHECK_VALIDITY)
129           && 0 == unformat (input, "verbose %=", &really_verbose, 1)
130           && 0 == unformat (input, "trace %=", &trace, 1)
131           && 0 == unformat (input, "vm %=", &use_vm, 1)
132           && 0 == unformat (input, "align %|", &check_mask, CHECK_ALIGN)
133           && 0 == unformat (input, "test1 %|", &check_mask, TEST1))
134         {
135           clib_warning ("unknown input `%U'", format_unformat_error, input);
136           return 1;
137         }
138     }
139
140   /* Zero seed means use default. */
141   if (!seed)
142     seed = random_default_seed ();
143
144   if (check_mask & TEST1)
145     {
146       return test1 ();
147     }
148
149   if_verbose
150     ("testing %d iterations, %d %saligned objects, max. size %d, seed %d",
151      n_iterations, n_objects, (check_mask & CHECK_ALIGN) ? "randomly " : "un",
152      max_object_size, seed);
153
154   vec_resize (objects, n_objects);
155   if (vec_bytes (objects) > 0)  /* stupid warning be gone */
156     clib_memset (objects, ~0, vec_bytes (objects));
157   objects_used = 0;
158
159   /* Allocate initial heap. */
160   {
161     uword size =
162       max_pow2 (2 * n_objects * max_object_size * sizeof (data[0]));
163
164     h_mem = clib_mem_alloc (size);
165     if (!h_mem)
166       return 0;
167
168     h = mheap_alloc (h_mem, size);
169   }
170
171   if (trace)
172     mheap_trace (h, trace);
173
174   mh = mheap_header (h);
175
176   if (use_vm)
177     mh->flags &= ~MHEAP_FLAG_DISABLE_VM;
178   else
179     mh->flags |= MHEAP_FLAG_DISABLE_VM;
180
181   if (check_mask & CHECK_VALIDITY)
182     mh->flags |= MHEAP_FLAG_VALIDATE;
183
184   for (i = 0; i < n_iterations; i++)
185     {
186       while (1)
187         {
188           j = random_u32 (&seed) % vec_len (objects);
189           if (objects[j] != ~0 || i + objects_used < n_iterations)
190             break;
191         }
192
193       if (objects[j] != ~0)
194         {
195           mheap_put (h, objects[j]);
196           objects_used--;
197           objects[j] = ~0;
198         }
199       else
200         {
201           uword size, align, align_offset;
202
203           size = (random_u32 (&seed) % max_object_size) * sizeof (data[0]);
204           align = align_offset = 0;
205           if (check_mask & CHECK_ALIGN)
206             {
207               align = 1 << (random_u32 (&seed) % 10);
208               align_offset = round_pow2 (random_u32 (&seed) & (align - 1),
209                                          sizeof (u32));
210             }
211
212           h = mheap_get_aligned (h, size, align, align_offset, &objects[j]);
213
214           if (align > 0)
215             ASSERT (0 == ((objects[j] + align_offset) & (align - 1)));
216
217           ASSERT (objects[j] != ~0);
218           objects_used++;
219
220           /* Set newly allocated object with test data. */
221           if (check_mask & CHECK_DATA)
222             {
223               uword len;
224
225               data = (void *) h + objects[j];
226               len = mheap_len (h, data);
227
228               ASSERT (size <= mheap_data_bytes (h, objects[j]));
229
230               data[0] = len;
231               for (k = 1; k < len; k++)
232                 data[k] = objects[j] + k;
233             }
234         }
235
236       /* Verify that all used objects have correct test data. */
237       if (check_mask & 2)
238         {
239           for (j = 0; j < vec_len (objects); j++)
240             if (objects[j] != ~0)
241               {
242                 u32 *data = h + objects[j];
243                 uword len = data[0];
244                 for (k = 1; k < len; k++)
245                   ASSERT (data[k] == objects[j] + k);
246               }
247         }
248       if (print_every != 0 && i > 0 && (i % print_every) == 0)
249         fformat (stderr, "iteration %d: %U\n", i, format_mheap, h,
250                  really_verbose);
251     }
252
253   if (verbose)
254     fformat (stderr, "%U\n", format_mheap, h, really_verbose);
255   mheap_free (h);
256   clib_mem_free (h_mem);
257   vec_free (objects);
258
259   return 0;
260 }
261
262 #ifdef CLIB_UNIX
263 int
264 main (int argc, char *argv[])
265 {
266   unformat_input_t i;
267   int ret;
268
269   clib_mem_init (0, 3ULL << 30);
270
271   verbose = (argc > 1);
272   unformat_init_command_line (&i, argv);
273   ret = test_mheap_main (&i);
274   unformat_free (&i);
275
276   return ret;
277 }
278 #endif /* CLIB_UNIX */
279
280 /*
281  * fd.io coding-style-patch-verification: ON
282  *
283  * Local Variables:
284  * eval: (c-set-style "gnu")
285  * End:
286  */