update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -1,32 +0,0 @@
// boost lockfree: allocator rebind helper
//
// Copyright (C) 2017 Minmin Gong
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LOCKFREE_ALLOCATOR_REBIND_HELPER_HPP_INCLUDED
#define BOOST_LOCKFREE_ALLOCATOR_REBIND_HELPER_HPP_INCLUDED
#include <memory>
namespace boost {
namespace lockfree {
namespace detail {
template <class allocator_type, class value_type>
struct allocator_rebind_helper
{
#if !defined( BOOST_NO_CXX11_ALLOCATOR )
typedef typename std::allocator_traits<allocator_type>::template rebind_alloc<value_type> type;
#else
typedef typename allocator_type::template rebind<value_type>::other type;
#endif
};
} /* namespace detail */
} /* namespace lockfree */
} /* namespace boost */
#endif /* BOOST_LOCKFREE_ALLOCATOR_REBIND_HELPER_HPP_INCLUDED */

View File

@@ -9,6 +9,7 @@
#ifndef BOOST_LOCKFREE_FREELIST_HPP_INCLUDED
#define BOOST_LOCKFREE_FREELIST_HPP_INCLUDED
#include <cstring>
#include <limits>
#include <memory>
@@ -59,6 +60,7 @@ public:
{
for (std::size_t i = 0; i != n; ++i) {
T * node = Alloc::allocate(1);
std::memset((void*)node, 0, sizeof(T));
#ifdef BOOST_LOCKFREE_FREELIST_INIT_RUNS_DTOR
destruct<false>(node);
#else
@@ -72,6 +74,7 @@ public:
{
for (std::size_t i = 0; i != count; ++i) {
T * node = Alloc::allocate(1);
std::memset((void*)node, 0, sizeof(T));
deallocate<ThreadSafe>(node);
}
}
@@ -178,8 +181,11 @@ private:
for(;;) {
if (!old_pool.get_ptr()) {
if (!Bounded)
return Alloc::allocate(1);
if (!Bounded) {
T *ptr = Alloc::allocate(1);
std::memset((void*)ptr, 0, sizeof(T));
return ptr;
}
else
return 0;
}
@@ -200,8 +206,11 @@ private:
tagged_node_ptr old_pool = pool_.load(memory_order_relaxed);
if (!old_pool.get_ptr()) {
if (!Bounded)
return Alloc::allocate(1);
if (!Bounded) {
T *ptr = Alloc::allocate(1);
std::memset((void*)ptr, 0, sizeof(T));
return ptr;
}
else
return 0;
}
@@ -329,7 +338,7 @@ protected:
template <typename T,
std::size_t size>
struct compiletime_sized_freelist_storage
struct BOOST_ALIGNMENT(BOOST_LOCKFREE_CACHELINE_BYTES) compiletime_sized_freelist_storage
{
// array-based freelists only support a 16bit address space.
BOOST_STATIC_ASSERT(size < 65536);
@@ -339,7 +348,9 @@ struct compiletime_sized_freelist_storage
// unused ... only for API purposes
template <typename Allocator>
compiletime_sized_freelist_storage(Allocator const & /* alloc */, std::size_t /* count */)
{}
{
data.fill(0);
}
T * nodes(void) const
{
@@ -369,6 +380,7 @@ struct runtime_sized_freelist_storage:
if (count > 65535)
boost::throw_exception(std::runtime_error("boost.lockfree: freelist size is limited to a maximum of 65535 objects"));
nodes_ = allocator_type::allocate(count);
std::memset((void*)nodes_, 0, sizeof(T) * count);
}
~runtime_sized_freelist_storage(void)

View File

@@ -9,13 +9,15 @@
#ifndef BOOST_LOCKFREE_DETAIL_PARAMETER_HPP
#define BOOST_LOCKFREE_DETAIL_PARAMETER_HPP
#include <boost/align/aligned_allocator.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/lockfree/detail/prefix.hpp>
#include <boost/lockfree/policies.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/parameter/parameters.hpp>
#include <boost/mpl/void.hpp>
#include <boost/lockfree/detail/allocator_rebind_helper.hpp>
namespace boost {
@@ -53,10 +55,10 @@ struct extract_allocator
typedef typename mpl::if_c<has_allocator,
typename has_arg<bound_args, tag::allocator>::type,
std::allocator<T>
boost::alignment::aligned_allocator<T, BOOST_LOCKFREE_CACHELINE_BYTES>
>::type allocator_arg;
typedef typename detail::allocator_rebind_helper<allocator_arg, T>::type type;
typedef typename boost::allocator_rebind<allocator_arg, T>::type type;
};
template <typename bound_args, bool default_ = false>

View File

@@ -23,7 +23,7 @@
#include <boost/predef.h>
#if BOOST_ARCH_X86_64 || defined (__aarch64__)
#if BOOST_ARCH_X86_64 || ( (BOOST_ARCH_ARM >= BOOST_VERSION_NUMBER(8,0,0)) && !BOOST_PLAT_ANDROID )
#define BOOST_LOCKFREE_PTR_COMPRESSION 1
#endif

View File

@@ -19,7 +19,7 @@ namespace boost {
namespace lockfree {
namespace detail {
#if BOOST_ARCH_X86_64 || defined (__aarch64__)
#ifdef BOOST_LOCKFREE_PTR_COMPRESSION
template <class T>
class tagged_ptr

View File

@@ -9,7 +9,7 @@
#ifndef BOOST_LOCKFREE_POLICIES_HPP_INCLUDED
#define BOOST_LOCKFREE_POLICIES_HPP_INCLUDED
#include <boost/parameter/aux_/template_keyword.hpp>
#include <boost/parameter/template_keyword.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/size_t.hpp>

View File

@@ -13,11 +13,11 @@
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/config.hpp> // for BOOST_LIKELY & BOOST_ALIGNMENT
#include <boost/lockfree/detail/allocator_rebind_helper.hpp>
#include <boost/lockfree/detail/atomic.hpp>
#include <boost/lockfree/detail/copy_payload.hpp>
#include <boost/lockfree/detail/freelist.hpp>
@@ -117,7 +117,7 @@ private:
typedef typename detail::select_tagged_handle<node, node_based>::handle_type handle_type;
node(T const & v, handle_type null_handle):
data(v)//, next(tagged_node_handle(0, 0))
data(v)
{
/* increment tag to avoid ABA problem */
tagged_node_handle old_next = next.load(memory_order_relaxed);
@@ -178,19 +178,27 @@ public:
return head_.is_lock_free() && tail_.is_lock_free() && pool.is_lock_free();
}
//! Construct queue
// @{
/** Construct a fixed-sized queue
*
* \pre Must specify a capacity<> argument
* */
queue(void):
head_(tagged_node_handle(0, 0)),
tail_(tagged_node_handle(0, 0)),
pool(node_allocator(), capacity)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(has_capacity);
initialize();
}
/** Construct a fixed-sized queue with a custom allocator
*
* \pre Must specify a capacity<> argument
* */
template <typename U>
explicit queue(typename detail::allocator_rebind_helper<node_allocator, U>::type const & alloc):
explicit queue(typename boost::allocator_rebind<node_allocator, U>::type const & alloc):
head_(tagged_node_handle(0, 0)),
tail_(tagged_node_handle(0, 0)),
pool(alloc, capacity)
@@ -199,29 +207,46 @@ public:
initialize();
}
/** Construct a fixed-sized queue with a custom allocator
*
* \pre Must specify a capacity<> argument
* */
explicit queue(allocator const & alloc):
head_(tagged_node_handle(0, 0)),
tail_(tagged_node_handle(0, 0)),
pool(alloc, capacity)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(has_capacity);
initialize();
}
// @}
//! Construct queue, allocate n nodes for the freelist.
// @{
/** Construct a variable-sized queue
*
* Allocate n nodes initially for the freelist
*
* \pre Must \b not specify a capacity<> argument
* */
explicit queue(size_type n):
head_(tagged_node_handle(0, 0)),
tail_(tagged_node_handle(0, 0)),
pool(node_allocator(), n + 1)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(!has_capacity);
initialize();
}
/** Construct a variable-sized queue with a custom allocator
*
* Allocate n nodes initially for the freelist
*
* \pre Must \b not specify a capacity<> argument
* */
template <typename U>
queue(size_type n, typename detail::allocator_rebind_helper<node_allocator, U>::type const & alloc):
queue(size_type n, typename boost::allocator_rebind<node_allocator, U>::type const & alloc):
head_(tagged_node_handle(0, 0)),
tail_(tagged_node_handle(0, 0)),
pool(alloc, n + 1)
@@ -229,7 +254,6 @@ public:
BOOST_STATIC_ASSERT(!has_capacity);
initialize();
}
// @}
/** \copydoc boost::lockfree::stack::reserve
* */

View File

@@ -16,6 +16,7 @@
#include <boost/aligned_storage.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/utility.hpp>
#include <boost/next_prior.hpp>
#include <boost/utility/enable_if.hpp>
@@ -24,7 +25,6 @@
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/lockfree/detail/allocator_rebind_helper.hpp>
#include <boost/lockfree/detail/atomic.hpp>
#include <boost/lockfree/detail/copy_payload.hpp>
#include <boost/lockfree/detail/parameter.hpp>
@@ -352,9 +352,8 @@ public:
if ( !boost::has_trivial_destructor<T>::value ) {
// make sure to call all destructors!
T dummy_element;
while (pop(dummy_element))
{}
detail::consume_noop consume_functor;
(void)consume_all( consume_functor );
} else {
write_index_.store(0, memory_order_relaxed);
read_index_.store(0, memory_order_release);
@@ -448,6 +447,13 @@ protected:
return max_size;
}
~compile_time_sized_ringbuffer(void)
{
// destroy all remaining items
detail::consume_noop consume_functor;
(void)consume_all(consume_functor);
}
public:
bool push(T const & t)
{
@@ -551,7 +557,7 @@ public:
}
template <typename U>
runtime_sized_ringbuffer(typename detail::allocator_rebind_helper<Alloc, U>::type const & alloc, size_type max_elements):
runtime_sized_ringbuffer(typename boost::allocator_rebind<Alloc, U>::type const & alloc, size_type max_elements):
Alloc(alloc), max_elements_(max_elements + 1)
{
#ifdef BOOST_NO_CXX11_ALLOCATOR
@@ -576,8 +582,8 @@ public:
~runtime_sized_ringbuffer(void)
{
// destroy all remaining items
T out;
while (pop(&out, 1)) {}
detail::consume_noop consume_functor;
(void)consume_all(consume_functor);
#ifdef BOOST_NO_CXX11_ALLOCATOR
Alloc::deallocate(array_, max_elements_);
@@ -749,51 +755,72 @@ public:
*
* \pre spsc_queue must be configured to be sized at compile-time
*/
// @{
spsc_queue(void)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(!runtime_sized);
}
/** Constructs a spsc_queue with a custom allocator
*
* \pre spsc_queue must be configured to be sized at compile-time
*
* \note This is just for API compatibility: an allocator isn't actually needed
*/
template <typename U>
explicit spsc_queue(typename detail::allocator_rebind_helper<allocator, U>::type const &)
explicit spsc_queue(typename boost::allocator_rebind<allocator, U>::type const &)
{
// just for API compatibility: we don't actually need an allocator
BOOST_STATIC_ASSERT(!runtime_sized);
}
/** Constructs a spsc_queue with a custom allocator
*
* \pre spsc_queue must be configured to be sized at compile-time
*
* \note This is just for API compatibility: an allocator isn't actually needed
*/
explicit spsc_queue(allocator const &)
{
// just for API compatibility: we don't actually need an allocator
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(!runtime_sized);
}
// @}
/** Constructs a spsc_queue for element_count elements
*
* \pre spsc_queue must be configured to be sized at run-time
*/
// @{
explicit spsc_queue(size_type element_count):
base_type(element_count)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(runtime_sized);
}
/** Constructs a spsc_queue for element_count elements with a custom allocator
*
* \pre spsc_queue must be configured to be sized at run-time
*/
template <typename U>
spsc_queue(size_type element_count, typename detail::allocator_rebind_helper<allocator, U>::type const & alloc):
spsc_queue(size_type element_count, typename boost::allocator_rebind<allocator, U>::type const & alloc):
base_type(alloc, element_count)
{
BOOST_STATIC_ASSERT(runtime_sized);
}
/** Constructs a spsc_queue for element_count elements with a custom allocator
*
* \pre spsc_queue must be configured to be sized at run-time
*/
spsc_queue(size_type element_count, allocator_arg const & alloc):
base_type(alloc, element_count)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(runtime_sized);
}
// @}
/** Pushes object t to the ringbuffer.
*
@@ -1011,9 +1038,8 @@ public:
if ( !boost::has_trivial_destructor<T>::value ) {
// make sure to call all destructors!
T dummy_element;
while (pop(dummy_element))
{}
detail::consume_noop consume_functor;
(void)consume_all(consume_functor);
} else {
base_type::write_index_.store(0, memory_order_relaxed);
base_type::read_index_.store(0, memory_order_release);

View File

@@ -9,13 +9,13 @@
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/integer_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/lockfree/detail/allocator_rebind_helper.hpp>
#include <boost/lockfree/detail/atomic.hpp>
#include <boost/lockfree/detail/copy_payload.hpp>
#include <boost/lockfree/detail/freelist.hpp>
@@ -135,48 +135,72 @@ public:
return tos.is_lock_free() && pool.is_lock_free();
}
//! Construct stack
// @{
/** Construct a fixed-sized stack
*
* \pre Must specify a capacity<> argument
* */
stack(void):
pool(node_allocator(), capacity)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(has_capacity);
initialize();
}
/** Construct a fixed-sized stack with a custom allocator
*
* \pre Must specify a capacity<> argument
* */
template <typename U>
explicit stack(typename detail::allocator_rebind_helper<node_allocator, U>::type const & alloc):
explicit stack(typename boost::allocator_rebind<node_allocator, U>::type const & alloc):
pool(alloc, capacity)
{
BOOST_STATIC_ASSERT(has_capacity);
initialize();
}
/** Construct a fixed-sized stack with a custom allocator
*
* \pre Must specify a capacity<> argument
* */
explicit stack(allocator const & alloc):
pool(alloc, capacity)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(has_capacity);
initialize();
}
// @}
//! Construct stack, allocate n nodes for the freelist.
// @{
/** Construct a variable-sized stack
*
* Allocate n nodes initially for the freelist
*
* \pre Must \b not specify a capacity<> argument
* */
explicit stack(size_type n):
pool(node_allocator(), n)
{
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(!has_capacity);
initialize();
}
/** Construct a variable-sized stack with a custom allocator
*
* Allocate n nodes initially for the freelist
*
* \pre Must \b not specify a capacity<> argument
* */
template <typename U>
stack(size_type n, typename detail::allocator_rebind_helper<node_allocator, U>::type const & alloc):
stack(size_type n, typename boost::allocator_rebind<node_allocator, U>::type const & alloc):
pool(alloc, n)
{
BOOST_STATIC_ASSERT(!has_capacity);
initialize();
}
// @}
/** Allocate n nodes for freelist
*
@@ -186,7 +210,9 @@ public:
* */
void reserve(size_type n)
{
BOOST_STATIC_ASSERT(!has_capacity);
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(!has_capacity);
pool.template reserve<true>(n);
}
@@ -198,7 +224,9 @@ public:
* */
void reserve_unsafe(size_type n)
{
BOOST_STATIC_ASSERT(!has_capacity);
// Don't use BOOST_STATIC_ASSERT() here since it will be evaluated when compiling
// this function and this function may be compiled even when it isn't being used.
BOOST_ASSERT(!has_capacity);
pool.template reserve<false>(n);
}
@@ -209,9 +237,8 @@ public:
* */
~stack(void)
{
T dummy;
while(unsynchronized_pop(dummy))
{}
detail::consume_noop consume_functor;
(void)consume_all(consume_functor);
}
private:
@@ -238,7 +265,7 @@ private:
tagged_node_handle old_tos = tos.load(detail::memory_order_relaxed);
tagged_node_handle new_tos (pool.get_handle(new_top_node), old_tos.get_tag());
end_node->next = pool.get_pointer(old_tos);
end_node->next = pool.get_handle(old_tos);
tos.store(new_tos, memory_order_relaxed);
}