int test_random_main (unformat_input_t * input) { uword n_iterations; uword i, repeat_count; uword * bitmap = 0; uword print; u32 seed; u32 *seedp = &seed; /* first, check known sequence from Numerical Recipes in C, 2nd ed. page 284 */ seed = known_random_sequence[0]; for (i = 0; i < ARRAY_LEN(known_random_sequence)-1; i++) { u32 rv; rv = random_u32 (seedp); if (rv != known_random_sequence[i+1]) { fformat(stderr, "known sequence check FAILS at index %d", i+1); break; } } clib_warning ("known sequence check passes"); n_iterations = 1000; seed = 0; print = 1 << 24; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (0 == unformat (input, "iter %d", &n_iterations) && 0 == unformat (input, "print %d", &print) && 0 == unformat (input, "seed %d", &seed)) clib_error ("unknown input `%U'", format_unformat_error, input); } if (! seed) seed = random_default_seed (); if (n_iterations == 0) n_iterations = random_u32_max (); clib_warning ("%d iterations, seed %d\n", n_iterations, seed); repeat_count = 0; for (i = 0; i < n_iterations; i++) { uword r = random_u32 (&seed); uword b, ri, rj; ri = r / BITS (bitmap[0]); rj = (uword) 1 << (r % BITS (bitmap[0])); vec_validate (bitmap, ri); b = bitmap[ri]; if (b & rj) goto repeat; b |= rj; bitmap[ri] = b; if (0 == (i & (print - 1))) fformat (stderr, "0x%08x iterations %d repeats\n", i, repeat_count); continue; repeat: fformat (stderr, "repeat found at iteration %d/%d\n", i, n_iterations); repeat_count++; continue; } return 0; }
int test_mheap_main (unformat_input_t * input) { int i, j, k, n_iterations; void *h, *h_mem; uword *objects = 0; u32 objects_used, really_verbose, n_objects, max_object_size; u32 check_mask, seed, trace, use_vm; u32 print_every = 0; u32 *data; mheap_t *mh; /* Validation flags. */ check_mask = 0; #define CHECK_VALIDITY 1 #define CHECK_DATA 2 #define CHECK_ALIGN 4 #define TEST1 8 n_iterations = 10; seed = 0; max_object_size = 100; n_objects = 1000; trace = 0; really_verbose = 0; use_vm = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (0 == unformat (input, "iter %d", &n_iterations) && 0 == unformat (input, "count %d", &n_objects) && 0 == unformat (input, "size %d", &max_object_size) && 0 == unformat (input, "seed %d", &seed) && 0 == unformat (input, "print %d", &print_every) && 0 == unformat (input, "validdata %|", &check_mask, CHECK_DATA | CHECK_VALIDITY) && 0 == unformat (input, "valid %|", &check_mask, CHECK_VALIDITY) && 0 == unformat (input, "verbose %=", &really_verbose, 1) && 0 == unformat (input, "trace %=", &trace, 1) && 0 == unformat (input, "vm %=", &use_vm, 1) && 0 == unformat (input, "align %|", &check_mask, CHECK_ALIGN) && 0 == unformat (input, "test1 %|", &check_mask, TEST1)) { clib_warning ("unknown input `%U'", format_unformat_error, input); return 1; } } /* Zero seed means use default. */ if (!seed) seed = random_default_seed (); if (check_mask & TEST1) { return test1 (); } if_verbose ("testing %d iterations, %d %saligned objects, max. size %d, seed %d", n_iterations, n_objects, (check_mask & CHECK_ALIGN) ? "randomly " : "un", max_object_size, seed); vec_resize (objects, n_objects); if (vec_bytes (objects) > 0) /* stupid warning be gone */ clib_memset (objects, ~0, vec_bytes (objects)); objects_used = 0; /* Allocate initial heap. */ { uword size = max_pow2 (2 * n_objects * max_object_size * sizeof (data[0])); h_mem = clib_mem_alloc (size); if (!h_mem) return 0; h = mheap_alloc (h_mem, size); } if (trace) mheap_trace (h, trace); mh = mheap_header (h); if (use_vm) mh->flags &= ~MHEAP_FLAG_DISABLE_VM; else mh->flags |= MHEAP_FLAG_DISABLE_VM; if (check_mask & CHECK_VALIDITY) mh->flags |= MHEAP_FLAG_VALIDATE; for (i = 0; i < n_iterations; i++) { while (1) { j = random_u32 (&seed) % vec_len (objects); if (objects[j] != ~0 || i + objects_used < n_iterations) break; } if (objects[j] != ~0) { mheap_put (h, objects[j]); objects_used--; objects[j] = ~0; } else { uword size, align, align_offset; size = (random_u32 (&seed) % max_object_size) * sizeof (data[0]); align = align_offset = 0; if (check_mask & CHECK_ALIGN) { align = 1 << (random_u32 (&seed) % 10); align_offset = round_pow2 (random_u32 (&seed) & (align - 1), sizeof (u32)); } h = mheap_get_aligned (h, size, align, align_offset, &objects[j]); if (align > 0) ASSERT (0 == ((objects[j] + align_offset) & (align - 1))); ASSERT (objects[j] != ~0); objects_used++; /* Set newly allocated object with test data. */ if (check_mask & CHECK_DATA) { uword len; data = (void *) h + objects[j]; len = mheap_len (h, data); ASSERT (size <= mheap_data_bytes (h, objects[j])); data[0] = len; for (k = 1; k < len; k++) data[k] = objects[j] + k; } } /* Verify that all used objects have correct test data. */ if (check_mask & 2) { for (j = 0; j < vec_len (objects); j++) if (objects[j] != ~0) { u32 *data = h + objects[j]; uword len = data[0]; for (k = 1; k < len; k++) ASSERT (data[k] == objects[j] + k); } } if (print_every != 0 && i > 0 && (i % print_every) == 0) fformat (stderr, "iteration %d: %U\n", i, format_mheap, h, really_verbose); } if (verbose) fformat (stderr, "%U\n", format_mheap, h, really_verbose); mheap_free (h); clib_mem_free (h_mem); vec_free (objects); return 0; }