diff --git a/containers_cpp/test/blocking_map_test-inl.h b/containers_cpp/test/blocking_map_test-inl.h new file mode 100755 index 0000000..1dc8d94 --- /dev/null +++ b/containers_cpp/test/blocking_map_test-inl.h @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2014-2016, Siemens AG. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CONTAINERS_CPP_TEST_MAP_TEST_INL_H_ +#define CONTAINERS_CPP_TEST_MAP_TEST_INL_H_ + +namespace embb { + namespace containers { + namespace test { + +template +MapTest::MapTest() : + n_threads(static_cast + (partest::TestSuite::GetDefaultNumThreads())), + n_iterations(200), + n_operations_per_iteration(200), + n_map_elements_per_thread(100), + map(), + map_contain_vector(static_cast + (n_map_elements_per_thread*n_threads)) { + CreateUnit("MapTestThreadsInsertAndEraseToGlobalMap"). + Pre(&MapTest::MapTest1_Pre, this). + Add(&MapTest::MapTest1_ThreadMethod, this, + static_cast(n_threads), + static_cast(n_iterations)). + Post(&MapTest::MapTest1_Post, this); + +} + +template +void MapTest::MapTest1_Pre() { + embb_internal_thread_index_reset(); + thread_local_vectors_key = + new std::vector[static_cast(n_threads)]; + + thread_local_vectors_value = + new std::vector[static_cast(n_threads)]; + + for (int i = 0; i != n_threads; ++i) { + int offset = n_map_elements_per_thread; + + for (int i2 = 0; i2 != n_map_elements_per_thread; ++i2) { + int insert_element = i2 + (offset*i); + thread_local_vectors_key[i].push_back(insert_element); + thread_local_vectors_value[i].push_back(insert_element * 2); + map_contain_vector[static_cast(insert_element)] = false; + } + + } +} + +template +void MapTest::MapTest1_Post() { + unsigned int map_elements = map_contain_vector.size(); + for (unsigned int i = 0; i < map_elements; i++) { + PT_ASSERT(map_contain_vector[i] == map.Contains(static_cast(i))); + if (map_contain_vector[i]) + PT_ASSERT((map[i] == i * 2)); + } +} + +template +void MapTest::MapTest1_ThreadMethod() { + unsigned int thread_index; + int return_val = embb_internal_thread_index(&thread_index); + + PT_ASSERT((EMBB_SUCCESS == return_val)); + + srand(time(NULL)); + + std::vector& my_values = thread_local_vectors_value[thread_index]; + std::vector& my_keys = thread_local_vectors_key[thread_index]; + + + for (int i = 0; i < n_operations_per_iteration; i++) { + int random_number = rand() % 100; + int inserting = rand() % 2; + + int key = my_keys[static_cast(random_number)]; + int value = my_values[static_cast(random_number)]; + + if (inserting) { + PT_ASSERT(map.Insert(key, value) != map_contain_vector[static_cast(key)]); + map_contain_vector[static_cast(key)] = true; + + } + else { + PT_ASSERT(map.Erase(key) == map_contain_vector[static_cast(key)]); + map_contain_vector[static_cast(key)] = false; + } + } + +} + + + + +} // namespace test +} // namespace containers +} // namespace embb + + +#endif // CONTAINERS_CPP_TEST_MAP_TEST_INL_H_ \ No newline at end of file diff --git a/containers_cpp/test/blocking_map_test.h b/containers_cpp/test/blocking_map_test.h new file mode 100755 index 0000000..d43f3c2 --- /dev/null +++ b/containers_cpp/test/blocking_map_test.h @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2014-2016, Siemens AG. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CONTAINERS_CPP_TEST_MAP_TEST_H_ +#define CONTAINERS_CPP_TEST_MAP_TEST_H_ + +#include +#include +#include +#include + +namespace embb { +namespace containers { +namespace test { +template +class MapTest : public partest::TestCase { + private: + int n_threads; + int n_iterations; + int n_operations_per_iteration; + int n_map_elements_per_thread; + Map_t map; + std::vector* thread_local_vectors_key; + std::vector* thread_local_vectors_value; + std::vector map_contain_vector; + + public: + MapTest(); + + void MapTest1_Pre(); + + void MapTest1_Post(); + + void MapTest1_ThreadMethod(); + +}; +} // namespace test +} // namespace containers +} // namespace embb + +#include "./blocking_map_test-inl.h" + +#endif \ No newline at end of file diff --git a/containers_cpp/test/main.cc b/containers_cpp/test/main.cc index d21dede..7950ec6 100644 --- a/containers_cpp/test/main.cc +++ b/containers_cpp/test/main.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,7 @@ #include "./stack_test.h" #include "./hazard_pointer_test.h" #include "./object_pool_test.h" +#include "./blocking_map_test.h" #define COMMA , @@ -50,12 +52,14 @@ using embb::containers::LockFreeMPMCQueue; using embb::containers::LockFreeStack; using embb::containers::LockFreeTreeValuePool; using embb::containers::WaitFreeArrayValuePool; +using embb::containers::BlockingMap; using embb::containers::test::PoolTest; using embb::containers::test::HazardPointerTest; using embb::containers::test::QueueTest; using embb::containers::test::StackTest; using embb::containers::test::ObjectPoolTest; using embb::containers::test::HazardPointerTest2; +using embb::containers::test::MapTest; PT_MAIN("Data Structures C++") { unsigned int max_threads = static_cast( @@ -70,8 +74,8 @@ PT_MAIN("Data Structures C++") { PT_RUN(QueueTest< LockFreeMPMCQueue< ::std::pair > COMMA true COMMA true >); PT_RUN(StackTest< LockFreeStack >); + PT_RUN(MapTest >); PT_RUN(ObjectPoolTest< LockFreeTreeValuePool >); PT_RUN(ObjectPoolTest< WaitFreeArrayValuePool >); - PT_EXPECT(embb_get_bytes_allocated() == 0); }