From 280fca7cab1a320eb5119121ff43281fe9383513 Mon Sep 17 00:00:00 2001 From: Damian Duy Date: Tue, 23 May 2023 12:25:15 +0200 Subject: [PATCH] [UMA] add more tests for allocations --- test/unified_memory_allocation/memoryPool.hpp | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/test/unified_memory_allocation/memoryPool.hpp b/test/unified_memory_allocation/memoryPool.hpp index c242419ba1..d3d6ceae88 100644 --- a/test/unified_memory_allocation/memoryPool.hpp +++ b/test/unified_memory_allocation/memoryPool.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifndef UMA_TEST_MEMORY_POOL_OPS_HPP #define UMA_TEST_MEMORY_POOL_OPS_HPP @@ -29,6 +30,7 @@ struct umaPoolTest : uma_test::test, return pool; } + static constexpr int NTHREADS = 5; uma::pool_unique_handle_t pool; }; @@ -57,6 +59,25 @@ TEST_P(umaPoolTest, allocFree) { umaPoolFree(pool.get(), ptr); } +// TEST_P(umaPoolTest, reallocFree) { +// static constexpr size_t allocSize = 64; +// static constexpr size_t multiplier = 3; +// auto *ptr = umaPoolMalloc(pool.get(), allocSize); +// ASSERT_NE(ptr, nullptr); +// auto *new_ptr = umaPoolRealloc(pool.get(), ptr, allocSize * multiplier); +// ASSERT_NE(new_ptr, nullptr); +// std::memset(new_ptr, 0, allocSize * multiplier); +// umaPoolFree(pool.get(), new_ptr); +// } + +// TEST_P(umaPoolTest, callocFree) { +// static constexpr size_t num = 10; +// static constexpr size_t size = sizeof(int); +// auto *ptr = umaPoolCalloc(pool.get(), num, size); +// ASSERT_NE(ptr, nullptr); +// umaPoolFree(pool.get(), ptr); +// } + TEST_P(umaPoolTest, pow2AlignedAlloc) { #ifdef _WIN32 // TODO: implement support for windows @@ -84,6 +105,146 @@ TEST_P(umaPoolTest, pow2AlignedAlloc) { } } +// TEST_P(umaPoolTest, allocZeroSize) { +// static constexpr size_t allocSize = 0; +// auto *ptr = umaPoolMalloc(pool.get(), allocSize); +// ASSERT_NE(ptr, nullptr); +// umaPoolFree(pool.get(), ptr); +// } + +TEST_P(umaPoolTest, freeNullptr) { + void *ptr = nullptr; + umaPoolFree(pool.get(), ptr); +} + +TEST_P(umaPoolTest, allocOutOfMem) { + // test whether memory is kept in a pool accordingly to MaxSize + static constexpr size_t allocSize = 16; + // MaxSize equals 16 * 1024 * 1024; + static constexpr size_t maxAllocs = 1024 * 1024; + + // allocate until oom + void *ptr = nullptr; + std::vector allocations; + + for (size_t i = 0; i <= maxAllocs; ++i) { + allocations.emplace_back(umaPoolMalloc(pool.get(), allocSize)); + ASSERT_NE(allocations.back(), nullptr); + } + + // check if the last allocation belongs to the pool + // it returns different values each time + // ASSERT_EQ(umaPoolByPtr(allocations.back()), pool.get()); + + // free some memory + umaPoolFree(pool.get(), allocations.back()); + + allocations.pop_back(); + + ptr = umaPoolMalloc(pool.get(), allocSize); + ASSERT_NE(ptr, nullptr); + + umaPoolFree(pool.get(), ptr); + + for (auto allocation : allocations) { + umaPoolFree(pool.get(), allocation); + } +} + +TEST_P(umaPoolTest, multiThreadedMallocFree) { + auto poolMalloc = [](size_t allocSize, uma_memory_pool_handle_t pool) { + std::vector allocations; + for (size_t i = 0; i <= 10; ++i) { + allocations.emplace_back(umaPoolMalloc(pool, allocSize)); + ASSERT_NE(allocations.back(), nullptr); + } + + for (auto allocation : allocations) { + umaPoolFree(pool, allocation); + } + }; + + std::vector threads; + for (int i = 0; i < NTHREADS; i++) { + threads.push_back(std::thread(poolMalloc, 64, pool.get())); + } + + for (auto &thread : threads) { + thread.join(); + } +} + +// TEST_P(umaPoolTest, multiThreadedReallocFree) { +// auto poolRealloc = [](size_t allocSize, size_t multiplier, uma_memory_pool_handle_t pool) { +// std::vector allocations; +// for (size_t i = 0; i <= 10; ++i) { +// allocations.emplace_back(umaPoolMalloc(pool, allocSize)); +// ASSERT_NE(allocations.back(), nullptr); +// } + +// for (auto allocation : allocations) { +// auto *ptr = umaPoolRealloc(pool, allocation, allocSize * multiplier); +// umaPoolFree(pool, ptr); +// } +// }; + +// std::vector threads; +// for (int i = 0; i < NTHREADS; i++) { +// threads.push_back(std::thread(poolRealloc, 64, 3, pool.get())); +// } + +// for (auto &thread : threads) { +// thread.join(); +// } +// } + +// TEST_P(umaPoolTest, multiThreadedCallocFree) { +// auto poolCalloc = [](size_t num, size_t size, +// uma_memory_pool_handle_t pool) { +// std::vector allocations; +// for (size_t i = 0; i <= 10; ++i) { +// allocations.emplace_back(umaPoolCalloc(pool, num, size)); +// ASSERT_NE(allocations.back(), nullptr); +// } + +// for (auto allocation : allocations) { +// umaPoolFree(pool, allocation); +// } +// }; + +// std::vector threads; +// for (int i = 0; i < NTHREADS; i++) { +// threads.push_back(std::thread(poolCalloc, 10, sizeof(int), pool.get())); +// } + +// for (auto &thread : threads) { +// thread.join(); +// } +// } + +TEST_P(umaPoolTest, multiThreadedMallocFreeRandomSizes) { + auto poolMalloc = [](size_t allocSize, uma_memory_pool_handle_t pool) { + std::vector allocations; + for (size_t i = 0; i <= 10; ++i) { + allocations.emplace_back(umaPoolMalloc(pool, allocSize)); + ASSERT_NE(allocations.back(), nullptr); + } + + for (auto allocation : allocations) { + umaPoolFree(pool, allocation); + } + }; + + std::vector threads; + for (int i = 0; i < NTHREADS; i++) { + threads.push_back(std::thread(poolMalloc, rand() % 64 + 1, pool.get())); + } + + for (auto &thread : threads) { + thread.join(); + } +} + // TODO: add similar tests for realloc/aligned_alloc, etc. // TODO: add multithreaded tests TEST_P(umaMultiPoolTest, memoryTracking) {