Skip to content

Commit

Permalink
[umf] add out of memory test
Browse files Browse the repository at this point in the history
  • Loading branch information
Damian Duy committed Aug 14, 2023
1 parent 333cfc2 commit 3ff3933
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 15 deletions.
9 changes: 2 additions & 7 deletions test/unified_malloc_framework/common/pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ struct proxy_pool : public pool_base {

memset(ptr, 0, num * size);

if (ptr) {
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
}
umf::getPoolLastStatusRef<proxy_pool>() = ret;
return ptr;
}
void *realloc(void *ptr, size_t size) noexcept {
Expand All @@ -145,9 +143,7 @@ struct proxy_pool : public pool_base {
void *aligned_malloc(size_t size, size_t alignment) noexcept {
void *ptr;
auto ret = umfMemoryProviderAlloc(provider, size, alignment, &ptr);
if (ptr) {
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
}
umf::getPoolLastStatusRef<proxy_pool>() = ret;
return ptr;
}
size_t malloc_usable_size(void *ptr) noexcept {
Expand All @@ -156,7 +152,6 @@ struct proxy_pool : public pool_base {
}
enum umf_result_t free(void *ptr) noexcept {
auto ret = umfMemoryProviderFree(provider, ptr, 0);
EXPECT_EQ_NOEXCEPT(ret, UMF_RESULT_SUCCESS);
return ret;
}
enum umf_result_t get_last_allocation_error() {
Expand Down
24 changes: 23 additions & 1 deletion test/unified_malloc_framework/common/provider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ auto wrapProviderUnique(umf_memory_provider_handle_t hProvider) {
}

struct provider_base {
umf_result_t initialize() noexcept { return UMF_RESULT_SUCCESS; };
umf_result_t initialize(int) noexcept { return UMF_RESULT_SUCCESS; };
enum umf_result_t alloc(size_t, size_t, void **) noexcept {
return UMF_RESULT_ERROR_UNKNOWN;
}
Expand Down Expand Up @@ -76,6 +76,28 @@ struct provider_malloc : public provider_base {
const char *get_name() noexcept { return "malloc"; }
};

struct provider_mock_out_of_mem : public provider_base {
provider_malloc helper_prov;
int allocNum = 0;
umf_result_t initialize(int allocNum) noexcept {
this->allocNum = allocNum;
return UMF_RESULT_SUCCESS;
}
enum umf_result_t alloc(size_t size, size_t align, void **ptr) noexcept {
if (allocNum <= 0) {
*ptr = nullptr;
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}
allocNum--;

return helper_prov.alloc(size, align, ptr);
}
enum umf_result_t free(void *ptr, size_t size) noexcept {
return helper_prov.free(ptr, size);
}
const char *get_name() noexcept { return "mock_out_of_mem"; }
};

} // namespace umf_test

#endif /* UMF_TEST_PROVIDER_HPP */
23 changes: 23 additions & 0 deletions test/unified_malloc_framework/memoryPool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// See LICENSE.TXT
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "disjoint_pool.hpp"
#include "pool.hpp"
#include "provider.hpp"

#include <array>
#include <cstring>
Expand Down Expand Up @@ -53,6 +55,11 @@ struct umfMultiPoolTest : umfPoolTest {
std::vector<umf::pool_unique_handle_t> pools;
};

struct umfMemTest : umfPoolTest {
void SetUp() override { umfPoolTest::SetUp(); }
void TearDown() override { umfPoolTest::TearDown(); }
};

TEST_P(umfPoolTest, allocFree) {
static constexpr size_t allocSize = 64;
auto *ptr = umfPoolMalloc(pool.get(), allocSize);
Expand Down Expand Up @@ -251,6 +258,22 @@ TEST_P(umfPoolTest, multiThreadedMallocFreeRandomSizes) {
}
}

TEST_P(umfMemTest, outOfMem) {
static constexpr size_t allocSize = 16;
auto hPool = pool.get();

std::vector<void *> allocations;

while (true) {
allocations.emplace_back(umfPoolMalloc(hPool, allocSize));
if (umfPoolGetLastAllocationError(hPool) == UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY) { break;}
}

for (auto allocation : allocations) {
umfPoolFree(hPool, allocation);
}
}

#ifdef UMF_ENABLE_POOL_TRACKING_TESTS
// TODO: add similar tests for realloc/aligned_alloc, etc.
// TODO: add multithreaded tests
Expand Down
16 changes: 11 additions & 5 deletions test/unified_malloc_framework/memoryPoolAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ TEST_F(test, memoryPoolTrace) {
ASSERT_EQ(providerCalls.size(), provider_call_count);

ret = umfPoolGetLastAllocationError(tracingPool.get());
ASSERT_EQ(ret, UMF_RESULT_ERROR_NOT_SUPPORTED);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
ASSERT_EQ(poolCalls["get_last_native_error"], 1);
ASSERT_EQ(poolCalls.size(), ++pool_call_count);

Expand Down Expand Up @@ -143,7 +143,7 @@ INSTANTIATE_TEST_SUITE_P(
INSTANTIATE_TEST_SUITE_P(
mallocProviderPoolTest, umfPoolTest, ::testing::Values([] {
return umf::poolMakeUnique<umf_test::proxy_pool, 1>(
{umf::memoryProviderMakeUnique<umf_test::provider_malloc>()
{umf::memoryProviderMakeUnique<umf_test::provider_malloc>(0)
.second})
.second;
}));
Expand All @@ -152,7 +152,15 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(umfMultiPoolTest);
INSTANTIATE_TEST_SUITE_P(
mallocMultiPoolTest, umfMultiPoolTest, ::testing::Values([] {
return umf::poolMakeUnique<umf_test::proxy_pool, 1>(
{umf::memoryProviderMakeUnique<umf_test::provider_malloc>()
{umf::memoryProviderMakeUnique<umf_test::provider_malloc>(0)
.second})
.second;
}));

INSTANTIATE_TEST_SUITE_P(
proxyPoolOOMTest, umfMemTest, ::testing::Values([] {
return umf::poolMakeUnique<umf_test::proxy_pool, 1>(
{umf::memoryProviderMakeUnique<umf_test::provider_mock_out_of_mem>(10)
.second})
.second;
}));
Expand Down Expand Up @@ -254,10 +262,8 @@ TEST_F(test, getLastFailedMemoryProvider) {
auto [ret, pool] = umf::poolMakeUnique<umf_test::proxy_pool>(&hProvider, 1);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);

ASSERT_EQ(umfGetLastFailedMemoryProvider(), nullptr);
auto ptr = umfPoolMalloc(pool.get(), allocSize);
ASSERT_NE(ptr, nullptr);
ASSERT_EQ(umfGetLastFailedMemoryProvider(), nullptr);
umfPoolFree(pool.get(), ptr);

// make provider return an error during allocation
Expand Down
17 changes: 15 additions & 2 deletions test/unified_malloc_framework/umf_pools/disjoint_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,17 @@ static usm::DisjointPool::Config poolConfig() {

static auto makePool() {
auto [ret, provider] =
umf::memoryProviderMakeUnique<umf_test::provider_malloc>();
umf::memoryProviderMakeUnique<umf_test::provider_malloc>(0);
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
auto [retp, pool] = umf::poolMakeUnique<usm::DisjointPool, 1>(
{std::move(provider)}, poolConfig());
EXPECT_EQ(retp, UMF_RESULT_SUCCESS);
return std::move(pool);
}

static auto makePoolOOMProvider() {
auto [ret, provider] =
umf::memoryProviderMakeUnique<umf_test::provider_mock_out_of_mem>(10);
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
auto [retp, pool] = umf::poolMakeUnique<usm::DisjointPool, 1>(
{std::move(provider)}, poolConfig());
Expand All @@ -49,7 +59,7 @@ TEST_F(test, freeErrorPropagation) {
};

auto [ret, providerUnique] =
umf::memoryProviderMakeUnique<memory_provider>();
umf::memoryProviderMakeUnique<memory_provider>(0);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);

auto config = poolConfig();
Expand All @@ -72,6 +82,9 @@ TEST_F(test, freeErrorPropagation) {
INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfPoolTest,
::testing::Values(makePool));

INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfMemTest,
::testing::Values(makePoolOOMProvider));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(umfMultiPoolTest);
INSTANTIATE_TEST_SUITE_P(disjointMultiPoolTests, umfMultiPoolTest,
::testing::Values(makePool));

0 comments on commit 3ff3933

Please sign in to comment.