Skip to content

Commit

Permalink
Add tests for scalable pool params
Browse files Browse the repository at this point in the history
  • Loading branch information
vinser52 committed Nov 11, 2024
1 parent 744e188 commit cb22292
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/cpp_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ template <typename T> umf_memory_pool_ops_t poolOpsBase() {
return ops;
}

template <typename T> umf_memory_provider_ops_t providerOpsBase() {
template <typename T> constexpr umf_memory_provider_ops_t providerOpsBase() {
umf_memory_provider_ops_t ops{};
ops.version = UMF_VERSION_CURRENT;
ops.finalize = [](void *obj) { delete reinterpret_cast<T *>(obj); };
Expand Down Expand Up @@ -134,7 +134,7 @@ template <typename T, typename ParamType> umf_memory_pool_ops_t poolMakeCOps() {
// C API. 'params' from ops.initialize will be casted to 'ParamType*'
// and passed to T::initialize() function.
template <typename T, typename ParamType>
umf_memory_provider_ops_t providerMakeCOps() {
constexpr umf_memory_provider_ops_t providerMakeCOps() {
umf_memory_provider_ops_t ops = detail::providerOpsBase<T>();

ops.initialize = []([[maybe_unused]] void *params, void **obj) {
Expand Down
138 changes: 138 additions & 0 deletions test/pools/scalable_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,148 @@

#include "pool.hpp"
#include "poolFixtures.hpp"
#include "provider.hpp"

auto defaultParams = umfOsMemoryProviderParamsDefault();
INSTANTIATE_TEST_SUITE_P(scalablePoolTest, umfPoolTest,
::testing::Values(poolCreateExtParams{
umfScalablePoolOps(), nullptr,
umfOsMemoryProviderOps(), &defaultParams,
nullptr}));

using scalablePoolParams = std::tuple<size_t, bool>;
struct umfScalablePoolParamsTest
: umf_test::test,
::testing::WithParamInterface<scalablePoolParams> {

struct validation_params_t {
size_t granularity;
bool keep_all_memory;
};

struct provider_validator : public umf_test::provider_ba_global {
using base_provider = umf_test::provider_ba_global;

umf_result_t initialize(validation_params_t *params) noexcept {
EXPECT_NE(params, nullptr);
expected_params = params;
return UMF_RESULT_SUCCESS;
}
umf_result_t alloc(size_t size, size_t align, void **ptr) noexcept {
EXPECT_EQ(size, expected_params->granularity);
return base_provider::alloc(size, align, ptr);
}
umf_result_t free(void *ptr, size_t size) noexcept {
EXPECT_EQ(expected_params->keep_all_memory, false);
return base_provider::free(ptr, size);
}

validation_params_t *expected_params;
};

static constexpr umf_memory_provider_ops_t VALIDATOR_PROVIDER_OPS =
umf::providerMakeCOps<provider_validator, validation_params_t>();

umfScalablePoolParamsTest() {}
void SetUp() override {
test::SetUp();
auto [granularity, keep_all_memory] = this->GetParam();
expected_params.granularity = granularity;
expected_params.keep_all_memory = keep_all_memory;
umf_result_t ret = umfScalablePoolParamsCreate(&params);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
ret = umfScalablePoolParamsSetGranularity(params, granularity);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
ret = umfScalablePoolParamsSetKeepAllMemory(params, keep_all_memory);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
}

void TearDown() override {
umfScalablePoolParamsDestroy(params);
test::TearDown();
}

umf::pool_unique_handle_t makePool() {
umf_memory_provider_handle_t hProvider = NULL;
umf_memory_pool_handle_t hPool = NULL;

auto ret = umfMemoryProviderCreate(&VALIDATOR_PROVIDER_OPS,
&expected_params, &hProvider);
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);

ret = umfPoolCreate(umfScalablePoolOps(), hProvider, params,
UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &hPool);
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);

return umf::pool_unique_handle_t(hPool, &umfPoolDestroy);
}

void allocFreeFlow() {
static const size_t ALLOC_SIZE = 128;
static const size_t NUM_ALLOCATIONS =
expected_params.granularity / ALLOC_SIZE * 20;
std::vector<void *> ptrs;

auto pool = makePool();
ASSERT_NE(pool, nullptr);

for (size_t i = 0; i < NUM_ALLOCATIONS; ++i) {
auto *ptr = umfPoolMalloc(pool.get(), ALLOC_SIZE);
ASSERT_NE(ptr, nullptr);
ptrs.push_back(ptr);
}

for (size_t i = 0; i < NUM_ALLOCATIONS; ++i) {
auto ret = umfPoolFree(pool.get(), ptrs[i]);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
}

// Now pool can call free during pool destruction
expected_params.keep_all_memory = false;
}

validation_params_t expected_params;
umf_scalable_pool_params_handle_t params;
};

TEST_P(umfScalablePoolParamsTest, allocFree) { allocFreeFlow(); }

TEST_P(umfScalablePoolParamsTest, updateParams) {
expected_params.granularity *= 2;
umf_result_t ret = umfScalablePoolParamsSetGranularity(
params, expected_params.granularity);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);

expected_params.keep_all_memory = !expected_params.keep_all_memory;
ret = umfScalablePoolParamsSetKeepAllMemory(
params, expected_params.keep_all_memory);
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);

allocFreeFlow();
}

TEST_P(umfScalablePoolParamsTest, invalidParams) {
umf_result_t ret = umfScalablePoolParamsCreate(nullptr);
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);

ret = umfScalablePoolParamsSetGranularity(nullptr, 2 * 1024 * 1024);
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);

ret = umfScalablePoolParamsSetGranularity(params, 0);
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);

ret = umfScalablePoolParamsSetKeepAllMemory(NULL, true);
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);

ret = umfScalablePoolParamsSetKeepAllMemory(NULL, false);
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);

ret = umfScalablePoolParamsDestroy(nullptr);
ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT);
}

INSTANTIATE_TEST_SUITE_P(
scalablePoolTest, umfScalablePoolParamsTest,
testing::Combine(testing::Values(2 * 1024 * 1024, 3 * 1024 * 1024,
4 * 1024 * 1024, 5 * 1024 * 1024),
testing::Values(false, true)));
18 changes: 18 additions & 0 deletions test/supp/memcheck-umf_test-scalable_pool.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
Conditional jump or move depends on uninitialised value(s) - internal issue of libtbbmalloc.so
Memcheck:Cond
fun:_ZN3rml9pool_freeEPNS_10MemoryPoolEPv
fun:tbb_free
fun:umfPoolFree
...
}

{
Conditional jump or move depends on uninitialised value(s) - internal issue of libtbbmalloc.so
Memcheck:Cond
obj:*libtbbmalloc.so*
fun:_ZN3rml9pool_freeEPNS_10MemoryPoolEPv
fun:tbb_free
fun:umfPoolFree
...
}

0 comments on commit cb22292

Please sign in to comment.