|
Packit |
345191 |
/*
|
|
Packit |
345191 |
* Copyright (C) 2018 - 2019 Intel Corporation.
|
|
Packit |
345191 |
* All rights reserved.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
345191 |
* modification, are permitted provided that the following conditions are met:
|
|
Packit |
345191 |
* 1. Redistributions of source code must retain the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer.
|
|
Packit |
345191 |
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer in the documentation
|
|
Packit |
345191 |
* and/or other materials provided with the distribution.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
|
Packit |
345191 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
Packit |
345191 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
Packit |
345191 |
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit |
345191 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
345191 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
345191 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
345191 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
Packit |
345191 |
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
Packit |
345191 |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
345191 |
*/
|
|
Packit |
345191 |
#include "memkind.h"
|
|
Packit |
345191 |
#include "pmem_allocator.h"
|
|
Packit |
345191 |
#include "common.h"
|
|
Packit |
345191 |
#include <vector>
|
|
Packit |
345191 |
#include <memory>
|
|
Packit |
345191 |
#include <array>
|
|
Packit |
345191 |
#include <list>
|
|
Packit |
345191 |
#include <map>
|
|
Packit |
345191 |
#include <utility>
|
|
Packit |
345191 |
#include <string>
|
|
Packit |
345191 |
#include <algorithm>
|
|
Packit |
345191 |
#include <scoped_allocator>
|
|
Packit |
345191 |
#include <thread>
|
|
Packit |
345191 |
|
|
Packit |
345191 |
extern const char *PMEM_DIR;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
// Tests for pmem::allocator class.
|
|
Packit |
345191 |
class PmemAllocatorTests: public ::testing::Test
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
public:
|
|
Packit |
345191 |
const size_t pmem_max_size = 1024*1024*1024;
|
|
Packit |
345191 |
static_assert(MEMKIND_MEM_USAGE_POLICY_MAX_VALUE == static_cast<int>
|
|
Packit |
345191 |
(libmemkind::allocation_policy::MAX),
|
|
Packit |
345191 |
"Allocation policy is not inline with memory usage policy");
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alloc_source { std::string(PMEM_DIR), pmem_max_size };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alloc_conservative { std::string(PMEM_DIR), pmem_max_size, libmemkind::allocation_policy::CONSERVATIVE };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alloc_source_f1 { std::string(PMEM_DIR), pmem_max_size };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alloc_source_f2 { std::string(PMEM_DIR), pmem_max_size };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
protected:
|
|
Packit |
345191 |
void SetUp()
|
|
Packit |
345191 |
{}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
void TearDown()
|
|
Packit |
345191 |
{}
|
|
Packit |
345191 |
};
|
|
Packit |
345191 |
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Compare two same kind different type allocators
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_AllocatorCompare_SameKindDifferentType_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<char> alc2 { alloc_source_f1 };
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 == alc2);
|
|
Packit |
345191 |
ASSERT_FALSE(alc1 != alc2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Compare two same kind same type
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_AllocatorCompare_SameKindSameType_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc2 { alloc_source_f1 };
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 == alc2);
|
|
Packit |
345191 |
ASSERT_FALSE(alc1 != alc2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Compare two different kind different type
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_AllocatorCompare_DifferentKindDifferentType_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<char> alc2 { alloc_source_f2 };
|
|
Packit |
345191 |
ASSERT_FALSE(alc1 == alc2);
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 != alc2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Compare two different kind same type allocators
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_AllocatorCompare_DifferentKindSameType_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc2 { alloc_source_f2 };
|
|
Packit |
345191 |
ASSERT_FALSE(alc1 == alc2);
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 != alc2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Copy assignment test
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_Allocator_CopyAssignment_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc2 { alloc_source_f2 };
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 != alc2);
|
|
Packit |
345191 |
alc1 = alc2;
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 == alc2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Move constructor test
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_Allocator_MoveConstructor_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f2 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc2 { alloc_source_f2 };
|
|
Packit |
345191 |
ASSERT_TRUE(alc2 == alc1);
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc3 = std::move(alc1);
|
|
Packit |
345191 |
ASSERT_TRUE(alc2 == alc3);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Move assignment test
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_Allocator_MoveAssignment_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc2 { alloc_source_f2 };
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 != alc2);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc3 { alc2 };
|
|
Packit |
345191 |
alc1 = std::move(alc3);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 == alc2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Single allocation-deallocation test
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_Allocator_SingleAllocationDeallocation_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
int *created_object = alc1.allocate(1);
|
|
Packit |
345191 |
alc1.deallocate(created_object, 1);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Single allocation-deallocation test conservative policy
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_Allocator_SingleAllocationDeallocation_TestConservative)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_conservative };
|
|
Packit |
345191 |
int *created_object = alc1.allocate(1);
|
|
Packit |
345191 |
alc1.deallocate(created_object, 1);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Shared cross-allocation-deallocation test
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_Allocator_SharedAllocationDeallocation_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc2 { alloc_source_f1 };
|
|
Packit |
345191 |
int *created_object = nullptr;
|
|
Packit |
345191 |
int *created_object_2 = nullptr;
|
|
Packit |
345191 |
created_object = alc1.allocate(1);
|
|
Packit |
345191 |
ASSERT_TRUE(alc1 == alc2);
|
|
Packit |
345191 |
alc2.deallocate(created_object, 1);
|
|
Packit |
345191 |
created_object = alc2.allocate(1);
|
|
Packit |
345191 |
alc1.deallocate(created_object, 1);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
created_object = alc1.allocate(1);
|
|
Packit |
345191 |
created_object_2 = alc2.allocate(1);
|
|
Packit |
345191 |
alc2.deallocate(created_object, 1);
|
|
Packit |
345191 |
alc1.deallocate(created_object_2, 1);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Construct-destroy test
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_Allocator_ConstructDestroy_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc1 { alloc_source_f1 };
|
|
Packit |
345191 |
int *created_object = alc1.allocate(1);
|
|
Packit |
345191 |
alc1.construct(created_object);
|
|
Packit |
345191 |
alc1.destroy(created_object);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Testing thread-safety support
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_Allocator_MultithreadingSupport_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
const size_t num_threads = 1000;
|
|
Packit |
345191 |
const size_t iteration_count = 5000;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
std::vector<std::thread> thds;
|
|
Packit |
345191 |
for (size_t i = 0; i < num_threads; ++i) {
|
|
Packit |
345191 |
|
|
Packit |
345191 |
thds.push_back(std::thread( [&]() {
|
|
Packit |
345191 |
std::vector<libmemkind::pmem::allocator<int>> allocators_local;
|
|
Packit |
345191 |
for (size_t j = 0; j < iteration_count; j++) {
|
|
Packit |
345191 |
allocators_local.push_back(libmemkind::pmem::allocator<int> ( alloc_source ));
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
for (size_t j = 0; j < iteration_count; j++) {
|
|
Packit |
345191 |
allocators_local.pop_back();
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}));
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (size_t i = 0; i < num_threads; ++i) {
|
|
Packit |
345191 |
thds[i].join();
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Test multiple memkind allocator usage
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_MultipleAllocatorUsage_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alloc { PMEM_DIR, pmem_max_size } ;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alloc { PMEM_DIR, pmem_max_size } ;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Test vector
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_AllocatorUsage_Vector_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc{ alloc_source };
|
|
Packit |
345191 |
std::vector<int, libmemkind::pmem::allocator<int>> vector{ alc };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
const int num = 20;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (int i = 0; i < num; ++i) {
|
|
Packit |
345191 |
vector.push_back(0xDEAD + i);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (int i = 0; i < num; ++i) {
|
|
Packit |
345191 |
ASSERT_TRUE(vector[i] == 0xDEAD + i);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Test list
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_AllocatorUsage_List_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<int> alc{ alloc_source };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
std::list<int, libmemkind::pmem::allocator<int>> list{ alc };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
const int num = 4;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (int i = 0; i < num; ++i) {
|
|
Packit |
345191 |
list.emplace_back(0xBEAC011 + i);
|
|
Packit |
345191 |
ASSERT_TRUE(list.back() == 0xBEAC011 + i);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (int i = 0; i < num; ++i) {
|
|
Packit |
345191 |
list.pop_back();
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Test map
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_AllocatorUsage_Map_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
libmemkind::pmem::allocator<std::pair<const std::string, std::string>> alc{ alloc_source };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
std::map<std::string, std::string, std::less<std::string>, libmemkind::pmem::allocator<std::pair<const std::string, std::string>>>
|
|
Packit |
345191 |
map{ std::less<std::string>(), alc };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
const int num = 10;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
for (int i = 0; i < num; ++i) {
|
|
Packit |
345191 |
map[std::to_string(i)] = std::to_string(0x0CEA11 + i);
|
|
Packit |
345191 |
ASSERT_TRUE(map[std::to_string(i)] == std::to_string(0x0CEA11 + i));
|
|
Packit |
345191 |
map[std::to_string((i * 997 + 83) % 113)] = std::to_string(0x0CEA11 + i);
|
|
Packit |
345191 |
ASSERT_TRUE(map[std::to_string((i * 997 + 83) % 113)] == std::to_string(
|
|
Packit |
345191 |
0x0CEA11 + i));
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#if _GLIBCXX_USE_CXX11_ABI
|
|
Packit |
345191 |
//Test vector of strings
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests, test_TC_MEMKIND_AllocatorUsage_VectorOfString_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
typedef std::basic_string<char, std::char_traits<char>, libmemkind::pmem::allocator<char>>
|
|
Packit |
345191 |
pmem_string;
|
|
Packit |
345191 |
typedef libmemkind::pmem::allocator<pmem_string> pmem_alloc;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
pmem_alloc alc{ alloc_source };
|
|
Packit |
345191 |
libmemkind::pmem::allocator<char> st_alc{alc};
|
|
Packit |
345191 |
|
|
Packit |
345191 |
std::vector<pmem_string,std::scoped_allocator_adaptor<pmem_alloc>> vec{ alc };
|
|
Packit |
345191 |
pmem_string arg{ "Very very loooong striiiing", st_alc };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
vec.push_back(arg);
|
|
Packit |
345191 |
ASSERT_TRUE(vec.back() == arg);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
//Test map of int strings
|
|
Packit |
345191 |
TEST_F(PmemAllocatorTests,
|
|
Packit |
345191 |
test_TC_MEMKIND_AllocatorScopedUsage_MapOfIntString_Test)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
typedef std::basic_string<char, std::char_traits<char>, libmemkind::pmem::allocator<char>>
|
|
Packit |
345191 |
pmem_string;
|
|
Packit |
345191 |
typedef int key_t;
|
|
Packit |
345191 |
typedef pmem_string value_t;
|
|
Packit |
345191 |
typedef std::pair<const key_t, value_t> target_pair;
|
|
Packit |
345191 |
typedef libmemkind::pmem::allocator<target_pair> pmem_alloc;
|
|
Packit |
345191 |
typedef libmemkind::pmem::allocator<char> str_allocator_t;
|
|
Packit |
345191 |
typedef std::map<key_t, value_t, std::less<key_t>, std::scoped_allocator_adaptor<pmem_alloc>>
|
|
Packit |
345191 |
map_t;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
pmem_alloc map_allocator( alloc_source );
|
|
Packit |
345191 |
|
|
Packit |
345191 |
str_allocator_t str_allocator( map_allocator );
|
|
Packit |
345191 |
|
|
Packit |
345191 |
value_t source_str1("Lorem ipsum dolor ", str_allocator);
|
|
Packit |
345191 |
value_t source_str2("sit amet consectetuer adipiscing elit", str_allocator );
|
|
Packit |
345191 |
|
|
Packit |
345191 |
map_t target_map{ std::scoped_allocator_adaptor<pmem_alloc>(map_allocator) };
|
|
Packit |
345191 |
|
|
Packit |
345191 |
target_map[key_t(165)] = source_str1;
|
|
Packit |
345191 |
ASSERT_TRUE(target_map[key_t(165)] == source_str1);
|
|
Packit |
345191 |
target_map[key_t(165)] = source_str2;
|
|
Packit |
345191 |
ASSERT_TRUE(target_map[key_t(165)] == source_str2);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
#endif // _GLIBCXX_USE_CXX11_ABI
|