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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
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:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
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.
38 #ifdef CLIB_LINUX_KERNEL
39 #include <linux/unistd.h>
45 #include <stdio.h> /* scanf */
48 #include <vppinfra/mheap.h>
49 #include <vppinfra/format.h>
50 #include <vppinfra/random.h>
52 static int verbose = 0;
53 #define if_verbose(format,args...) \
54 if (verbose) { clib_warning(format, ## args); }
57 test_mheap_main (unformat_input_t * input)
59 int i, j, k, n_iterations;
62 u32 objects_used, really_verbose, n_objects, max_object_size;
63 u32 check_mask, seed, trace, use_vm;
68 /* Validation flags. */
70 #define CHECK_VALIDITY 1
76 max_object_size = 100;
82 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
84 if (0 == unformat (input, "iter %d", &n_iterations)
85 && 0 == unformat (input, "count %d", &n_objects)
86 && 0 == unformat (input, "size %d", &max_object_size)
87 && 0 == unformat (input, "seed %d", &seed)
88 && 0 == unformat (input, "print %d", &print_every)
89 && 0 == unformat (input, "validdata %|",
90 &check_mask, CHECK_DATA | CHECK_VALIDITY)
91 && 0 == unformat (input, "valid %|",
92 &check_mask, CHECK_VALIDITY)
93 && 0 == unformat (input, "verbose %=", &really_verbose, 1)
94 && 0 == unformat (input, "trace %=", &trace, 1)
95 && 0 == unformat (input, "vm %=", &use_vm, 1)
96 && 0 == unformat (input, "align %|", &check_mask, CHECK_ALIGN))
98 clib_warning ("unknown input `%U'", format_unformat_error, input);
103 /* Zero seed means use default. */
105 seed = random_default_seed ();
108 ("testing %d iterations, %d %saligned objects, max. size %d, seed %d",
109 n_iterations, n_objects, (check_mask & CHECK_ALIGN) ? "randomly " : "un",
110 max_object_size, seed);
112 vec_resize (objects, n_objects);
113 if (vec_bytes (objects) > 0) /* stupid warning be gone */
114 memset (objects, ~0, vec_bytes (objects));
117 /* Allocate initial heap. */
120 max_pow2 (2 * n_objects * max_object_size * sizeof (data[0]));
122 h_mem = clib_mem_alloc (size);
126 h = mheap_alloc (h_mem, size);
130 mheap_trace (h, trace);
132 mh = mheap_header (h);
135 mh->flags &= ~MHEAP_FLAG_DISABLE_VM;
137 mh->flags |= MHEAP_FLAG_DISABLE_VM;
139 if (check_mask & CHECK_VALIDITY)
140 mh->flags |= MHEAP_FLAG_VALIDATE;
142 for (i = 0; i < n_iterations; i++)
146 j = random_u32 (&seed) % vec_len (objects);
147 if (objects[j] != ~0 || i + objects_used < n_iterations)
151 if (objects[j] != ~0)
153 mheap_put (h, objects[j]);
159 uword size, align, align_offset;
161 size = (random_u32 (&seed) % max_object_size) * sizeof (data[0]);
162 align = align_offset = 0;
163 if (check_mask & CHECK_ALIGN)
165 align = 1 << (random_u32 (&seed) % 10);
166 align_offset = round_pow2 (random_u32 (&seed) & (align - 1),
170 h = mheap_get_aligned (h, size, align, align_offset, &objects[j]);
173 ASSERT (0 == ((objects[j] + align_offset) & (align - 1)));
175 ASSERT (objects[j] != ~0);
178 /* Set newly allocated object with test data. */
179 if (check_mask & CHECK_DATA)
183 data = (void *) h + objects[j];
184 len = mheap_len (h, data);
186 ASSERT (size <= mheap_data_bytes (h, objects[j]));
189 for (k = 1; k < len; k++)
190 data[k] = objects[j] + k;
194 /* Verify that all used objects have correct test data. */
197 for (j = 0; j < vec_len (objects); j++)
198 if (objects[j] != ~0)
200 u32 *data = h + objects[j];
202 for (k = 1; k < len; k++)
203 ASSERT (data[k] == objects[j] + k);
206 if (print_every != 0 && i > 0 && (i % print_every) == 0)
207 fformat (stderr, "iteration %d: %U\n", i, format_mheap, h,
212 fformat (stderr, "%U\n", format_mheap, h, really_verbose);
214 clib_mem_free (h_mem);
222 main (int argc, char *argv[])
227 verbose = (argc > 1);
228 unformat_init_command_line (&i, argv);
229 ret = test_mheap_main (&i);
234 #endif /* CLIB_UNIX */
237 * fd.io coding-style-patch-verification: ON
240 * eval: (c-set-style "gnu")