292 lines
12 KiB
C++
292 lines
12 KiB
C++
/*
|
|
* Copyright (C) 2021 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#include "shared/source/helpers/l3_range.h"
|
|
#include "shared/test/common/test_macros/test.h"
|
|
|
|
using namespace NEO;
|
|
|
|
constexpr uint64_t l3RangeMinimumAlignment = MemoryConstants::pageSize;
|
|
constexpr uint64_t l3RangeMax = 4 * MemoryConstants::gigaByte;
|
|
const uint64_t defaultPolicy = 0;
|
|
|
|
TEST(L3Range, whenMeetsMinimumAlignmentThenTrueIsReturned) {
|
|
EXPECT_TRUE(L3Range::meetsMinimumAlignment(0));
|
|
EXPECT_TRUE(L3Range::meetsMinimumAlignment(l3RangeMinimumAlignment));
|
|
EXPECT_TRUE(L3Range::meetsMinimumAlignment(l3RangeMinimumAlignment * 2));
|
|
EXPECT_TRUE(L3Range::meetsMinimumAlignment(l3RangeMinimumAlignment * 3));
|
|
EXPECT_TRUE(L3Range::meetsMinimumAlignment(l3RangeMinimumAlignment * 4));
|
|
}
|
|
|
|
TEST(L3Range, whenDoesNotMeetMinimumAlignmentThenFalseIsReturned) {
|
|
EXPECT_FALSE(L3Range::meetsMinimumAlignment(1));
|
|
EXPECT_FALSE(L3Range::meetsMinimumAlignment(l3RangeMinimumAlignment - 1));
|
|
}
|
|
|
|
TEST(L3Range, whenValidSizeThenProperMaskFromSizeIsReturned) {
|
|
EXPECT_EQ(0U, L3Range::getMaskFromSize(l3RangeMinimumAlignment));
|
|
EXPECT_EQ(1U, L3Range::getMaskFromSize(l3RangeMinimumAlignment * 2));
|
|
EXPECT_EQ(2U, L3Range::getMaskFromSize(l3RangeMinimumAlignment * 4));
|
|
EXPECT_EQ(3U, L3Range::getMaskFromSize(l3RangeMinimumAlignment * 8));
|
|
|
|
EXPECT_EQ(19U, L3Range::getMaskFromSize(l3RangeMax / 2));
|
|
EXPECT_EQ(20U, L3Range::getMaskFromSize(l3RangeMax));
|
|
}
|
|
|
|
TEST(L3Range, whenNonPow2SizeThenMaskCalculationIsAborted) {
|
|
EXPECT_THROW(L3Range::getMaskFromSize(l3RangeMinimumAlignment + 1), std::exception);
|
|
}
|
|
|
|
TEST(L3Range, whenTooSmallSizeThenMaskCalculationIsAborted) {
|
|
EXPECT_THROW(L3Range::getMaskFromSize(0), std::exception);
|
|
}
|
|
|
|
TEST(L3Range, whenTooBigSizeThenMaskCalculationIsAborted) {
|
|
EXPECT_THROW(L3Range::getMaskFromSize(l3RangeMax * 2), std::exception);
|
|
}
|
|
|
|
TEST(L3Range, WhenGettingMaskFromSizeThenCorrectSizeIsReturned) {
|
|
L3Range range;
|
|
|
|
range.setMask(L3Range::getMaskFromSize(l3RangeMinimumAlignment));
|
|
EXPECT_EQ(l3RangeMinimumAlignment, range.getSizeInBytes());
|
|
|
|
range.setMask(L3Range::getMaskFromSize(l3RangeMinimumAlignment * 4));
|
|
EXPECT_EQ(l3RangeMinimumAlignment * 4, range.getSizeInBytes());
|
|
|
|
range.setMask(L3Range::getMaskFromSize(l3RangeMax));
|
|
EXPECT_EQ(l3RangeMax, range.getSizeInBytes());
|
|
}
|
|
|
|
TEST(L3Range, whenMaskGetsChangedThenReturnsProperlyMaskedAddress) {
|
|
L3Range range;
|
|
range.setAddress(l3RangeMinimumAlignment * 4 + l3RangeMinimumAlignment * 3 + 1);
|
|
|
|
range.setMask(0);
|
|
EXPECT_EQ(range.getAddress() & ~(l3RangeMinimumAlignment - 1), range.getMaskedAddress());
|
|
|
|
range.setMask(1);
|
|
EXPECT_EQ(range.getAddress() & ~((l3RangeMinimumAlignment << 1) - 1), range.getMaskedAddress());
|
|
|
|
range.setMask(2);
|
|
EXPECT_EQ(range.getAddress() & ~((l3RangeMinimumAlignment << 2) - 1), range.getMaskedAddress());
|
|
|
|
range.setMask(3);
|
|
EXPECT_EQ(0U, range.getMaskedAddress());
|
|
}
|
|
|
|
TEST(L3Range, whenCreatedFromAddressAndMaskThenAddressAndMaskAreProperlySet) {
|
|
{
|
|
L3Range range = L3Range::fromAddressMask(0U, 0U);
|
|
EXPECT_EQ(0U, range.getAddress());
|
|
EXPECT_EQ(0U, range.getMask());
|
|
}
|
|
|
|
{
|
|
L3Range range = L3Range::fromAddressMask(l3RangeMinimumAlignment, 1U);
|
|
EXPECT_EQ(l3RangeMinimumAlignment, range.getAddress());
|
|
EXPECT_EQ(1U, range.getMask());
|
|
}
|
|
|
|
{
|
|
L3Range range = L3Range::fromAddressMask(l3RangeMinimumAlignment * 2, 3U);
|
|
EXPECT_EQ(l3RangeMinimumAlignment * 2, range.getAddress());
|
|
EXPECT_EQ(3U, range.getMask());
|
|
}
|
|
}
|
|
|
|
TEST(L3Range, whenCreatedFromAddressAndSizeThenMaskIsProperlySet) {
|
|
{
|
|
L3Range range = L3Range::fromAddressSize(0, l3RangeMinimumAlignment);
|
|
EXPECT_EQ(0U, range.getAddress());
|
|
EXPECT_EQ(L3Range::getMaskFromSize(l3RangeMinimumAlignment), range.getMask());
|
|
}
|
|
|
|
{
|
|
L3Range range = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment * 2);
|
|
EXPECT_EQ(l3RangeMinimumAlignment, range.getAddress());
|
|
EXPECT_EQ(L3Range::getMaskFromSize(l3RangeMinimumAlignment * 2), range.getMask());
|
|
}
|
|
|
|
{
|
|
L3Range range = L3Range::fromAddressSize(l3RangeMinimumAlignment * 2, l3RangeMax);
|
|
EXPECT_EQ(l3RangeMinimumAlignment * 2, range.getAddress());
|
|
EXPECT_EQ(L3Range::getMaskFromSize(l3RangeMax), range.getMask());
|
|
}
|
|
}
|
|
|
|
TEST(L3Range, whenComparOpIsEqualThenReturnsTrueOnlyIfSame) {
|
|
L3Range a = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment * 2);
|
|
L3Range b = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment * 2);
|
|
L3Range c = L3Range::fromAddressSize(0, l3RangeMinimumAlignment * 2);
|
|
L3Range d = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment);
|
|
|
|
EXPECT_TRUE(a == b);
|
|
EXPECT_FALSE(a == c);
|
|
EXPECT_FALSE(c == a);
|
|
EXPECT_FALSE(a == d);
|
|
EXPECT_FALSE(d == a);
|
|
}
|
|
|
|
TEST(L3Range, whenComparOpIsNotEqualThenReturnsTrueOnlyIfNotSame) {
|
|
L3Range a = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment * 2);
|
|
L3Range b = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment * 2);
|
|
L3Range c = L3Range::fromAddressSize(0, l3RangeMinimumAlignment * 2);
|
|
L3Range d = L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment);
|
|
|
|
EXPECT_FALSE(a != b);
|
|
EXPECT_TRUE(a != c);
|
|
EXPECT_TRUE(c != a);
|
|
EXPECT_TRUE(a != d);
|
|
EXPECT_TRUE(d != a);
|
|
}
|
|
|
|
TEST(CoverRange, whenNonAlignedThenAbort) {
|
|
L3RangesVec ranges;
|
|
EXPECT_THROW(coverRangeExact(1, l3RangeMinimumAlignment, ranges, defaultPolicy), std::exception);
|
|
EXPECT_THROW(coverRangeExact(l3RangeMinimumAlignment, 1, ranges, defaultPolicy), std::exception);
|
|
EXPECT_THROW(coverRangeExact(1, 1, ranges, defaultPolicy), std::exception);
|
|
}
|
|
|
|
L3Range fromAdjacentRange(const L3Range &lhs, uint64_t size) {
|
|
L3Range ret;
|
|
ret.setAddress(lhs.getMaskedAddress() + lhs.getSizeInBytes());
|
|
ret.setMask(L3Range::getMaskFromSize(size));
|
|
return ret;
|
|
}
|
|
|
|
TEST(CoverRange, whenAlignedThenCoverWithProperSubranges) {
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(0, l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(0, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "1 page, offset 0";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(l3RangeMinimumAlignment, l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "1 page, offset 1";
|
|
}
|
|
|
|
// 2 pages
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(0, 2 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(0, 2 * l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "2 pages, offset 0";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(2 * l3RangeMinimumAlignment, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "2 pages, offset 1";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(0, 3 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(0, 2 * l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(2 * l3RangeMinimumAlignment, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "3 pages, offset 0";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(l3RangeMinimumAlignment, 3 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(2 * l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "3 pages, offset 1";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(2 * l3RangeMinimumAlignment, 3 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(2 * l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(4 * l3RangeMinimumAlignment, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "3 pages, offset 2";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(0, 4 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(0, 4 * l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "4 pages, offset 0";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(l3RangeMinimumAlignment, 4 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(l3RangeMinimumAlignment, l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(2 * l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(4 * l3RangeMinimumAlignment, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "4 pages, offset 1";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(2 * l3RangeMinimumAlignment, 4 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(2 * l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(4 * l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "4 pages, offset 2";
|
|
}
|
|
|
|
{
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(3 * l3RangeMinimumAlignment, 4 * l3RangeMinimumAlignment, actualRanges, defaultPolicy);
|
|
|
|
L3RangesVec expectedRanges{L3Range::fromAddressSize(3 * l3RangeMinimumAlignment, l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(4 * l3RangeMinimumAlignment, 2 * l3RangeMinimumAlignment),
|
|
L3Range::fromAddressSize(6 * l3RangeMinimumAlignment, l3RangeMinimumAlignment)};
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "4 pages, offset 3";
|
|
}
|
|
|
|
{
|
|
uint64_t address = 3 * 4096;
|
|
uint64_t size = 1024 * 1024;
|
|
|
|
L3RangesVec actualRanges;
|
|
coverRangeExact(address, size, actualRanges, 0);
|
|
|
|
L3RangesVec expectedRanges;
|
|
expectedRanges.push_back(L3Range::fromAddressSize(address, 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 4 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 8 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 16 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 32 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 64 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 128 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 2 * 4096));
|
|
expectedRanges.push_back(fromAdjacentRange(*expectedRanges.rbegin(), 1 * 4096));
|
|
|
|
EXPECT_EQ(expectedRanges, actualRanges) << "1MB, offset 3 pages";
|
|
}
|
|
}
|
|
TEST(CoverRange, whenRangeCreatedWithPolicyThenAllParamsSetCorrectly) {
|
|
L3Range range = L3Range::fromAddressSizeWithPolicy(0, l3RangeMinimumAlignment, defaultPolicy);
|
|
EXPECT_EQ(0U, range.getAddress());
|
|
EXPECT_EQ(L3Range::getMaskFromSize(l3RangeMinimumAlignment), range.getMask());
|
|
EXPECT_EQ(range.getPolicy(), defaultPolicy);
|
|
|
|
auto policy = defaultPolicy + 1;
|
|
L3Range range2 = L3Range::fromAddressSizeWithPolicy(0, l3RangeMinimumAlignment, policy);
|
|
EXPECT_EQ(range2.getPolicy(), policy);
|
|
}
|