while (*byte == 0) {
get_random_bytes(byte, 1);
KUNIT_ASSERT_LT_MSG(test, failed_rng++, 100, "Is the RNG broken?");
}
}
staticvoid init_large(struct kunit *test)
{ /* Get many bit patterns. */
get_random_bytes(large_src, ARRAY_SIZE(large_src));
/* Make sure we have non-zero edges. */
set_random_nonzero(test, &large_src[0]);
set_random_nonzero(test, &large_src[ARRAY_SIZE(large_src) - 1]);
/* Explicitly zero the entire destination. */
memset(large_dst, 0, ARRAY_SIZE(large_dst));
}
/* * Instead of an indirect function call for "copy" or a giant macro, * use a bool to pick memcpy or memmove.
*/ staticvoid copy_large_test(struct kunit *test, bool use_memmove)
{
init_large(test);
/* Copy a growing number of non-overlapping bytes ... */ for (int bytes = 1; bytes <= ARRAY_SIZE(large_src); bytes++) { /* Over a shifting destination window ... */ for (int offset = 0; offset < ARRAY_SIZE(large_src); offset++) { int right_zero_pos = offset + bytes; int right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
/* Did we touch anything before the copy area? */
KUNIT_ASSERT_EQ_MSG(test,
memcmp(large_dst, large_zero, offset), 0, "with size %d at offset %d", bytes, offset); /* Did we touch anything after the copy area? */
KUNIT_ASSERT_EQ_MSG(test,
memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0, "with size %d at offset %d", bytes, offset);
/* Are we byte-for-byte exact across the copy? */
KUNIT_ASSERT_EQ_MSG(test,
memcmp(large_dst + offset, large_src, bytes), 0, "with size %d at offset %d", bytes, offset);
/* Zero out what we copied for the next cycle. */
memset(large_dst + offset, 0, bytes);
} /* Avoid stall warnings if this loop gets slow. */
cond_resched();
}
}
/* * On the assumption that boundary conditions are going to be the most * sensitive, instead of taking a full step (inc) each iteration, * take single index steps for at least the first "inc"-many indexes * from the "start" and at least the last "inc"-many indexes before * the "end". When in the middle, take full "inc"-wide steps. For * example, calling next_step(idx, 1, 15, 3) with idx starting at 0 * would see the following pattern: 1 2 3 4 7 10 11 12 13 14 15.
*/ staticint next_step(int idx, int start, int end, int inc)
{
start += inc;
end -= inc;
staticvoid inner_loop(struct kunit *test, int bytes, int d_off, int s_off)
{ int left_zero_pos, left_zero_size; int right_zero_pos, right_zero_size; int src_pos, src_orig_pos, src_size; int pos;
/* Place the source in the destination buffer. */
memcpy(&large_dst[s_off], large_src, bytes);
/* Copy to destination offset. */
memmove(&large_dst[d_off], &large_dst[s_off], bytes);
/* Make sure destination entirely matches. */
KUNIT_ASSERT_EQ_MSG(test, memcmp(&large_dst[d_off], large_src, bytes), 0, "with size %d at src offset %d and dest offset %d",
bytes, s_off, d_off);
/* Calculate the expected zero spans. */ if (s_off < d_off) {
left_zero_pos = 0;
left_zero_size = s_off;
/* Check non-overlapping source is unchanged.*/
KUNIT_ASSERT_EQ_MSG(test,
memcmp(&large_dst[src_pos], &large_src[src_orig_pos], src_size), 0, "with size %d at src offset %d and dest offset %d",
bytes, s_off, d_off);
/* Check leading buffer contents are zero. */
KUNIT_ASSERT_EQ_MSG(test,
memcmp(&large_dst[left_zero_pos], large_zero, left_zero_size), 0, "with size %d at src offset %d and dest offset %d",
bytes, s_off, d_off); /* Check trailing buffer contents are zero. */
KUNIT_ASSERT_EQ_MSG(test,
memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0, "with size %d at src offset %d and dest offset %d",
bytes, s_off, d_off);
/* Zero out everything not already zeroed.*/
pos = left_zero_pos + left_zero_size;
memset(&large_dst[pos], 0, right_zero_pos - pos);
}
staticvoid memmove_overlap_test(struct kunit *test)
{ /* * Running all possible offset and overlap combinations takes a * very long time. Instead, only check up to 128 bytes offset * into the destination buffer (which should result in crossing * cachelines), with a step size of 1 through 7 to try to skip some * redundancy.
*/ staticconstint offset_max = 128; /* less than ARRAY_SIZE(large_src); */ staticconstint bytes_step = 7; staticconstint window_step = 7;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.