diff --git a/include/libimp/construct.h b/include/libimp/construct.h index 4b485b1..8d39dd7 100644 --- a/include/libimp/construct.h +++ b/include/libimp/construct.h @@ -45,6 +45,7 @@ auto construct(void *p, A &&... args) template void *destroy(T *p) noexcept { + if (p == nullptr) return nullptr; #if defined(LIBIMP_CPP_17) std::destroy_at(p); #else @@ -55,6 +56,7 @@ void *destroy(T *p) noexcept { template void *destroy(T (*p)[N]) noexcept { + if (p == nullptr) return nullptr; #if defined(LIBIMP_CPP_20) std::destroy_at(p); #elif defined(LIBIMP_CPP_17) diff --git a/include/libipc/def.h b/include/libipc/def.h index 0561ffe..6690155 100755 --- a/include/libipc/def.h +++ b/include/libipc/def.h @@ -6,8 +6,11 @@ */ #pragma once -#include +#include // std::max_align_t #include +#include // std::hardware_destructive_interference_size + +#include "libimp/detect_plat.h" #define LIBIPC_ ipc #define LIBIPC_NAMESPACE_BEG_ namespace LIBIPC_ { @@ -35,4 +38,16 @@ struct mode { }; }; +enum : std::size_t { + /// @brief Minimum offset between two objects to avoid false sharing. + /// @see https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size + cache_line_size = +#if defined(LIBIMP_CPP_17) && defined(__cpp_lib_hardware_interference_size) + ( std::hardware_destructive_interference_size < alignof(std::max_align_t) ) ? 64 + : std::hardware_destructive_interference_size, +#else + 64, +#endif +}; + LIBIPC_NAMESPACE_END_ diff --git a/src/libipc/concurrent.h b/src/libipc/concurrent.h new file mode 100644 index 0000000..b7371db --- /dev/null +++ b/src/libipc/concurrent.h @@ -0,0 +1,26 @@ + +#include +#include + +#include "libipc/def.h" + +LIBIPC_NAMESPACE_BEG_ +namespace concurrent { + +/// @brief The queue index type. +using index_t = std::uint32_t; + +namespace state { + +/// @brief The state flag type for the queue element. +using flag_t = std::uint64_t; + +enum : flag_t { + /// @brief The invalid state value. + invalid_value = (std::numeric_limits::max)(), +}; + +} // namespace state + +} // namespace concurrent +LIBIPC_NAMESPACE_END_ diff --git a/test/test_ipc_concurrent.cpp b/test/test_ipc_concurrent.cpp new file mode 100644 index 0000000..45cb1b6 --- /dev/null +++ b/test/test_ipc_concurrent.cpp @@ -0,0 +1,16 @@ + +#include +#include + +#include "gtest/gtest.h" + +#include "libipc/concurrent.h" + +TEST(concurrent, cache_line_size) { + std::cout << ipc::cache_line_size << "\n"; + EXPECT_TRUE(ipc::cache_line_size >= alignof(std::max_align_t)); +} + +TEST(concurrent, index_and_flag) { + EXPECT_TRUE(sizeof(ipc::concurrent::index_t) < sizeof(ipc::concurrent::state::flag_t)); +} \ No newline at end of file