diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79e825b..2324cc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -240,7 +240,7 @@ jobs: cxxstd: "14,latest" addrmd: 32,64 os: windows-2019 - supported: true + supported: false # requires _ENABLE_ATOMIC_ALIGNMENT_FIX - toolset: msvc-14.2 cxxstd: "14,17,20,latest" addrmd: 32,64 diff --git a/include/boost/lockfree/detail/freelist.hpp b/include/boost/lockfree/detail/freelist.hpp index 31c8c98..64af569 100644 --- a/include/boost/lockfree/detail/freelist.hpp +++ b/include/boost/lockfree/detail/freelist.hpp @@ -36,7 +36,7 @@ namespace boost { namespace lockfree { namespace detail { //---------------------------------------------------------------------------------------------------------------------- template < typename T, typename Alloc = std::allocator< T > > -class freelist_stack : Alloc +class alignas( cacheline_bytes ) freelist_stack : Alloc { struct freelist_node { @@ -267,8 +267,7 @@ class freelist_stack : Alloc atomic< tagged_node_ptr > pool_; }; -class BOOST_ALIGNMENT( 4 ) // workaround for bugs in MSVC - tagged_index +class tagged_index { public: typedef std::uint16_t tag_t; @@ -336,7 +335,7 @@ class BOOST_ALIGNMENT( 4 ) // workaround for bugs in MSVC //---------------------------------------------------------------------------------------------------------------------- template < typename T, std::size_t size > -struct BOOST_ALIGNMENT( BOOST_LOCKFREE_CACHELINE_BYTES ) compiletime_sized_freelist_storage +struct alignas( cacheline_bytes ) compiletime_sized_freelist_storage { // array-based freelists only support a 16bit address space. BOOST_STATIC_ASSERT( size < 65536 ); @@ -353,7 +352,7 @@ struct BOOST_ALIGNMENT( BOOST_LOCKFREE_CACHELINE_BYTES ) compiletime_sized_freel T* nodes( void ) const { char* data_pointer = const_cast< char* >( data.data() ); - return reinterpret_cast< T* >( boost::alignment::align_up( data_pointer, BOOST_LOCKFREE_CACHELINE_BYTES ) ); + return reinterpret_cast< T* >( boost::alignment::align_up( data_pointer, cacheline_bytes ) ); } std::size_t node_count( void ) const @@ -365,12 +364,11 @@ struct BOOST_ALIGNMENT( BOOST_LOCKFREE_CACHELINE_BYTES ) compiletime_sized_freel //---------------------------------------------------------------------------------------------------------------------- template < typename T, typename Alloc = std::allocator< T > > -struct runtime_sized_freelist_storage : - boost::alignment::aligned_allocator_adaptor< Alloc, BOOST_LOCKFREE_CACHELINE_BYTES > +struct runtime_sized_freelist_storage : boost::alignment::aligned_allocator_adaptor< Alloc, cacheline_bytes > { - typedef boost::alignment::aligned_allocator_adaptor< Alloc, BOOST_LOCKFREE_CACHELINE_BYTES > allocator_type; - T* nodes_; - std::size_t node_count_; + typedef boost::alignment::aligned_allocator_adaptor< Alloc, cacheline_bytes > allocator_type; + T* nodes_; + std::size_t node_count_; template < typename Allocator > runtime_sized_freelist_storage( Allocator const& alloc, std::size_t count ) : diff --git a/include/boost/lockfree/detail/parameter.hpp b/include/boost/lockfree/detail/parameter.hpp index 1617b55..e25539b 100644 --- a/include/boost/lockfree/detail/parameter.hpp +++ b/include/boost/lockfree/detail/parameter.hpp @@ -59,7 +59,7 @@ using extract_capacity_t = typename extract_capacity< bound_args >::type; template < typename bound_args, typename T > struct extract_allocator { - using default_allocator = boost::alignment::aligned_allocator< T, BOOST_LOCKFREE_CACHELINE_BYTES >; + using default_allocator = boost::alignment::aligned_allocator< T, cacheline_bytes >; using allocator_t = extract_arg_or_default_t< bound_args, tag::allocator, default_allocator >; using has_no_allocator_t = has_no_arg_t< bound_args, tag::allocator >; diff --git a/include/boost/lockfree/detail/prefix.hpp b/include/boost/lockfree/detail/prefix.hpp index 88bcbdf..456a8fe 100644 --- a/include/boost/lockfree/detail/prefix.hpp +++ b/include/boost/lockfree/detail/prefix.hpp @@ -7,24 +7,38 @@ #ifndef BOOST_LOCKFREE_PREFIX_HPP_INCLUDED #define BOOST_LOCKFREE_PREFIX_HPP_INCLUDED +#include + /* this file defines the following macros: - BOOST_LOCKFREE_CACHELINE_BYTES: size of a cache line BOOST_LOCKFREE_PTR_COMPRESSION: use tag/pointer compression to utilize parts of the virtual address space as tag (at least 16bit) */ -#if defined( __s390__ ) || defined( __s390x__ ) -# define BOOST_LOCKFREE_CACHELINE_BYTES 256 -#elif defined( powerpc ) || defined( __powerpc__ ) || defined( __ppc__ ) -# define BOOST_LOCKFREE_CACHELINE_BYTES 128 +namespace boost { namespace lockfree { namespace detail { + +#ifdef __cpp_inline_variables +# define inline_constexpr inline #else -# define BOOST_LOCKFREE_CACHELINE_BYTES 64 +# define inline_constexpr #endif -#include +#if BOOST_ARCH_SYS390 +inline_constexpr constexpr size_t cacheline_bytes = 256; +#elif BOOST_ARCH_PPC +inline_constexpr constexpr size_t cacheline_bytes = 128; +#elif BOOST_ARCH_ARM && ( BOOST_OS_MACOS || BOOST_OS_IOS ) +// technically this is for apple's the M chips, but the A chip are probably similar +inline_constexpr constexpr size_t cacheline_bytes = 128; +#else +inline_constexpr constexpr size_t cacheline_bytes = 64; +#endif + +}}} // namespace boost::lockfree::detail #if BOOST_ARCH_X86_64 || ( ( BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER( 8, 0, 0 ) ) && !BOOST_PLAT_ANDROID ) # define BOOST_LOCKFREE_PTR_COMPRESSION 1 #endif +#undef inline_constexpr + #endif /* BOOST_LOCKFREE_PREFIX_HPP_INCLUDED */ diff --git a/include/boost/lockfree/detail/tagged_ptr_dcas.hpp b/include/boost/lockfree/detail/tagged_ptr_dcas.hpp index 4a772e3..31d0777 100644 --- a/include/boost/lockfree/detail/tagged_ptr_dcas.hpp +++ b/include/boost/lockfree/detail/tagged_ptr_dcas.hpp @@ -19,15 +19,7 @@ namespace boost { namespace lockfree { namespace detail { template < class T > -class -#if BOOST_COMP_MSVC && BOOST_ARCH_X86_64 - BOOST_ALIGNMENT( 16 ) -#elif BOOST_COMP_MSVC && BOOST_ARCH_X86_32 - BOOST_ALIGNMENT( 8 ) -#else - BOOST_ALIGNMENT( 2 * sizeof( void* ) ) -#endif - tagged_ptr +class alignas( 2 * sizeof( void* ) ) tagged_ptr { public: typedef std::size_t tag_t; diff --git a/include/boost/lockfree/queue.hpp b/include/boost/lockfree/queue.hpp index 6e7bcf0..f7b2249 100644 --- a/include/boost/lockfree/queue.hpp +++ b/include/boost/lockfree/queue.hpp @@ -104,7 +104,7 @@ class queue static constexpr bool node_based = !( has_capacity || fixed_sized ); static constexpr bool compile_time_sized = has_capacity; - struct BOOST_ALIGNMENT( BOOST_LOCKFREE_CACHELINE_BYTES ) node + struct alignas( detail::cacheline_bytes ) node { typedef typename detail::select_tagged_handle< node, node_based >::tagged_handle_type tagged_node_handle; typedef typename detail::select_tagged_handle< node, node_based >::handle_type handle_type; @@ -606,7 +606,7 @@ class queue private: #ifndef BOOST_DOXYGEN_INVOKED atomic< tagged_node_handle > head_; - static constexpr int padding_size = BOOST_LOCKFREE_CACHELINE_BYTES - sizeof( tagged_node_handle ); + static constexpr int padding_size = detail::cacheline_bytes - sizeof( tagged_node_handle ); char padding1[ padding_size ]; atomic< tagged_node_handle > tail_; char padding2[ padding_size ]; diff --git a/include/boost/lockfree/spsc_queue.hpp b/include/boost/lockfree/spsc_queue.hpp index f2db625..5423294 100644 --- a/include/boost/lockfree/spsc_queue.hpp +++ b/include/boost/lockfree/spsc_queue.hpp @@ -43,7 +43,7 @@ class ringbuffer_base #ifndef BOOST_DOXYGEN_INVOKED protected: typedef std::size_t size_t; - static constexpr int padding_size = BOOST_LOCKFREE_CACHELINE_BYTES - sizeof( size_t ); + static constexpr int padding_size = cacheline_bytes - sizeof( size_t ); atomic< size_t > write_index_; char padding1[ padding_size ]; /* force read_index and write_index to different cache lines */ atomic< size_t > read_index_; diff --git a/include/boost/lockfree/spsc_value.hpp b/include/boost/lockfree/spsc_value.hpp index 80c737e..6abc97b 100644 --- a/include/boost/lockfree/spsc_value.hpp +++ b/include/boost/lockfree/spsc_value.hpp @@ -314,7 +314,7 @@ struct spsc_value uint8_t byte; }; - static constexpr size_t cacheline_bytes = BOOST_LOCKFREE_CACHELINE_BYTES; + static constexpr size_t cacheline_bytes = detail::cacheline_bytes; struct alignas( cacheline_bytes ) cache_aligned_value { diff --git a/include/boost/lockfree/stack.hpp b/include/boost/lockfree/stack.hpp index 19d5e7d..44b2087 100644 --- a/include/boost/lockfree/stack.hpp +++ b/include/boost/lockfree/stack.hpp @@ -802,7 +802,7 @@ class stack #ifndef BOOST_DOXYGEN_INVOKED detail::atomic< tagged_node_handle > tos; - static const int padding_size = BOOST_LOCKFREE_CACHELINE_BYTES - sizeof( tagged_node_handle ); + static const int padding_size = detail::cacheline_bytes - sizeof( tagged_node_handle ); char padding[ padding_size ]; pool_t pool; diff --git a/test/queue_interprocess_test.cpp b/test/queue_interprocess_test.cpp index 0cc2429..1f690a0 100644 --- a/test/queue_interprocess_test.cpp +++ b/test/queue_interprocess_test.cpp @@ -29,7 +29,7 @@ int main( int argc, char* argv[] ) } } remover; - managed_shared_memory segment( create_only, "boost_queue_interprocess_test_shm", 524288 ); + managed_shared_memory segment( create_only, "boost_queue_interprocess_test_shm", 1'048'576 ); ShmemAllocator alloc_inst( segment.get_segment_manager() ); queue* q = segment.construct< queue >( "queue" )( alloc_inst );