|
7 | 7 |
|
8 | 8 | #include "pool.hpp"
|
9 | 9 | #include "poolFixtures.hpp"
|
| 10 | +#include "provider.hpp" |
10 | 11 |
|
11 | 12 | auto defaultParams = umfOsMemoryProviderParamsDefault();
|
12 | 13 | INSTANTIATE_TEST_SUITE_P(scalablePoolTest, umfPoolTest,
|
13 | 14 | ::testing::Values(poolCreateExtParams{
|
14 | 15 | umfScalablePoolOps(), nullptr,
|
15 | 16 | umfOsMemoryProviderOps(), &defaultParams,
|
16 | 17 | nullptr}));
|
| 18 | + |
| 19 | +using scalablePoolParams = std::tuple<size_t, bool>; |
| 20 | +struct umfScalablePoolParamsTest |
| 21 | + : umf_test::test, |
| 22 | + ::testing::WithParamInterface<scalablePoolParams> { |
| 23 | + |
| 24 | + struct validation_params_t { |
| 25 | + size_t granularity; |
| 26 | + bool keep_all_memory; |
| 27 | + }; |
| 28 | + |
| 29 | + struct provider_validator : public umf_test::provider_ba_global { |
| 30 | + using base_provider = umf_test::provider_ba_global; |
| 31 | + |
| 32 | + umf_result_t initialize(validation_params_t *params) noexcept { |
| 33 | + EXPECT_NE(params, nullptr); |
| 34 | + expected_params = params; |
| 35 | + return UMF_RESULT_SUCCESS; |
| 36 | + } |
| 37 | + umf_result_t alloc(size_t size, size_t align, void **ptr) noexcept { |
| 38 | + EXPECT_EQ(size, expected_params->granularity); |
| 39 | + return base_provider::alloc(size, align, ptr); |
| 40 | + } |
| 41 | + umf_result_t free(void *ptr, size_t size) noexcept { |
| 42 | + EXPECT_EQ(expected_params->keep_all_memory, false); |
| 43 | + return base_provider::free(ptr, size); |
| 44 | + } |
| 45 | + |
| 46 | + validation_params_t *expected_params; |
| 47 | + }; |
| 48 | + |
| 49 | + static constexpr umf_memory_provider_ops_t VALIDATOR_PROVIDER_OPS = |
| 50 | + umf::providerMakeCOps<provider_validator, validation_params_t>(); |
| 51 | + |
| 52 | + umfScalablePoolParamsTest() {} |
| 53 | + void SetUp() override { |
| 54 | + test::SetUp(); |
| 55 | + auto [granularity, keep_all_memory] = this->GetParam(); |
| 56 | + expected_params.granularity = granularity; |
| 57 | + expected_params.keep_all_memory = keep_all_memory; |
| 58 | + umf_result_t ret = umfScalablePoolParamsCreate(¶ms); |
| 59 | + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); |
| 60 | + ret = umfScalablePoolParamsSetGranularity(params, granularity); |
| 61 | + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); |
| 62 | + ret = umfScalablePoolParamsSetKeepAllMemory(params, keep_all_memory); |
| 63 | + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); |
| 64 | + } |
| 65 | + |
| 66 | + void TearDown() override { |
| 67 | + umfScalablePoolParamsDestroy(params); |
| 68 | + test::TearDown(); |
| 69 | + } |
| 70 | + |
| 71 | + umf::pool_unique_handle_t makePool() { |
| 72 | + umf_memory_provider_handle_t hProvider = nullptr; |
| 73 | + umf_memory_pool_handle_t hPool = nullptr; |
| 74 | + |
| 75 | + auto ret = umfMemoryProviderCreate(&VALIDATOR_PROVIDER_OPS, |
| 76 | + &expected_params, &hProvider); |
| 77 | + EXPECT_EQ(ret, UMF_RESULT_SUCCESS); |
| 78 | + |
| 79 | + ret = umfPoolCreate(umfScalablePoolOps(), hProvider, params, |
| 80 | + UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &hPool); |
| 81 | + EXPECT_EQ(ret, UMF_RESULT_SUCCESS); |
| 82 | + |
| 83 | + return umf::pool_unique_handle_t(hPool, &umfPoolDestroy); |
| 84 | + } |
| 85 | + |
| 86 | + void allocFreeFlow() { |
| 87 | + static const size_t ALLOC_SIZE = 128; |
| 88 | + static const size_t NUM_ALLOCATIONS = |
| 89 | + expected_params.granularity / ALLOC_SIZE * 20; |
| 90 | + std::vector<void *> ptrs; |
| 91 | + |
| 92 | + auto pool = makePool(); |
| 93 | + ASSERT_NE(pool, nullptr); |
| 94 | + |
| 95 | + for (size_t i = 0; i < NUM_ALLOCATIONS; ++i) { |
| 96 | + auto *ptr = umfPoolMalloc(pool.get(), ALLOC_SIZE); |
| 97 | + ASSERT_NE(ptr, nullptr); |
| 98 | + ptrs.push_back(ptr); |
| 99 | + } |
| 100 | + |
| 101 | + for (size_t i = 0; i < NUM_ALLOCATIONS; ++i) { |
| 102 | + auto ret = umfPoolFree(pool.get(), ptrs[i]); |
| 103 | + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); |
| 104 | + } |
| 105 | + |
| 106 | + // Now pool can call free during pool destruction |
| 107 | + expected_params.keep_all_memory = false; |
| 108 | + } |
| 109 | + |
| 110 | + validation_params_t expected_params; |
| 111 | + umf_scalable_pool_params_handle_t params; |
| 112 | +}; |
| 113 | + |
| 114 | +TEST_P(umfScalablePoolParamsTest, allocFree) { allocFreeFlow(); } |
| 115 | + |
| 116 | +TEST_P(umfScalablePoolParamsTest, updateParams) { |
| 117 | + expected_params.granularity *= 2; |
| 118 | + umf_result_t ret = umfScalablePoolParamsSetGranularity( |
| 119 | + params, expected_params.granularity); |
| 120 | + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); |
| 121 | + |
| 122 | + expected_params.keep_all_memory = !expected_params.keep_all_memory; |
| 123 | + ret = umfScalablePoolParamsSetKeepAllMemory( |
| 124 | + params, expected_params.keep_all_memory); |
| 125 | + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); |
| 126 | + |
| 127 | + allocFreeFlow(); |
| 128 | +} |
| 129 | + |
| 130 | +TEST_P(umfScalablePoolParamsTest, invalidParams) { |
| 131 | + umf_result_t ret = umfScalablePoolParamsCreate(nullptr); |
| 132 | + ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); |
| 133 | + |
| 134 | + ret = umfScalablePoolParamsSetGranularity(nullptr, 2 * 1024 * 1024); |
| 135 | + ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); |
| 136 | + |
| 137 | + ret = umfScalablePoolParamsSetGranularity(params, 0); |
| 138 | + ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); |
| 139 | + |
| 140 | + ret = umfScalablePoolParamsSetKeepAllMemory(nullptr, true); |
| 141 | + ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); |
| 142 | + |
| 143 | + ret = umfScalablePoolParamsSetKeepAllMemory(nullptr, false); |
| 144 | + ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); |
| 145 | + |
| 146 | + ret = umfScalablePoolParamsDestroy(nullptr); |
| 147 | + ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); |
| 148 | +} |
| 149 | + |
| 150 | +INSTANTIATE_TEST_SUITE_P( |
| 151 | + scalablePoolTest, umfScalablePoolParamsTest, |
| 152 | + testing::Combine(testing::Values(2 * 1024 * 1024, 3 * 1024 * 1024, |
| 153 | + 4 * 1024 * 1024, 5 * 1024 * 1024), |
| 154 | + testing::Values(false, true))); |
0 commit comments