#include #include #include "pls/internal/base/system_details.h" #include "pls/internal/data_structures/aligned_stack.h" using namespace pls::internal::data_structures; using namespace pls::internal::base; using namespace std; // Forward Declaration void test_stack(aligned_stack &stack); TEST_CASE("aligned stack stores objects correctly", "[internal/data_structures/aligned_stack.h]") { constexpr long data_size = 1024; SECTION("plain aligned stack") { char data[data_size]; aligned_stack stack{data, data_size, data_size}; test_stack(stack); } SECTION("static aligned stack") { static_aligned_stack stack; test_stack(stack.get_stack()); } SECTION("heap aligned stack") { heap_aligned_stack stack{data_size}; test_stack(stack.get_stack()); } } void test_stack(aligned_stack &stack) { SECTION("stack correctly pushes sub linesize objects") { std::array small_data_one{'a', 'b', 'c', 'd', 'e'}; std::array small_data_two{}; std::array small_data_three{'A'}; auto pointer_one = stack.push(small_data_one); auto pointer_two = stack.push(small_data_two); auto pointer_three = stack.push(small_data_three); REQUIRE(reinterpret_cast(pointer_one) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(pointer_two) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(pointer_three) % system_details::CACHE_LINE_SIZE == 0); } SECTION("stack correctly pushes above linesize objects") { std::array small_data_one{'a', 'b', 'c', 'd', 'e'}; std::array big_data_one{}; auto big_pointer_one = stack.push(big_data_one); auto small_pointer_one = stack.push(small_data_one); REQUIRE(reinterpret_cast(big_pointer_one) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(small_pointer_one) % system_details::CACHE_LINE_SIZE == 0); } SECTION("stack correctly stores and retrieves objects") { std::array data_one{'a', 'b', 'c', 'd', 'e'}; auto *push_one = stack.push(data_one); stack.pop>(); auto *push_two = stack.push(data_one); REQUIRE(push_one == push_two); } SECTION("stack can push and pop multiple times with correct alignment") { std::array small_data_one{'a', 'b', 'c', 'd', 'e'}; std::array small_data_two{}; std::array small_data_three{'A'}; auto pointer_one = stack.push(small_data_one); auto pointer_two = stack.push(small_data_two); auto pointer_three = stack.push(small_data_three); stack.pop(); stack.pop(); auto pointer_four = stack.push(small_data_two); auto pointer_five = stack.push(small_data_three); REQUIRE(reinterpret_cast(pointer_one) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(pointer_two) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(pointer_three) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(pointer_four) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(reinterpret_cast(pointer_five) % system_details::CACHE_LINE_SIZE == 0); REQUIRE(pointer_four == pointer_two); REQUIRE(pointer_five == pointer_three); } }