diff --git a/runtime/os_interface/32bit_memory.h b/runtime/os_interface/32bit_memory.h index dc7ddb65a9..1c91bd5948 100644 --- a/runtime/os_interface/32bit_memory.h +++ b/runtime/os_interface/32bit_memory.h @@ -1,23 +1,8 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (C) 2017-2019 Intel Corporation * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * SPDX-License-Identifier: MIT * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ #pragma once @@ -36,10 +21,10 @@ class Allocator32bit { Allocator32bit(uint64_t base, uint64_t size); Allocator32bit(Allocator32bit::OsInternals *osInternals); Allocator32bit(); - ~Allocator32bit(); + MOCKABLE_VIRTUAL ~Allocator32bit(); uint64_t allocate(size_t &size); - uintptr_t getBase(); + uintptr_t getBase() const; int free(uint64_t ptr, size_t size); protected: diff --git a/runtime/os_interface/linux/drm_32bit_memory.cpp b/runtime/os_interface/linux/drm_32bit_memory.cpp index 2d49ef079e..1e7c67b094 100644 --- a/runtime/os_interface/linux/drm_32bit_memory.cpp +++ b/runtime/os_interface/linux/drm_32bit_memory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2018 Intel Corporation + * Copyright (C) 2017-2019 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -9,8 +9,8 @@ #include "runtime/os_interface/32bit_memory.h" #include "runtime/os_interface/linux/allocator_helper.h" #include "runtime/helpers/aligned_memory.h" -#include "runtime/helpers/ptr_math.h" #include "runtime/helpers/basic_math.h" +#include "runtime/helpers/ptr_math.h" #include "runtime/os_interface/debug_settings_manager.h" #include @@ -24,7 +24,7 @@ class Allocator32bit::OsInternals { uintptr_t lowerRangeAddress = lowerRangeStart; decltype(&mmap) mmapFunction = mmap; decltype(&munmap) munmapFunction = munmap; - void *heapBasePtr = (void *)0; + void *heapBasePtr = nullptr; size_t heapSize = 0; class Drm32BitAllocator { @@ -71,18 +71,14 @@ class Allocator32bit::OsInternals { } return outer.munmapFunction(ptr, size); } - - ~Drm32BitAllocator() = default; }; Drm32BitAllocator *drmAllocator = nullptr; }; bool OCLRT::is32BitOsAllocatorAvailable = true; -Allocator32bit::Allocator32bit(uint64_t base, uint64_t size) { - this->base = base; - this->size = size; - heapAllocator = std::unique_ptr(new HeapAllocator(base, size)); +Allocator32bit::Allocator32bit(uint64_t base, uint64_t size) : base(base), size(size) { + heapAllocator = std::make_unique(base, size); } OCLRT::Allocator32bit::Allocator32bit() : Allocator32bit(new OsInternals) { @@ -92,31 +88,25 @@ OCLRT::Allocator32bit::Allocator32bit(Allocator32bit::OsInternals *osInternalsIn if (DebugManager.flags.UseNewHeapAllocator.get()) { size_t sizeToMap = getSizeToMap(); - void *ptr = MAP_FAILED; - - ptr = this->osInternals->mmapFunction(nullptr, sizeToMap, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); + void *ptr = this->osInternals->mmapFunction(nullptr, sizeToMap, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); if (ptr == MAP_FAILED) { - size_t sizeToMapRetry = sizeToMap - (sizeToMap / 4); + sizeToMap -= sizeToMap / 4; ptr = this->osInternals->mmapFunction(nullptr, sizeToMap, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); DebugManager.log(DebugManager.flags.PrintDebugMessages.get(), __FUNCTION__, " Allocator RETRY ptr == ", ptr); - if (ptr != MAP_FAILED) { - sizeToMap = sizeToMapRetry; + if (ptr == MAP_FAILED) { + ptr = nullptr; + sizeToMap = 0; } } - DebugManager.log(DebugManager.flags.PrintDebugMessages.get(), __FUNCTION__, "Allocator ptr == \n", ptr); + DebugManager.log(DebugManager.flags.PrintDebugMessages.get(), __FUNCTION__, "Allocator ptr == ", ptr); - if (ptr == MAP_FAILED) { - ptr = nullptr; - sizeToMap = 0; - } - - osInternals->heapBasePtr = (void *)ptr; + osInternals->heapBasePtr = ptr; osInternals->heapSize = sizeToMap; - base = (uint64_t)ptr; + base = reinterpret_cast(ptr); size = sizeToMap; heapAllocator = std::unique_ptr(new HeapAllocator(base, sizeToMap)); @@ -127,7 +117,7 @@ OCLRT::Allocator32bit::Allocator32bit(Allocator32bit::OsInternals *osInternalsIn OCLRT::Allocator32bit::~Allocator32bit() { if (this->osInternals.get() != nullptr) { - if (this->osInternals->heapBasePtr != (void *)0) + if (this->osInternals->heapBasePtr != nullptr) this->osInternals->munmapFunction(this->osInternals->heapBasePtr, this->osInternals->heapSize); if (this->osInternals->drmAllocator != nullptr) @@ -146,7 +136,7 @@ uint64_t OCLRT::Allocator32bit::allocate(size_t &size) { } int Allocator32bit::free(uint64_t ptr, size_t size) { - if ((ptr == reinterpret_cast(MAP_FAILED)) || (ptr == 0llu)) + if (ptr == reinterpret_cast(MAP_FAILED) || ptr == 0llu) return 0; if (DebugManager.flags.UseNewHeapAllocator.get()) { @@ -157,6 +147,6 @@ int Allocator32bit::free(uint64_t ptr, size_t size) { return 0; } -uintptr_t Allocator32bit::getBase() { +uintptr_t Allocator32bit::getBase() const { return (uintptr_t)base; } diff --git a/runtime/os_interface/windows/wddm_32bit_memory.cpp b/runtime/os_interface/windows/wddm_32bit_memory.cpp index 42eae9b76f..afb4cc561d 100644 --- a/runtime/os_interface/windows/wddm_32bit_memory.cpp +++ b/runtime/os_interface/windows/wddm_32bit_memory.cpp @@ -1,49 +1,32 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (C) 2017-2019 Intel Corporation * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * SPDX-License-Identifier: MIT * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. */ #include "runtime/os_interface/32bit_memory.h" #include "runtime/helpers/aligned_memory.h" using namespace OCLRT; -bool OCLRT::is32BitOsAllocatorAvailable = is64bit ? true : false; +bool OCLRT::is32BitOsAllocatorAvailable = is64bit; class Allocator32bit::OsInternals { public: void *allocatedRange; }; -Allocator32bit::Allocator32bit(uint64_t base, uint64_t size) { - this->base = base; - this->size = size; - heapAllocator = std::unique_ptr(new HeapAllocator(base, size)); +Allocator32bit::Allocator32bit(uint64_t base, uint64_t size) : base(base), size(size) { + heapAllocator = std::make_unique(base, size); } OCLRT::Allocator32bit::Allocator32bit() { size_t sizeToMap = 100 * 4096; this->base = (uint64_t)alignedMalloc(sizeToMap, 4096); - osInternals = std::unique_ptr(new OsInternals); - osInternals.get()->allocatedRange = (void *)((uintptr_t)this->base); + osInternals = std::make_unique(); + osInternals->allocatedRange = (void *)((uintptr_t)this->base); - heapAllocator = std::unique_ptr(new HeapAllocator(this->base, sizeToMap)); + heapAllocator = std::make_unique(this->base, sizeToMap); } OCLRT::Allocator32bit::~Allocator32bit() { @@ -63,6 +46,6 @@ int Allocator32bit::free(uint64_t ptr, size_t size) { return 0; } -uintptr_t Allocator32bit::getBase() { +uintptr_t Allocator32bit::getBase() const { return (uintptr_t)base; } diff --git a/unit_tests/mocks/mock_32bitAllocator.h b/unit_tests/mocks/mock_32bitAllocator.h index 06752be2c4..985952a820 100644 --- a/unit_tests/mocks/mock_32bitAllocator.h +++ b/unit_tests/mocks/mock_32bitAllocator.h @@ -1,11 +1,12 @@ /* - * Copyright (C) 2017-2018 Intel Corporation + * Copyright (C) 2017-2019 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once +#include #include "runtime/os_interface/32bit_memory.h" #include "runtime/os_interface/linux/drm_32bit_memory.cpp" #include "runtime/helpers/aligned_memory.h" @@ -16,6 +17,7 @@ static bool failMmap = false; static bool fail32BitMmap = false; static bool failUpperRange = false; static bool failLowerRanger = false; +static size_t maxMmapLength = std::numeric_limits::max(); static uintptr_t startUpperHeap = maxMmap32BitAddress; static uintptr_t lowerRangeHeapStart = lowerRangeStart; @@ -33,8 +35,9 @@ void *MockMmap(void *addr, size_t length, int prot, int flags, bool returnLowerRange = false; mmapCallCount++; - if (failMmap) + if (failMmap || length > maxMmapLength) { return MAP_FAILED; + } if (mmapFailCount > 0) { mmapFailCount--; @@ -83,20 +86,20 @@ int MockMunmap(void *addr, size_t length) noexcept { return 0; } -class mockAllocator32Bit : public Allocator32bit { +class MockAllocator32Bit : public Allocator32bit { public: class OsInternalsPublic : public Allocator32bit::OsInternals { }; - mockAllocator32Bit(Allocator32bit::OsInternals *osInternalsIn) : Allocator32bit(osInternalsIn) { + MockAllocator32Bit(Allocator32bit::OsInternals *osInternalsIn) : Allocator32bit(osInternalsIn) { } - mockAllocator32Bit() { + MockAllocator32Bit() { this->osInternals->mmapFunction = MockMmap; this->osInternals->munmapFunction = MockMunmap; resetState(); } - ~mockAllocator32Bit() { + ~MockAllocator32Bit() { resetState(); } static void resetState() { @@ -104,6 +107,7 @@ class mockAllocator32Bit : public Allocator32bit { failUpperRange = false; failLowerRanger = false; failMmap = false; + maxMmapLength = std::numeric_limits::max(); startUpperHeap = maxMmap32BitAddress; lowerRangeHeapStart = lowerRangeStart; offsetIn32BitRange = 0u; @@ -116,6 +120,6 @@ class mockAllocator32Bit : public Allocator32bit { return new OsInternalsPublic; } - OsInternals *getosInternal() { return this->osInternals.get(); } + OsInternals *getOsInternals() const { return this->osInternals.get(); } }; } // namespace OCLRT \ No newline at end of file diff --git a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp index 69165b4d32..bc88e3f6c5 100644 --- a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp @@ -2235,45 +2235,42 @@ TEST(Allocator32BitUsingHeapAllocator, given32BitAllocatorWhenMMapFailsThenNullp DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(true); - mockAllocator32Bit::resetState(); + MockAllocator32Bit::resetState(); failMmap = true; - mockAllocator32Bit::OsInternalsPublic *osInternals = mockAllocator32Bit::createOsInternals(); + MockAllocator32Bit::OsInternalsPublic *osInternals = MockAllocator32Bit::createOsInternals(); osInternals->mmapFunction = MockMmap; osInternals->munmapFunction = MockMunmap; - mockAllocator32Bit *mock32BitAllocator = new mockAllocator32Bit(osInternals); + MockAllocator32Bit mock32BitAllocator{osInternals}; size_t size = 100u; - auto ptr = mock32BitAllocator->allocate(size); + auto ptr = mock32BitAllocator.allocate(size); EXPECT_EQ(0llu, ptr); EXPECT_EQ(2u, mmapCallCount); - delete mock32BitAllocator; } TEST(Allocator32BitUsingHeapAllocator, given32BitAllocatorWhenFirstMMapFailsThenSecondIsCalledWithSmallerSize) { DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(true); - mockAllocator32Bit::resetState(); - mmapFailCount = 1u; - mockAllocator32Bit::OsInternalsPublic *osInternals = mockAllocator32Bit::createOsInternals(); + MockAllocator32Bit::resetState(); + maxMmapLength = getSizeToMap() - 1; + MockAllocator32Bit::OsInternalsPublic *osInternals = MockAllocator32Bit::createOsInternals(); osInternals->mmapFunction = MockMmap; osInternals->munmapFunction = MockMunmap; - mockAllocator32Bit *mock32BitAllocator = new mockAllocator32Bit(osInternals); + MockAllocator32Bit mock32BitAllocator{osInternals}; size_t size = 100u; - auto ptr = mock32BitAllocator->allocate(size); + auto ptr = mock32BitAllocator.allocate(size); EXPECT_NE(0llu, ptr); EXPECT_EQ(2u, mmapCallCount); EXPECT_NE(nullptr, osInternals->heapBasePtr); EXPECT_NE(0u, osInternals->heapSize); - - delete mock32BitAllocator; } TEST(DrmAllocator32Bit, allocateReturnsPointer) { DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; size_t size = 100u; auto ptr = mock32BitAllocator.allocate(size); EXPECT_NE(0u, (uintptr_t)ptr); @@ -2285,7 +2282,7 @@ TEST(DrmAllocator32Bit, freeMapFailedPointer) { DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; size_t size = 100u; int result = mock32BitAllocator.free(reinterpret_cast(MAP_FAILED), size); EXPECT_EQ(0, result); @@ -2295,7 +2292,7 @@ TEST(DrmAllocator32Bit, freeNullPtrPointer) { DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; uint32_t size = 100u; int result = mock32BitAllocator.free(0llu, size); EXPECT_EQ(0, result); @@ -2305,7 +2302,7 @@ TEST(DrmAllocator32Bit, freeLowerRangeAfterTwoMmapFails) { DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; mmapFailCount = 2; size_t size = 100u; auto ptr = mock32BitAllocator.allocate(size); @@ -2318,7 +2315,7 @@ TEST(DrmAllocator32Bit, given32BitAllocatorWhenMMapFailsThenUpperHeapIsBrowsedFo DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; fail32BitMmap = true; size_t size = 100u; auto ptr = mock32BitAllocator.allocate(size); @@ -2330,7 +2327,7 @@ TEST(DrmAllocator32Bit, given32BitAllocatorWith32AndUpperHeapsExhaustedThenPoint DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; fail32BitMmap = true; failUpperRange = true; size_t size = 100u; @@ -2343,7 +2340,7 @@ TEST(DrmAllocator32Bit, given32bitRegionExhaustedWhenTwoAllocationsAreCreatedThe DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; fail32BitMmap = true; size_t size = 100u; auto ptr = (uintptr_t)mock32BitAllocator.allocate(size); @@ -2356,7 +2353,7 @@ TEST(DrmAllocator32Bit, given32bitRegionExhaustedWhenTwoAllocationsAreCreatedThe EXPECT_EQ(4u, mmapCallCount); mock32BitAllocator.free(ptr2, size); - auto getInternals = mock32BitAllocator.getosInternal(); + auto getInternals = mock32BitAllocator.getOsInternals(); EXPECT_EQ(ptr2, getInternals->upperRangeAddress); mock32BitAllocator.free(ptr, size); @@ -2369,7 +2366,7 @@ TEST(DrmAllocator32Bit, given32bitRegionAndUpperRegionExhaustedWhenTwoAllocation DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; fail32BitMmap = true; failUpperRange = true; size_t size = 100u; @@ -2383,7 +2380,7 @@ TEST(DrmAllocator32Bit, given32bitRegionAndUpperRegionExhaustedWhenTwoAllocation EXPECT_EQ(6u, mmapCallCount); mock32BitAllocator.free(ptr2, size); - auto getInternals = mock32BitAllocator.getosInternal(); + auto getInternals = mock32BitAllocator.getOsInternals(); EXPECT_EQ(ptr2, getInternals->lowerRangeAddress); mock32BitAllocator.free(ptr, size); @@ -2396,7 +2393,7 @@ TEST(DrmAllocator32Bit, given32bitAllocatorWithAllHeapsExhaustedWhenAskedForAllo DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; fail32BitMmap = true; failLowerRanger = true; failUpperRange = true; @@ -2414,7 +2411,7 @@ TEST(DrmAllocator32Bit, given32bitAllocatorWithUpperHeapCloseToFullWhenAskedForA DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; fail32BitMmap = true; size_t size = 3 * 1024 * 1024 * 1029u; @@ -2429,7 +2426,7 @@ TEST(DrmAllocator32Bit, givenMapFailedAsInputToFreeFunctionWhenItIsCalledThenUnm DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; mock32BitAllocator.free(reinterpret_cast(MAP_FAILED), 100u); EXPECT_EQ(0u, unmapCallCount); } @@ -2438,7 +2435,7 @@ TEST(DrmAllocator32Bit, givenNullptrAsInputToFreeFunctionWhenItIsCalledThenUnmap DebugManagerStateRestore restore; DebugManager.flags.UseNewHeapAllocator.set(false); - mockAllocator32Bit mock32BitAllocator; + MockAllocator32Bit mock32BitAllocator; mock32BitAllocator.free(0llu, 100u); EXPECT_EQ(0u, unmapCallCount); }