Compile-time dependency reduction. Update to Boost.Container changes.

This commit is contained in:
Ion Gaztañaga
2015-01-02 19:40:37 +01:00
parent 2706da2f3b
commit 37d00bc798
55 changed files with 1836 additions and 1904 deletions

View File

@@ -4012,9 +4012,8 @@ Here is the declaration of the function:
std::pair<T *, bool>
allocation_command( boost::interprocess::allocation_type command
, std::size_t limit_size
, std::size_t preferred_size
, std::size_t &received_size
, T *reuse_ptr = 0);
, size_type &prefer_in_recvd_out_size
, T *&reuse_ptr);
[*Preconditions for the function]:
@@ -6735,6 +6734,7 @@ thank them:
[section:release_notes Release Notes]
[section:release_notes_boost_1_58_00 Boost 1.58 Release]
* Reduced some compile-tim dependencies. Updated to Boost.Container changes.
* Fixed bugs:
* [@https://github.com/boostorg/interprocess/pull/13 GitHub Pull #13 (['"haiku: we don't have XSI shared memory, so don't try to use it"])].

View File

@@ -51,51 +51,53 @@ int main()
//->
//Allocate at least 100 bytes, 1000 bytes if possible
managed_shared_memory::size_type min_size = 100, preferred_size = 1000;
managed_shared_memory::size_type received_size;
managed_shared_memory::size_type min_size = 100;
managed_shared_memory::size_type first_received_size = 1000;
std::size_t *hint = 0;
std::size_t *ptr = managed_shm.allocation_command<std::size_t>
(boost::interprocess::allocate_new, min_size, preferred_size, received_size).first;
(boost::interprocess::allocate_new, min_size, first_received_size, hint);
//Received size must be bigger than min_size
assert(received_size >= min_size);
assert(first_received_size >= min_size);
//Get free memory
managed_shared_memory::size_type free_memory_after_allocation = managed_shm.get_free_memory();
//Now write the data
for(std::size_t i = 0; i < received_size; ++i) ptr[i] = i;
for(std::size_t i = 0; i < first_received_size; ++i) ptr[i] = i;
//Now try to triplicate the buffer. We won't admit an expansion
//lower to the double of the original buffer.
//This "should" be successful since no other class is allocating
//memory from the segment
managed_shared_memory::size_type expanded_size;
std::pair<std::size_t *, bool> ret = managed_shm.allocation_command
(boost::interprocess::expand_fwd, received_size*2, received_size*3, expanded_size, ptr);
min_size = first_received_size*2;
managed_shared_memory::size_type expanded_size = first_received_size*3;
std::size_t * ret = managed_shm.allocation_command
(boost::interprocess::expand_fwd, min_size, expanded_size, ptr);
//Check invariants
assert(ret.second == true);
assert(ret.first == ptr);
assert(expanded_size >= received_size*2);
assert(ptr != 0);
assert(ret == ptr);
assert(expanded_size >= first_received_size*2);
//Get free memory and compare
managed_shared_memory::size_type free_memory_after_expansion = managed_shm.get_free_memory();
assert(free_memory_after_expansion < free_memory_after_allocation);
//Write new values
for(std::size_t i = received_size; i < expanded_size; ++i) ptr[i] = i;
for(std::size_t i = first_received_size; i < expanded_size; ++i) ptr[i] = i;
//Try to shrink approximately to min_size, but the new size
//should be smaller than min_size*2.
//This "should" be successful since no other class is allocating
//memory from the segment
managed_shared_memory::size_type shrunk_size;
managed_shared_memory::size_type shrunk_size = min_size;
ret = managed_shm.allocation_command
(boost::interprocess::shrink_in_place, min_size*2, min_size, shrunk_size, ptr);
(boost::interprocess::shrink_in_place, min_size*2, shrunk_size, ptr);
//Check invariants
assert(ret.second == true);
assert(ret.first == ptr);
assert(ptr != 0);
assert(ret == ptr);
assert(shrunk_size <= min_size*2);
assert(shrunk_size >= min_size);

View File

@@ -30,8 +30,7 @@
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <memory>
#include <algorithm>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
//!\file
@@ -137,7 +136,7 @@ class adaptive_pool_base
adaptive_pool_base& operator=(const adaptive_pool_base &other)
{
adaptive_pool_base c(other);
swap(*this, c);
boost::adl_move_swap(*this, c);
return *this;
}
@@ -167,7 +166,7 @@ class adaptive_pool_base
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ ipcdetail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
{ boost::adl_move_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -388,11 +387,8 @@ class adaptive_pool
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const;
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,

View File

@@ -31,9 +31,7 @@
#include <boost/utility/addressof.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <memory>
#include <new>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
@@ -164,7 +162,7 @@ class allocator
//!Swap segment manager. Does not throw. If each allocator is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ ipcdetail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
{ boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold. This size only works for memory allocated with
@@ -174,14 +172,13 @@ class allocator
return (size_type)mp_mngr->size(ipcdetail::to_raw_pointer(p))/sizeof(T);
}
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
return mp_mngr->allocation_command
(command, limit_size, preferred_size, received_size, ipcdetail::to_raw_pointer(reuse));
value_type *reuse_raw = ipcdetail::to_raw_pointer(reuse);
pointer const p = mp_mngr->allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse_raw);
reuse = reuse_raw;
return p;
}
//!Allocates many elements of size elem_size in a contiguous block

View File

@@ -268,11 +268,8 @@ class cached_adaptive_pool
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const;
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,

View File

@@ -240,11 +240,8 @@ class cached_node_allocator
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const;
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,

View File

@@ -33,8 +33,7 @@
#include <boost/move/utility_core.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <algorithm> //std::swap
#include <utility> //std::pair
#include <boost/move/adl_move_swap.hpp>
#include <new>
namespace boost {
@@ -295,9 +294,9 @@ class cache_impl
public:
void swap(cache_impl &other)
{
ipcdetail::do_swap(mp_node_pool, other.mp_node_pool);
m_cached_nodes.swap(other.m_cached_nodes);
ipcdetail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
::boost::adl_move_swap(mp_node_pool, other.mp_node_pool);
::boost::adl_move_swap(m_cached_nodes, other.m_cached_nodes);
::boost::adl_move_swap(m_max_cached_nodes, other.m_max_cached_nodes);
}
};
@@ -338,14 +337,14 @@ class array_allocation_impl
return (size_type)this->derived()->get_segment_manager()->size(ipcdetail::to_raw_pointer(p))/sizeof(T);
}
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
return this->derived()->get_segment_manager()->allocation_command
(command, limit_size, preferred_size, received_size, ipcdetail::to_raw_pointer(reuse));
value_type *reuse_raw = ipcdetail::to_raw_pointer(reuse);
pointer const p = this->derived()->get_segment_manager()->allocation_command
(command, limit_size, prefer_in_recvd_out_size, reuse_raw);
reuse = reuse_raw;
return p;
}
//!Allocates many elements of size elem_size in a contiguous block
@@ -671,7 +670,7 @@ class cached_allocator_impl
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different shared memory segments, the result is undefined.
friend void swap(cached_allocator_impl &alloc1, cached_allocator_impl &alloc2)
{ alloc1.m_cache.swap(alloc2.m_cache); }
{ ::boost::adl_move_swap(alloc1.m_cache, alloc2.m_cache); }
void deallocate_cache()
{ m_cache.deallocate_all_cached_nodes(); }

View File

@@ -29,8 +29,7 @@
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
#include <memory>
#include <algorithm>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
//!\file
@@ -144,7 +143,7 @@ class node_allocator_base
node_allocator_base& operator=(const node_allocator_base &other)
{
node_allocator_base c(other);
swap(*this, c);
boost::adl_move_swap(*this, c);
return *this;
}
@@ -166,7 +165,7 @@ class node_allocator_base
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ ipcdetail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
{ boost::adl_move_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -373,11 +372,8 @@ class node_allocator
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const;
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,

View File

@@ -28,8 +28,7 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <memory>
#include <algorithm>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
//!\file
@@ -168,7 +167,7 @@ class private_adaptive_pool_base
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different shared memory segments, the result is undefined.
friend void swap(self_t &alloc1,self_t &alloc2)
{ alloc1.m_node_pool.swap(alloc2.m_node_pool); }
{ boost::adl_move_swap(alloc1.m_node_pool, alloc2.m_node_pool); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -388,11 +387,8 @@ class private_adaptive_pool
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const;
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,

View File

@@ -28,8 +28,7 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <memory>
#include <algorithm>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
//!\file
@@ -160,7 +159,7 @@ class private_node_allocator_base
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different shared memory segments, the result is undefined.
friend void swap(self_t &alloc1,self_t &alloc2)
{ alloc1.m_node_pool.swap(alloc2.m_node_pool); }
{ boost::adl_move_swap(alloc1.m_node_pool, alloc2.m_node_pool); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:
@@ -365,11 +364,8 @@ class private_node_allocator
//!allocate, allocation_command and allocate_many.
size_type size(const pointer &p) const;
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0);
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,

View File

@@ -28,7 +28,7 @@
//
#include <boost/detail/no_exceptions_support.hpp>
//
#include <utility>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <fstream>
#include <new>
#include <boost/assert.hpp>
@@ -288,14 +288,9 @@ class basic_managed_memory_impl
{ return mp_header->allocate_aligned(nbytes, alignment, nothrow); }
template<class T>
std::pair<T *, bool>
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0)
{
return mp_header->allocation_command
(command, limit_size, preferred_size, received_size, reuse_ptr);
}
T * allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type &prefer_in_recvd_out_size, T *&reuse)
{ return mp_header->allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
//!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
//!must be power of two. If no

View File

@@ -29,10 +29,13 @@
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/permissions.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp> //managed_open_or_create_impl
#include <new>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/streams/vectorstream.hpp>
#include <memory>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <string> //string
#include <new> //bad_alloc
#include <ostream>//std::ends
#include <boost/assert.hpp>
//These includes needed to fulfill default template parameters of
//predeclarations in interprocess_fwd.hpp

View File

@@ -31,7 +31,7 @@
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <cstddef>
#include <memory>
#include <ostream>
#if defined(BOOST_INTERPROCESS_WINDOWS)
# include <boost/interprocess/detail/win32_api.hpp>

View File

@@ -31,10 +31,8 @@
#include <cstddef> //std::size_t
#include <string> //char_traits
#include <new> //std::nothrow
#include <utility> //std::pair
#include <iterator> //std::iterator_traits
#include <boost/assert.hpp> //BOOST_ASSERT
#include <functional> //unary_function
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
#endif
@@ -399,7 +397,7 @@ struct index_data
{
typedef VoidPointer void_pointer;
void_pointer m_ptr;
index_data(void *ptr) : m_ptr(ptr){}
explicit index_data(void *ptr) : m_ptr(ptr){}
void *value() const
{ return static_cast<void*>(to_raw_pointer(m_ptr)); }
@@ -481,8 +479,6 @@ class segment_manager_iterator_value_adaptor<Iterator, false>
template<class Iterator, bool intrusive>
struct segment_manager_iterator_transform
: std::unary_function< typename std::iterator_traits<Iterator>::value_type
, segment_manager_iterator_value_adaptor<Iterator, intrusive> >
{
typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;

View File

@@ -0,0 +1,46 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2015. 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)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTERPROCESS_DETAIL_STD_FWD_HPP
#define BOOST_INTERPROCESS_DETAIL_STD_FWD_HPP
#if defined(_MSC_VER)
# pragma once
#endif
//////////////////////////////////////////////////////////////////////////////
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
#if defined(__clang__) && defined(_LIBCPP_VERSION)
#define BOOST_INTERPROCESS_CLANG_INLINE_STD_NS
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wc++11-extensions"
#define BOOST_INTERPROCESS_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_INTERPROCESS_STD_NS_END _LIBCPP_END_NAMESPACE_STD
#else
#define BOOST_INTERPROCESS_STD_NS_BEG namespace std{
#define BOOST_INTERPROCESS_STD_NS_END }
#endif
BOOST_INTERPROCESS_STD_NS_BEG
template<class T>
struct char_traits;
struct nothrow_t;
BOOST_INTERPROCESS_STD_NS_END
#ifdef BOOST_INTERPROCESS_CLANG_INLINE_STD_NS
#pragma GCC diagnostic pop
#undef BOOST_INTERPROCESS_CLANG_INLINE_STD_NS
#endif //BOOST_INTERPROCESS_CLANG_INLINE_STD_NS
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_STD_FWD_HPP

View File

@@ -32,8 +32,6 @@
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/static_assert.hpp>
#include <utility>
#include <algorithm>
#include <climits>
namespace boost {
@@ -49,14 +47,6 @@ inline typename boost::intrusive::pointer_traits<Pointer>::element_type*
to_raw_pointer(const Pointer &p)
{ return boost::interprocess::ipcdetail::to_raw_pointer(p.operator->()); }
//!To avoid ADL problems with swap
template <class T>
inline void do_swap(T& x, T& y)
{
using std::swap;
swap(x, y);
}
//Rounds "orig_size" by excess to round_to bytes
template<class SizeType>
inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)

View File

@@ -26,7 +26,6 @@
#include <boost/assert.hpp>
#include <string>
#include <vector>
#include <memory>
#ifdef BOOST_USE_WINDOWS_H
#include <windows.h>

View File

@@ -17,11 +17,13 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <functional>
#include <utility>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/interprocess/containers/flat_map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <functional> //std::less
#include <utility> //std::pair
//!\file
//!Describes index adaptor of boost::map container, to use it
//!as name/shared memory index

View File

@@ -18,13 +18,12 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <string>
#include <functional>
#include <utility>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
#include <boost/intrusive/set.hpp>
//!\file
//!Describes index adaptor of boost::intrusive::set container, to use it
//!as name/shared memory index

View File

@@ -18,13 +18,12 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <functional>
#include <utility>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
//!\file
//!Describes index adaptor of boost::intrusive::unordered_set container, to use it
@@ -179,9 +178,9 @@ class iunordered_set_index
{
if(old_size <= new_size )
return old_size;
size_type received_size;
size_type received_size = new_size;
if(!alloc.allocation_command
(boost::interprocess::try_shrink_in_place | boost::interprocess::nothrow_allocation, old_size, new_size, received_size, buckets).first){
(boost::interprocess::try_shrink_in_place | boost::interprocess::nothrow_allocation, old_size, received_size, buckets)){
return old_size;
}
@@ -193,7 +192,7 @@ class iunordered_set_index
}
bucket_ptr shunk_p = alloc.allocation_command
(boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_size, received_size, received_size, buckets).first;
(boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_size, received_size, buckets);
BOOST_ASSERT(buckets == shunk_p); (void)shunk_p;
bucket_ptr buckets_init = buckets + received_size;
@@ -207,24 +206,23 @@ class iunordered_set_index
( bucket_ptr old_buckets, const size_type old_num
, allocator_type &alloc, const size_type new_num)
{
size_type received_size;
std::pair<bucket_ptr, bool> ret =
alloc.allocation_command
(boost::interprocess::expand_fwd | boost::interprocess::allocate_new, new_num, new_num, received_size, old_buckets);
if(ret.first == old_buckets){
size_type received_size = new_num;
bucket_ptr reuse(old_buckets);
bucket_ptr ret = alloc.allocation_command
(boost::interprocess::expand_fwd | boost::interprocess::allocate_new, new_num, received_size, reuse);
if(ret == old_buckets){
bucket_ptr buckets_init = old_buckets + old_num;
for(size_type i = 0; i < (new_num - old_num); ++i){
new(to_raw_pointer(buckets_init++))bucket_type();
}
}
else{
bucket_ptr buckets_init = ret.first;
bucket_ptr buckets_init = ret;
for(size_type i = 0; i < new_num; ++i){
new(to_raw_pointer(buckets_init++))bucket_type();
}
}
return ret.first;
return ret;
}
static void destroy_buckets

View File

@@ -18,10 +18,11 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <functional>
#include <utility>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/private_adaptive_pool.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
//!\file
//!Describes index adaptor of boost::map container, to use it

View File

@@ -19,11 +19,14 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <functional>
#include <utility>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/unordered_map.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/allocators/private_adaptive_pool.hpp>
#include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
//!\file
//!Describes index adaptor of boost::unordered_map container, to use it
//!as name/shared memory index

View File

@@ -15,6 +15,8 @@
# pragma once
#endif
#include <boost/interprocess/detail/std_fwd.hpp>
//! \file
//! This header file forward declares the basic interprocess types:
//! - boost::interprocess::offset_ptr;
@@ -123,20 +125,8 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
namespace boost{
namespace intrusive{
}}
namespace boost{
namespace interprocess{
namespace bi = boost::intrusive;
}}
#include <utility>
#include <memory>
#include <functional>
#include <iosfwd>
#include <string>
namespace boost{ namespace intrusive{ } }
namespace boost{ namespace interprocess{ namespace bi = boost::intrusive; } }
namespace boost { namespace interprocess {
@@ -225,19 +215,16 @@ class private_node_allocator;
template<class T, class SegmentManager, std::size_t NodesPerBlock = 64>
class cached_node_allocator;
template<class T, class SegmentManager, std::size_t NodesPerBlock = 64, std::size_t MaxFreeBlocks = 2
, unsigned char OverheadPercent = 5
>
template< class T, class SegmentManager, std::size_t NodesPerBlock = 64
, std::size_t MaxFreeBlocks = 2, unsigned char OverheadPercent = 5 >
class adaptive_pool;
template<class T, class SegmentManager, std::size_t NodesPerBlock = 64, std::size_t MaxFreeBlocks = 2
, unsigned char OverheadPercent = 5
>
template< class T, class SegmentManager, std::size_t NodesPerBlock = 64
, std::size_t MaxFreeBlocks = 2, unsigned char OverheadPercent = 5 >
class private_adaptive_pool;
template<class T, class SegmentManager, std::size_t NodesPerBlock = 64, std::size_t MaxFreeBlocks = 2
, unsigned char OverheadPercent = 5
>
template< class T, class SegmentManager, std::size_t NodesPerBlock = 64
, std::size_t MaxFreeBlocks = 2, unsigned char OverheadPercent = 5 >
class cached_adaptive_pool;
@@ -247,7 +234,8 @@ class cached_adaptive_pool;
static const std::size_t offset_type_alignment = 0;
template <class T, class DifferenceType = std::ptrdiff_t, class OffsetType = std::size_t, std::size_t Alignment = offset_type_alignment>
template < class T, class DifferenceType = std::ptrdiff_t
, class OffsetType = std::size_t, std::size_t Alignment = offset_type_alignment>
class offset_ptr;
//////////////////////////////////////////////////////////////////////////////

View File

@@ -26,6 +26,8 @@
#include <string>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
#include <boost/move/adl_move_swap.hpp>
//Some Unixes use caddr_t instead of void * in madvise
// SunOS Tru64 HP-UX AIX
#if defined(sun) || defined(__sun) || defined(__osf__) || defined(__osf) || defined(_hpux) || defined(hpux) || defined(_AIX)
@@ -853,14 +855,14 @@ inline std::size_t mapped_region::get_page_size()
inline void mapped_region::swap(mapped_region &other)
{
ipcdetail::do_swap(this->m_base, other.m_base);
ipcdetail::do_swap(this->m_size, other.m_size);
ipcdetail::do_swap(this->m_page_offset, other.m_page_offset);
ipcdetail::do_swap(this->m_mode, other.m_mode);
::boost::adl_move_swap(this->m_base, other.m_base);
::boost::adl_move_swap(this->m_size, other.m_size);
::boost::adl_move_swap(this->m_page_offset, other.m_page_offset);
::boost::adl_move_swap(this->m_mode, other.m_mode);
#if defined (BOOST_INTERPROCESS_WINDOWS)
ipcdetail::do_swap(this->m_file_or_mapping_hnd, other.m_file_or_mapping_hnd);
::boost::adl_move_swap(this->m_file_or_mapping_hnd, other.m_file_or_mapping_hnd);
#else
ipcdetail::do_swap(this->m_is_xsi, other.m_is_xsi);
::boost::adl_move_swap(this->m_is_xsi, other.m_is_xsi);
#endif
}

View File

@@ -29,8 +29,6 @@
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <algorithm>
#include <utility>
#include <iterator>
#include <boost/assert.hpp>
@@ -240,10 +238,11 @@ class memory_algorithm_common
return 0;
}
size_type real_size;
size_type real_size = nbytes;
if(alignment <= Alignment){
void *ignore_reuse = 0;
return memory_algo->priv_allocate
(boost::interprocess::allocate_new, nbytes, nbytes, real_size).first;
(boost::interprocess::allocate_new, nbytes, real_size, ignore_reuse);
}
if(nbytes > UsableByPreviousChunk)
@@ -268,8 +267,9 @@ class memory_algorithm_common
);
//Now allocate the buffer
void *buffer = memory_algo->priv_allocate
(boost::interprocess::allocate_new, request, request, real_size).first;
real_size = request;
void *ignore_reuse = 0;
void *buffer = memory_algo->priv_allocate(boost::interprocess::allocate_new, request, real_size, ignore_reuse);
if(!buffer){
return 0;
}
@@ -358,9 +358,9 @@ class memory_algorithm_common
static bool try_shrink
(MemoryAlgorithm *memory_algo, void *ptr
,const size_type max_size, const size_type preferred_size
,size_type &received_size)
,const size_type max_size, size_type &received_size)
{
size_type const preferred_size = received_size;
(void)memory_algo;
//Obtain the real block
block_ctrl *block = memory_algo->priv_get_block(ptr);
@@ -414,15 +414,14 @@ class memory_algorithm_common
static bool shrink
(MemoryAlgorithm *memory_algo, void *ptr
,const size_type max_size, const size_type preferred_size
,size_type &received_size)
,const size_type max_size, size_type &received_size)
{
size_type const preferred_size = received_size;
//Obtain the real block
block_ctrl *block = memory_algo->priv_get_block(ptr);
size_type old_block_units = (size_type)block->m_size;
if(!try_shrink
(memory_algo, ptr, max_size, preferred_size, received_size)){
if(!try_shrink(memory_algo, ptr, max_size, received_size)){
return false;
}
@@ -492,14 +491,15 @@ class memory_algorithm_common
: memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element);
min_allocation = min_allocation*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk;
size_type received_size;
std::pair<void *, bool> ret = memory_algo->priv_allocate
(boost::interprocess::allocate_new, min_allocation, total_bytes, received_size, 0);
if(!ret.first){
size_type received_size = total_bytes;
void *ignore_reuse = 0;
void *ret = memory_algo->priv_allocate
(boost::interprocess::allocate_new, min_allocation, received_size, ignore_reuse);
if(!ret){
break;
}
block_ctrl *block = memory_algo->priv_get_block(ret.first);
block_ctrl *block = memory_algo->priv_get_block(ret);
size_type received_units = (size_type)block->m_size;
char *block_address = reinterpret_cast<char*>(block);
@@ -521,8 +521,8 @@ class memory_algorithm_common
(total_used_units + elem_units +
((!sizeof_element)
? elem_units
: std::max(memory_algo->priv_get_total_units(elem_sizes[low_idx+1]*sizeof_element), ptr_size_units))
) > received_units){
: max_value(memory_algo->priv_get_total_units(elem_sizes[low_idx+1]*sizeof_element), ptr_size_units))
> received_units)){
//By default, the new block will use the rest of the buffer
new_block->m_size = received_units - total_used_units;
memory_algo->priv_mark_new_allocated_block(new_block);
@@ -530,13 +530,12 @@ class memory_algorithm_common
//If the remaining units are bigger than needed and we can
//split it obtaining a new free memory block do it.
if((received_units - total_used_units) >= (elem_units + MemoryAlgorithm::BlockCtrlUnits)){
size_type shrunk_received;
size_type shrunk_request = elem_units*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk;
size_type shrunk_received = shrunk_request;
bool shrink_ok = shrink
(memory_algo
,memory_algo->priv_get_user_buffer(new_block)
,shrunk_request
,shrunk_request
,shrunk_received);
(void)shrink_ok;
//Shrink must always succeed with passed parameters

View File

@@ -34,8 +34,7 @@
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <algorithm>
#include <utility>
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <cstring>
#include <boost/assert.hpp>
#include <new>
@@ -192,15 +191,11 @@ class simple_seq_fit_impl
void zero_free_memory();
template<class T>
std::pair<T *, bool>
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0);
T *allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type &prefer_in_recvd_out_size, T *&reuse);
std::pair<void *, bool>
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
void *reuse_ptr = 0, size_type sizeof_object = 1);
void * raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type &prefer_in_recvd_out_size, void *&reuse_ptr, size_type sizeof_object = 1);
//!Returns the size of the buffer previously allocated pointed by ptr
size_type size(const void *ptr) const;
@@ -218,18 +213,15 @@ class simple_seq_fit_impl
static block_ctrl *priv_get_block(const void *ptr);
//!Real allocation algorithm with min allocation option
std::pair<void *, bool> priv_allocate(boost::interprocess::allocation_type command
,size_type min_size
,size_type preferred_size
,size_type &received_size
,void *reuse_ptr = 0);
void * priv_allocate(boost::interprocess::allocation_type command
,size_type min_size
,size_type &prefer_in_recvd_out_size, void *&reuse_ptr);
std::pair<void *, bool> priv_allocation_command(boost::interprocess::allocation_type command
,size_type min_size
,size_type preferred_size
,size_type &received_size
,void *reuse_ptr
,size_type sizeof_object);
void * priv_allocation_command(boost::interprocess::allocation_type command
,size_type min_size
,size_type &prefer_in_recvd_out_size
,void *&reuse_ptr
,size_type sizeof_object);
//!Returns the number of total units that a user buffer
//!of "userbytes" bytes really occupies (including header)
@@ -247,18 +239,14 @@ class simple_seq_fit_impl
//!Returns previous block's if it's free.
//!Returns 0 if previous block is not free.
std::pair<block_ctrl*, block_ctrl*>priv_prev_block_if_free(block_ctrl *ptr);
std::pair<block_ctrl*, block_ctrl*> priv_prev_block_if_free(block_ctrl *ptr);
//!Real expand function implementation
bool priv_expand(void *ptr
,size_type min_size, size_type preferred_size
,size_type &received_size);
bool priv_expand(void *ptr, size_type min_size, size_type &prefer_in_recvd_out_size);
//!Real expand to both sides implementation
void* priv_expand_both_sides(boost::interprocess::allocation_type command
,size_type min_size
,size_type preferred_size
,size_type &received_size
,size_type min_size, size_type &prefer_in_recvd_out_size
,void *reuse_ptr
,bool only_preferred_backwards);
@@ -409,8 +397,9 @@ void simple_seq_fit_impl<MutexFamily, VoidPointer>::shrink_to_fit()
void *unique_block = 0;
if(!m_header.m_allocated){
BOOST_ASSERT(prev == root);
size_type ignore;
unique_block = priv_allocate(boost::interprocess::allocate_new, 0, 0, ignore).first;
size_type ignore_recvd = 0;
void *ignore_reuse = 0;
unique_block = priv_allocate(boost::interprocess::allocate_new, 0, ignore_recvd, ignore_reuse);
if(!unique_block)
return;
last = ipcdetail::to_raw_pointer(m_header.m_root.m_next);
@@ -573,8 +562,9 @@ inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
size_type ignore;
return priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
size_type ignore_recvd = nbytes;
void *ignore_reuse = 0;
return priv_allocate(boost::interprocess::allocate_new, nbytes, ignore_recvd, ignore_reuse);
}
template<class MutexFamily, class VoidPointer>
@@ -590,61 +580,66 @@ inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
template<class MutexFamily, class VoidPointer>
template<class T>
inline std::pair<T*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
inline T* simple_seq_fit_impl<MutexFamily, VoidPointer>::
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr)
size_type &prefer_in_recvd_out_size, T *&reuse_ptr)
{
std::pair<void*, bool> ret = priv_allocation_command
(command, limit_size, preferred_size, received_size, static_cast<void*>(reuse_ptr), sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret.first % ::boost::alignment_of<T>::value));
return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);
void *raw_reuse = reuse_ptr;
void * const ret = priv_allocation_command
(command, limit_size, prefer_in_recvd_out_size, raw_reuse, sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret % ::boost::alignment_of<T>::value));
reuse_ptr = static_cast<T*>(raw_reuse);
return static_cast<T*>(ret);
}
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
size_type preferred_objects,size_type &received_objects,
void *reuse_ptr, size_type sizeof_object)
inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
size_type &prefer_in_recvd_out_size, void *&reuse_ptr, size_type sizeof_object)
{
if(!sizeof_object)
return std::pair<void *, bool>(static_cast<void*>(0), false);
size_type const preferred_objects = prefer_in_recvd_out_size;
if(!sizeof_object){
return reuse_ptr = 0, static_cast<void*>(0);
}
if(command & boost::interprocess::try_shrink_in_place){
if(!reuse_ptr) return static_cast<void*>(0);
prefer_in_recvd_out_size = preferred_objects*sizeof_object;
bool success = algo_impl_t::try_shrink
( this, reuse_ptr, limit_objects*sizeof_object
, preferred_objects*sizeof_object, received_objects);
received_objects /= sizeof_object;
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
( this, reuse_ptr, limit_objects*sizeof_object, prefer_in_recvd_out_size);
prefer_in_recvd_out_size /= sizeof_object;
return success ? reuse_ptr : 0;
}
else{
return priv_allocation_command
(command, limit_objects, prefer_in_recvd_out_size, reuse_ptr, sizeof_object);
}
return priv_allocation_command
(command, limit_objects, preferred_objects, received_objects, reuse_ptr, sizeof_object);
}
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size, size_type &received_size,
void *reuse_ptr, size_type sizeof_object)
size_type &prefer_in_recvd_out_size, void *&reuse_ptr, size_type sizeof_object)
{
size_type const preferred_size = prefer_in_recvd_out_size;
command &= ~boost::interprocess::expand_bwd;
if(!command) return std::pair<void *, bool>(static_cast<void*>(0), false);
if(!command){
return reuse_ptr = 0, static_cast<void*>(0);
}
std::pair<void*, bool> ret;
size_type max_count = m_header.m_size/sizeof_object;
if(limit_size > max_count || preferred_size > max_count){
ret.first = 0; return ret;
return reuse_ptr = 0, static_cast<void*>(0);
}
size_type l_size = limit_size*sizeof_object;
size_type p_size = preferred_size*sizeof_object;
size_type r_size;
size_type r_size = preferred_size*sizeof_object;
void *ret = 0;
{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
ret = priv_allocate(command, l_size, p_size, r_size, reuse_ptr);
ret = priv_allocate(command, l_size, r_size, reuse_ptr);
}
received_size = r_size/sizeof_object;
prefer_in_recvd_out_size = r_size/sizeof_object;
return ret;
}
@@ -663,29 +658,29 @@ template<class MutexFamily, class VoidPointer>
void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_expand_both_sides(boost::interprocess::allocation_type command
,size_type min_size
,size_type preferred_size
,size_type &received_size
,size_type &prefer_in_recvd_out_size
,void *reuse_ptr
,bool only_preferred_backwards)
{
size_type const preferred_size = prefer_in_recvd_out_size;
typedef std::pair<block_ctrl *, block_ctrl *> prev_block_t;
block_ctrl *reuse = priv_get_block(reuse_ptr);
received_size = 0;
prefer_in_recvd_out_size = 0;
if(this->size(reuse_ptr) > min_size){
received_size = this->size(reuse_ptr);
prefer_in_recvd_out_size = this->size(reuse_ptr);
return reuse_ptr;
}
if(command & boost::interprocess::expand_fwd){
if(priv_expand(reuse_ptr, min_size, preferred_size, received_size))
if(priv_expand(reuse_ptr, min_size, prefer_in_recvd_out_size = preferred_size))
return reuse_ptr;
}
else{
received_size = this->size(reuse_ptr);
prefer_in_recvd_out_size = this->size(reuse_ptr);
}
if(command & boost::interprocess::expand_bwd){
size_type extra_forward = !received_size ? 0 : received_size + BlockCtrlBytes;
size_type extra_forward = !prefer_in_recvd_out_size ? 0 : prefer_in_recvd_out_size + BlockCtrlBytes;
prev_block_t prev_pair = priv_prev_block_if_free(reuse);
block_ctrl *prev = prev_pair.second;
if(!prev){
@@ -703,7 +698,7 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
//Check if previous block has enough size
if((prev->get_user_bytes()) >= needs_backwards){
//Now take all next space. This will succeed
if(!priv_expand(reuse_ptr, received_size, received_size, received_size)){
if(!priv_expand(reuse_ptr, prefer_in_recvd_out_size, prefer_in_recvd_out_size)){
BOOST_ASSERT(0);
}
@@ -717,7 +712,7 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
BlockCtrlUnits + (needs_backwards + extra_forward)/Alignment;
prev->m_size =
(prev->get_total_bytes() - needs_backwards)/Alignment - BlockCtrlUnits;
received_size = needs_backwards + extra_forward;
prefer_in_recvd_out_size = needs_backwards + extra_forward;
m_header.m_allocated += needs_backwards + BlockCtrlBytes;
return priv_get_user_buffer(new_block);
}
@@ -725,7 +720,7 @@ void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
//Just merge the whole previous block
block_ctrl *prev_2_block = prev_pair.first;
//Update received size and allocation
received_size = extra_forward + prev->get_user_bytes();
prefer_in_recvd_out_size = extra_forward + prev->get_user_bytes();
m_header.m_allocated += prev->get_total_bytes();
//Now unlink it from previous block
prev_2_block->m_next = prev->m_next;
@@ -761,23 +756,21 @@ simple_seq_fit_impl<MutexFamily, VoidPointer>::
}
template<class MutexFamily, class VoidPointer>
std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
void * simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_allocate(boost::interprocess::allocation_type command
,size_type limit_size
,size_type preferred_size
,size_type &received_size
,void *reuse_ptr)
,size_type limit_size, size_type &prefer_in_recvd_out_size, void *&reuse_ptr)
{
size_type const preferred_size = prefer_in_recvd_out_size;
if(command & boost::interprocess::shrink_in_place){
bool success =
algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
if(!reuse_ptr) return static_cast<void*>(0);
bool success = algo_impl_t::shrink(this, reuse_ptr, limit_size, prefer_in_recvd_out_size);
return success ? reuse_ptr : 0;
}
typedef std::pair<void *, bool> return_type;
received_size = 0;
prefer_in_recvd_out_size = 0;
if(limit_size > preferred_size)
return return_type(static_cast<void*>(0), false);
if(limit_size > preferred_size){
return reuse_ptr = 0, static_cast<void*>(0);
}
//Number of units to request (including block_ctrl header)
size_type nunits = ipcdetail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlUnits;
@@ -791,19 +784,16 @@ std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
size_type biggest_size = 0;
//Expand in place
//reuse_ptr, limit_size, preferred_size, received_size
//
if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
void *ret = priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, true);
void *ret = priv_expand_both_sides(command, limit_size, prefer_in_recvd_out_size = preferred_size, reuse_ptr, true);
if(ret){
algo_impl_t::assert_alignment(ret);
return return_type(ret, true);
return ret;
}
}
if(command & boost::interprocess::allocate_new){
received_size = 0;
prefer_in_recvd_out_size = 0;
while(block != root){
//Update biggest block pointers
if(block->m_size > biggest_size){
@@ -812,10 +802,10 @@ std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
biggest_block = block;
}
algo_impl_t::assert_alignment(block);
void *addr = this->priv_check_and_allocate(nunits, prev, block, received_size);
void *addr = this->priv_check_and_allocate(nunits, prev, block, prefer_in_recvd_out_size);
if(addr){
algo_impl_t::assert_alignment(addr);
return return_type(addr, false);
return reuse_ptr = 0, addr;
}
//Bad luck, let's check next block
prev = block;
@@ -826,25 +816,23 @@ std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
//try with this block
if(biggest_block){
size_type limit_units = ipcdetail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlUnits;
if(biggest_block->m_size < limit_units)
return return_type(static_cast<void*>(0), false);
received_size = biggest_block->m_size*Alignment - BlockCtrlUnits;
if(biggest_block->m_size < limit_units){
return reuse_ptr = 0, static_cast<void*>(0);
}
void *ret = this->priv_check_and_allocate
(biggest_block->m_size, prev_biggest_block, biggest_block, received_size);
(biggest_block->m_size, prev_biggest_block, biggest_block, prefer_in_recvd_out_size = biggest_block->m_size*Alignment - BlockCtrlUnits);
BOOST_ASSERT(ret != 0);
algo_impl_t::assert_alignment(ret);
return return_type(ret, false);
return reuse_ptr = 0, ret;
}
}
//Now try to expand both sides with min size
if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
return_type ret (priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, false), true);
algo_impl_t::assert_alignment(ret.first);
void *ret = priv_expand_both_sides (command, limit_size, prefer_in_recvd_out_size = preferred_size, reuse_ptr, false);
algo_impl_t::assert_alignment(ret);
return ret;
}
return return_type(static_cast<void*>(0), false);
return reuse_ptr = 0, static_cast<void*>(0);
}
template<class MutexFamily, class VoidPointer> inline
@@ -917,11 +905,9 @@ inline
template<class MutexFamily, class VoidPointer>
inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_expand (void *ptr
,size_type min_size
,size_type preferred_size
,size_type &received_size)
priv_expand (void *ptr, size_type min_size, size_type &received_size)
{
size_type preferred_size = received_size;
//Obtain the real size of the block
block_ctrl *block = reinterpret_cast<block_ctrl*>(priv_get_block(ptr));
size_type old_block_size = block->m_size;

View File

@@ -37,8 +37,6 @@
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <algorithm>
#include <utility>
#include <climits>
#include <cstring>
#include <iterator>
@@ -235,15 +233,12 @@ class rbtree_best_fit
bool check_sanity();
template<class T>
std::pair<T *, bool>
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0);
T * allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type &prefer_in_recvd_out_size, T *&reuse);
std::pair<void *, bool>
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_object,
size_type preferred_object,size_type &received_object,
void *reuse_ptr = 0, size_type sizeof_object = 1);
void * raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_object,
size_type &prefer_in_recvd_out_size,
void *&reuse_ptr, size_type sizeof_object = 1);
//!Returns the size of the buffer previously allocated pointed by ptr
size_type size(const void *ptr) const;
@@ -260,19 +255,14 @@ class rbtree_best_fit
block_ctrl *priv_end_block();
std::pair<void*, bool>
priv_allocation_command(boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
void *reuse_ptr, size_type sizeof_object);
void* priv_allocation_command(boost::interprocess::allocation_type command, size_type limit_size,
size_type &prefer_in_recvd_out_size, void *&reuse_ptr, size_type sizeof_object);
//!Real allocation algorithm with min allocation option
std::pair<void *, bool> priv_allocate(boost::interprocess::allocation_type command
,size_type limit_size
,size_type preferred_size
,size_type &received_size
,void *reuse_ptr = 0
,size_type backwards_multiple = 1);
void * priv_allocate( boost::interprocess::allocation_type command
, size_type limit_size, size_type &prefer_in_recvd_out_size
, void *&reuse_ptr, size_type backwards_multiple = 1);
//!Obtains the block control structure of the user buffer
static block_ctrl *priv_get_block(const void *ptr);
@@ -285,15 +275,12 @@ class rbtree_best_fit
static size_type priv_get_total_units(size_type userbytes);
//!Real expand function implementation
bool priv_expand(void *ptr
,const size_type min_size, const size_type preferred_size
,size_type &received_size);
bool priv_expand(void *ptr, const size_type min_size, size_type &prefer_in_recvd_out_size);
//!Real expand to both sides implementation
void* priv_expand_both_sides(boost::interprocess::allocation_type command
,size_type min_size
,size_type preferred_size
,size_type &received_size
,size_type &prefer_in_recvd_out_size
,void *reuse_ptr
,bool only_preferred_backwards
,size_type backwards_multiple);
@@ -540,8 +527,9 @@ void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::shrink_to_fit()
//Check if no memory is allocated between the first and last block
if(priv_next_block(first_block) == old_end_block){
//If so check if we can allocate memory
size_type ignore;
unique_buffer = priv_allocate(boost::interprocess::allocate_new, 0, 0, ignore).first;
size_type ignore_recvd = 0;
void *ignore_reuse = 0;
unique_buffer = priv_allocate(boost::interprocess::allocate_new, 0, ignore_recvd, ignore_reuse);
//If not, return, we can't shrink
if(!unique_buffer)
return;
@@ -675,9 +663,9 @@ inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
size_type ignore;
void * ret = priv_allocate(boost::interprocess::allocate_new, nbytes, nbytes, ignore).first;
return ret;
size_type ignore_recvd = nbytes;
void *ignore_reuse = 0;
return priv_allocate(boost::interprocess::allocate_new, nbytes, ignore_recvd, ignore_reuse);
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
@@ -692,48 +680,51 @@ inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
template<class T>
inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
inline T* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr)
size_type &prefer_in_recvd_out_size, T *&reuse)
{
std::pair<void*, bool> ret = priv_allocation_command
(command, limit_size, preferred_size, received_size, static_cast<void*>(reuse_ptr), sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret.first % ::boost::alignment_of<T>::value));
return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);
void* raw_reuse = reuse;
void* const ret = priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, raw_reuse, sizeof(T));
reuse = static_cast<T*>(raw_reuse);
BOOST_ASSERT(0 == ((std::size_t)ret % ::boost::alignment_of<T>::value));
return static_cast<T*>(ret);
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
size_type preferred_objects,size_type &received_objects,
void *reuse_ptr, size_type sizeof_object)
size_type &prefer_in_recvd_out_objects, void *&reuse_ptr, size_type sizeof_object)
{
size_type const preferred_objects = prefer_in_recvd_out_objects;
if(!sizeof_object)
return std::pair<void *, bool>(static_cast<void*>(0), false);
return reuse_ptr = 0, static_cast<void*>(0);
if(command & boost::interprocess::try_shrink_in_place){
bool success = algo_impl_t::try_shrink
if(!reuse_ptr) return static_cast<void*>(0);
const bool success = algo_impl_t::try_shrink
( this, reuse_ptr, limit_objects*sizeof_object
, preferred_objects*sizeof_object, received_objects);
received_objects /= sizeof_object;
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
, prefer_in_recvd_out_objects = preferred_objects*sizeof_object);
prefer_in_recvd_out_objects /= sizeof_object;
return success ? reuse_ptr : 0;
}
else{
return priv_allocation_command
(command, limit_objects, prefer_in_recvd_out_objects, reuse_ptr, sizeof_object);
}
return priv_allocation_command
(command, limit_objects, preferred_objects, received_objects, reuse_ptr, sizeof_object);
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
priv_allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
void *reuse_ptr, size_type sizeof_object)
size_type &prefer_in_recvd_out_size,
void *&reuse_ptr, size_type sizeof_object)
{
std::pair<void*, bool> ret;
size_type max_count = m_header.m_size/sizeof_object;
void* ret;
size_type const preferred_size = prefer_in_recvd_out_size;
size_type const max_count = m_header.m_size/sizeof_object;
if(limit_size > max_count || preferred_size > max_count){
ret.first = 0; return ret;
return reuse_ptr = 0, static_cast<void*>(0);
}
size_type l_size = limit_size*sizeof_object;
size_type p_size = preferred_size*sizeof_object;
@@ -742,9 +733,9 @@ inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlign
//-----------------------
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
//-----------------------
ret = priv_allocate(command, l_size, p_size, r_size, reuse_ptr, sizeof_object);
ret = priv_allocate(command, l_size, r_size = p_size, reuse_ptr, sizeof_object);
}
received_size = r_size/sizeof_object;
prefer_in_recvd_out_size = r_size/sizeof_object;
return ret;
}
@@ -788,20 +779,20 @@ template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
priv_expand_both_sides(boost::interprocess::allocation_type command
,size_type min_size
,size_type preferred_size
,size_type &received_size
,size_type &prefer_in_recvd_out_size
,void *reuse_ptr
,bool only_preferred_backwards
,size_type backwards_multiple)
{
size_type const preferred_size = prefer_in_recvd_out_size;
algo_impl_t::assert_alignment(reuse_ptr);
if(command & boost::interprocess::expand_fwd){
if(priv_expand(reuse_ptr, min_size, preferred_size, received_size))
if(priv_expand(reuse_ptr, min_size, prefer_in_recvd_out_size = preferred_size))
return reuse_ptr;
}
else{
received_size = this->size(reuse_ptr);
if(received_size >= preferred_size || received_size >= min_size)
prefer_in_recvd_out_size = this->size(reuse_ptr);
if(prefer_in_recvd_out_size >= preferred_size || prefer_in_recvd_out_size >= min_size)
return reuse_ptr;
}
@@ -835,7 +826,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
size_type lcm;
if(!algo_impl_t::calculate_lcm_and_needs_backwards_lcmed
( backwards_multiple
, received_size
, prefer_in_recvd_out_size
, only_preferred_backwards ? preferred_size : min_size
, lcm, needs_backwards_aligned)){
return 0;
@@ -846,10 +837,10 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//Now take all next space. This will succeed
if(command & boost::interprocess::expand_fwd){
size_type received_size2;
if(!priv_expand(reuse_ptr, received_size, received_size, received_size2)){
if(!priv_expand(reuse_ptr, prefer_in_recvd_out_size, received_size2 = prefer_in_recvd_out_size)){
BOOST_ASSERT(0);
}
BOOST_ASSERT(received_size == received_size2);
BOOST_ASSERT(prefer_in_recvd_out_size == received_size2);
}
//We need a minimum size to split the previous one
if(prev_block->m_size >= (needs_backwards_aligned/Alignment + BlockCtrlUnits)){
@@ -858,7 +849,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//Free old previous buffer
new_block->m_size =
AllocatedCtrlUnits + (needs_backwards_aligned + (received_size - UsableByPreviousChunk))/Alignment;
AllocatedCtrlUnits + (needs_backwards_aligned + (prefer_in_recvd_out_size - UsableByPreviousChunk))/Alignment;
BOOST_ASSERT(new_block->m_size >= BlockCtrlUnits);
priv_mark_as_allocated_block(new_block);
@@ -880,7 +871,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
}
}
received_size = needs_backwards_aligned + received_size;
prefer_in_recvd_out_size = needs_backwards_aligned + prefer_in_recvd_out_size;
m_header.m_allocated += needs_backwards_aligned;
//Check alignment
@@ -903,7 +894,7 @@ void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
//Just merge the whole previous block
//prev_block->m_size*Alignment is multiple of lcm (and backwards_multiple)
received_size = received_size + (size_type)prev_block->m_size*Alignment;
prefer_in_recvd_out_size = prefer_in_recvd_out_size + (size_type)prev_block->m_size*Alignment;
m_header.m_allocated += (size_type)prev_block->m_size*Alignment;
//Now update sizes
@@ -937,28 +928,25 @@ inline void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
void * rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
priv_allocate(boost::interprocess::allocation_type command
,size_type limit_size
,size_type preferred_size
,size_type &received_size
,void *reuse_ptr
,size_type &prefer_in_recvd_out_size
,void *&reuse_ptr
,size_type backwards_multiple)
{
//Remove me. Forbid backwards allocation
//command &= (~boost::interprocess::expand_bwd);
size_type const preferred_size = prefer_in_recvd_out_size;
if(command & boost::interprocess::shrink_in_place){
if(!reuse_ptr) return static_cast<void*>(0);
bool success =
algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
algo_impl_t::shrink(this, reuse_ptr, limit_size, prefer_in_recvd_out_size = preferred_size);
return success ? reuse_ptr : 0;
}
typedef std::pair<void *, bool> return_type;
received_size = 0;
prefer_in_recvd_out_size = 0;
if(limit_size > preferred_size)
return return_type(static_cast<void*>(0), false);
return reuse_ptr = 0, static_cast<void*>(0);
//Number of units to request (including block_ctrl header)
size_type preferred_units = priv_get_total_units(preferred_size);
@@ -967,11 +955,12 @@ std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>:
size_type limit_units = priv_get_total_units(limit_size);
//Expand in place
prefer_in_recvd_out_size = preferred_size;
if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
void *ret = priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, true, backwards_multiple);
(command, limit_size, prefer_in_recvd_out_size, reuse_ptr, true, backwards_multiple);
if(ret)
return return_type(ret, true);
return ret;
}
if(command & boost::interprocess::allocate_new){
@@ -979,25 +968,24 @@ std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>:
imultiset_iterator it(m_header.m_imultiset.lower_bound(preferred_units, comp));
if(it != m_header.m_imultiset.end()){
return return_type(this->priv_check_and_allocate
(preferred_units, ipcdetail::to_raw_pointer(&*it), received_size), false);
return reuse_ptr = 0, this->priv_check_and_allocate
(preferred_units, ipcdetail::to_raw_pointer(&*it), prefer_in_recvd_out_size);
}
if(it != m_header.m_imultiset.begin()&&
(--it)->m_size >= limit_units){
return return_type(this->priv_check_and_allocate
(it->m_size, ipcdetail::to_raw_pointer(&*it), received_size), false);
return reuse_ptr = 0, this->priv_check_and_allocate
(it->m_size, ipcdetail::to_raw_pointer(&*it), prefer_in_recvd_out_size);
}
}
//Now try to expand both sides with min size
if(reuse_ptr && (command & (boost::interprocess::expand_fwd | boost::interprocess::expand_bwd))){
return return_type(priv_expand_both_sides
(command, limit_size, preferred_size, received_size, reuse_ptr, false, backwards_multiple), true);
return priv_expand_both_sides
(command, limit_size, prefer_in_recvd_out_size = preferred_size, reuse_ptr, false, backwards_multiple);
}
return return_type(static_cast<void*>(0), false);
return reuse_ptr = 0, static_cast<void*>(0);
}
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
@@ -1030,11 +1018,9 @@ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
priv_expand (void *ptr
,const size_type min_size
,const size_type preferred_size
,size_type &received_size)
priv_expand (void *ptr, const size_type min_size, size_type &prefer_in_recvd_out_size)
{
size_type const preferred_size = prefer_in_recvd_out_size;
//Obtain the real size of the block
block_ctrl *block = priv_get_block(ptr);
size_type old_block_units = block->m_size;
@@ -1043,8 +1029,8 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
BOOST_ASSERT(priv_is_allocated_block(block));
//Put this to a safe value
received_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
if(received_size >= preferred_size || received_size >= min_size)
prefer_in_recvd_out_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
if(prefer_in_recvd_out_size >= preferred_size || prefer_in_recvd_out_size >= min_size)
return true;
//Now translate it to Alignment units
@@ -1057,7 +1043,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
block_ctrl *next_block;
if(priv_is_allocated_block(next_block = priv_next_block(block))){
return received_size >= min_size ? true : false;
return prefer_in_recvd_out_size >= min_size;
}
algo_impl_t::assert_alignment(next_block);
@@ -1068,7 +1054,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
const size_type merged_user_units = merged_units - AllocatedCtrlUnits;
if(merged_user_units < min_user_units){
received_size = merged_units*Alignment - UsableByPreviousChunk;
prefer_in_recvd_out_size = merged_units*Alignment - UsableByPreviousChunk;
return false;
}
@@ -1132,7 +1118,7 @@ bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
m_header.m_allocated += (merged_units - old_block_units)*Alignment;
}
priv_mark_as_allocated_block(block);
received_size = ((size_type)block->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
prefer_in_recvd_out_size = ((size_type)block->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
return true;
}

View File

@@ -37,7 +37,7 @@
#include <cstddef> //std::size_t
#include <string> //char_traits
#include <new> //std::nothrow
#include <utility> //std::pair
#include <boost/intrusive/detail/minimal_pair_header.hpp>
#include <boost/assert.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <exception>
@@ -191,28 +191,23 @@ class segment_manager_base
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
template<class T>
std::pair<T *, bool>
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type preferred_size,size_type &received_size,
T *reuse_ptr = 0)
T *allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
size_type &prefer_in_recvd_out_size, T *&reuse)
{
std::pair<T *, bool> ret = MemoryAlgorithm::allocation_command
( command | boost::interprocess::nothrow_allocation, limit_size, preferred_size, received_size
, reuse_ptr);
if(!(command & boost::interprocess::nothrow_allocation) && !ret.first)
T *ret = MemoryAlgorithm::allocation_command
(command | boost::interprocess::nothrow_allocation, limit_size, prefer_in_recvd_out_size, reuse);
if(!(command & boost::interprocess::nothrow_allocation) && !ret)
throw bad_alloc();
return ret;
}
std::pair<void *, bool>
raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
size_type preferred_objects,size_type &received_objects,
void *reuse_ptr = 0, size_type sizeof_object = 1)
void *raw_allocation_command (boost::interprocess::allocation_type command, size_type limit_objects,
size_type &prefer_in_recvd_out_size, void *&reuse, size_type sizeof_object = 1)
{
std::pair<void *, bool> ret = MemoryAlgorithm::raw_allocation_command
( command | boost::interprocess::nothrow_allocation, limit_objects, preferred_objects, received_objects
, reuse_ptr, sizeof_object);
if(!(command & boost::interprocess::nothrow_allocation) && !ret.first)
void *ret = MemoryAlgorithm::raw_allocation_command
( command | boost::interprocess::nothrow_allocation, limit_objects,
prefer_in_recvd_out_size, reuse, sizeof_object);
if(!(command & boost::interprocess::nothrow_allocation) && !ret)
throw bad_alloc();
return ret;
}
@@ -728,7 +723,7 @@ class segment_manager
//!and the object count. On failure the first member of the
//!returned pair is 0.
template <class T>
std::pair<T*, size_type> priv_find__impl (const ipcdetail::unique_instance_t* name, bool lock)
std::pair<T*, size_type> priv_find_impl (const ipcdetail::unique_instance_t* name, bool lock)
{
ipcdetail::placement_destroy<T> table;
size_type size;
@@ -741,7 +736,7 @@ class segment_manager
{
void *ret;
//Security overflow check
if(num > ((std::size_t)-1)/table.size){
if(num > ((std::size_t)-1)/table.size){
if(dothrow)
throw bad_alloc();
else
@@ -1019,7 +1014,7 @@ class segment_manager
//Check if the distance between the name pointer and the memory pointer
//is correct (this can detect incorrect type in destruction)
std::size_t num = ctrl_data->m_value_bytes/table.size;
std::size_t num = ctrl_data->m_value_bytes/table.size;
void *values = ctrl_data->value();
//Sanity check

View File

@@ -25,9 +25,9 @@
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/detail/shared_dir_helpers.hpp>
#include <boost/interprocess/permissions.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <cstddef>
#include <string>
#include <algorithm>
#if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS_ONLY)
# include <sys/shm.h> //System V shared memory...
@@ -164,8 +164,8 @@ inline bool shared_memory_object::get_size(offset_t &size) const
inline void shared_memory_object::swap(shared_memory_object &other)
{
std::swap(m_handle, other.m_handle);
std::swap(m_mode, other.m_mode);
boost::adl_move_swap(m_handle, other.m_handle);
boost::adl_move_swap(m_mode, other.m_mode);
m_filename.swap(other.m_filename);
}

View File

@@ -30,7 +30,8 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <functional> // std::less
#include <boost/move/adl_move_swap.hpp>
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
namespace boost {
namespace interprocess {
@@ -189,7 +190,7 @@ class shared_count
}
void swap(shared_count & r) // nothrow
{ ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); }
{ ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_swap(m_pi, r.m_pi); }
long use_count() const // nothrow
{ return m_pi != 0? m_pi->use_count(): 0; }
@@ -306,7 +307,7 @@ class weak_count
}
void swap(weak_count & r) // nothrow
{ ipcdetail::do_swap(m_px, r.m_px); ipcdetail::do_swap(m_pi, r.m_pi); }
{ ::boost::adl_move_swap(m_px, r.m_px); ::boost::adl_move_swap(m_pi, r.m_pi); }
long use_count() const // nothrow
{ return m_pi != 0? m_pi->use_count() : 0; }

View File

@@ -27,10 +27,11 @@
#include <boost/assert.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <functional> // for std::less
#include <iosfwd> // for std::basic_ostream
#include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::less
namespace boost {
namespace interprocess {
@@ -168,7 +169,7 @@ class intrusive_ptr
//!Exchanges the contents of the two smart pointers.
//!Does not throw
void swap(intrusive_ptr & rhs)
{ ipcdetail::do_swap(m_ptr, rhs.m_ptr); }
{ ::boost::adl_move_swap(m_ptr, rhs.m_ptr); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:

View File

@@ -24,6 +24,7 @@
#include <boost/interprocess/detail/pointer_type.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/assert.hpp>
#include <boost/move/adl_move_swap.hpp>
//!\file
//!Describes the smart pointer scoped_ptr
@@ -129,7 +130,10 @@ class scoped_ptr
//!Exchanges the internal pointer and deleter with other scoped_ptr
//!Never throws.
void swap(scoped_ptr & b) // never throws
{ ipcdetail::do_swap<Deleter>(*this, b); ipcdetail::do_swap(m_ptr, b.m_ptr); }
{
::boost::adl_move_swap(static_cast<Deleter&>(*this), static_cast<Deleter&>(b));
::boost::adl_move_swap(m_ptr, b.m_ptr);
}
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
private:

View File

@@ -35,10 +35,7 @@
#include <boost/static_assert.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <algorithm> // for std::swap
#include <functional> // for std::less
#include <typeinfo> // for std::bad_cast
#include <iosfwd> // for std::basic_ostream
#include <iosfwd> // for std::basic_ostream
//!\file
//!Describes the smart pointer shared_ptr
@@ -391,7 +388,7 @@ inline typename managed_shared_ptr<T, ManagedMemory>::type
//!Does not throw, return null shared pointer in error.
template<class T, class ManagedMemory>
inline typename managed_shared_ptr<T, ManagedMemory>::type
make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory, std::nothrow_t)
make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory, const std::nothrow_t &)
{
try{
return typename managed_shared_ptr<T, ManagedMemory>::type

View File

@@ -27,6 +27,7 @@
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/move/adl_move_swap.hpp>
//!\file
//!Describes the smart pointer weak_ptr.
@@ -197,7 +198,7 @@ class weak_ptr
//!
//!Throws: nothing.
void swap(this_type & other) // never throws
{ ipcdetail::do_swap(m_pn, other.m_pn); }
{ ::boost::adl_move_swap(m_pn, other.m_pn); }
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
template<class T2, class A2, class D2>

File diff suppressed because it is too large Load Diff

View File

@@ -25,10 +25,7 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <boost/move/adl_move_swap.hpp>
#include <boost/static_assert.hpp>
//!\file
@@ -146,7 +143,7 @@ class allocator_v1
//!Swap segment manager. Does not throw. If each allocator_v1 is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ ipcdetail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
{ ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
};
//!Equality test for same type of allocator_v1

View File

@@ -14,7 +14,6 @@
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <iostream>
#include <algorithm>
#include <functional>
#include "print_container.hpp"
#include <string>

View File

@@ -12,9 +12,7 @@
#define BOOST_INTERPROCESS_TEST_CHECK_EQUAL_CONTAINERS_HPP
#include <boost/interprocess/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/container/detail/pair.hpp>
namespace boost{

View File

@@ -13,8 +13,6 @@
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include "print_container.hpp"

View File

@@ -9,11 +9,9 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <deque>
#include <iostream>
#include <functional>
#include <list>
#include <boost/interprocess/managed_shared_memory.hpp>

View File

@@ -20,15 +20,10 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/containers/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file
//!Describes an allocator to test expand capabilities
@@ -110,12 +105,9 @@ class dummy_test_allocator
//Experimental version 2 dummy_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type,
size_type,
size_type,
size_type &, const pointer & = 0)
{ return std::pair<pointer, bool>(pointer(0), true); }
pointer allocation_command(boost::interprocess::allocation_type,
size_type, size_type &, pointer &)
{ return pointer(); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
@@ -126,7 +118,7 @@ class dummy_test_allocator
//!must be deallocated only with deallocate_one().
//!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate_one()
{ return pointer(0); }
{ return pointer(); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated

View File

@@ -24,11 +24,11 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/move/adl_move_swap.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
#include <new>
//!\file
//!Describes an allocator to test expand capabilities
@@ -113,38 +113,34 @@ class expand_bwd_test_allocator
friend void swap(self_t &alloc1, self_t &alloc2)
{
ipcdetail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
ipcdetail::do_swap(alloc1.m_size, alloc2.m_size);
ipcdetail::do_swap(alloc1.m_offset, alloc2.m_offset);
::boost::adl_move_swap(alloc1.mp_buffer, alloc2.mp_buffer);
::boost::adl_move_swap(alloc1.m_size, alloc2.m_size);
::boost::adl_move_swap(alloc1.m_offset, alloc2.m_offset);
}
//Experimental version 2 expand_bwd_test_allocator functions
std::pair<pointer, bool>
allocation_command(boost::interprocess::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
pointer allocation_command(boost::interprocess::allocation_type command,
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
(void)preferred_size; (void)reuse; (void)command;
(void)reuse; (void)command;
//This allocator only expands backwards!
assert(m_allocations == 0 || (command & boost::interprocess::expand_bwd));
received_size = limit_size;
prefer_in_recvd_out_size = limit_size;
if(m_allocations == 0){
if((m_offset + limit_size) > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer + m_offset, false);
return mp_buffer + m_offset;
}
else if(m_allocations == 1){
if(limit_size > m_size){
assert(0);
}
++m_allocations;
return std::pair<pointer, bool>(mp_buffer, true);
return mp_buffer;
}
else{
assert(0);

View File

@@ -14,7 +14,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <vector>
#include "expand_bwd_test_allocator.hpp"
#include <algorithm>
#include <algorithm> //std::equal
#include <iostream>
#include <boost/type_traits/remove_volatile.hpp>
namespace boost { namespace interprocess { namespace test {

View File

@@ -25,10 +25,7 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/containers/version_type.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <boost/move/adl_move_swap.hpp>
//!\file
//!Describes an heap_allocator_v1 that allocates portions of fixed size
@@ -141,7 +138,7 @@ class heap_allocator_v1
//!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
//!different memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{ ipcdetail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
{ ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
};
//!Equality test for same type of heap_allocator_v1

View File

@@ -16,7 +16,7 @@
#include <boost/detail/lightweight_test.hpp>
#include <boost/config.hpp>
#include <algorithm>
#include <boost/move/adl_move_swap.hpp>
#include <functional>
typedef boost::interprocess::offset_ptr<void> VP;
@@ -283,8 +283,7 @@ void test()
BOOST_TEST(px.get() == 0);
BOOST_TEST(px2.get() == 0);
using std::swap;
swap(px, px2);
::boost::adl_move_swap(px, px2);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px2.get() == 0);
@@ -304,8 +303,7 @@ void test()
BOOST_TEST(px3.get() == p);
BOOST_TEST(px3->use_count() == 2);
using std::swap;
swap(px, px2);
::boost::adl_move_swap(px, px2);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px2.get() == p);
@@ -330,8 +328,7 @@ void test()
BOOST_TEST(px3.get() == p2);
BOOST_TEST(px3->use_count() == 2);
using std::swap;
swap(px, px2);
::boost::adl_move_swap(px, px2);
BOOST_TEST(px.get() == p1);
BOOST_TEST(px->use_count() == 1);

View File

@@ -106,9 +106,10 @@ bool test_allocation_shrink(Allocator &a)
;i < max
; ++i){
typename Allocator::size_type received_size;
char *reuse = static_cast<char*>(buffers[i]);
if(a.template allocation_command<char>
( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, i*2
, i, received_size, static_cast<char*>(buffers[i])).first){
, received_size = i, reuse)){
if(received_size > std::size_t(i*2)){
return false;
}
@@ -158,9 +159,10 @@ bool test_allocation_expand(Allocator &a)
std::size_t preferred_size = i*2;
preferred_size = min_size > preferred_size ? min_size : preferred_size;
char *reuse = static_cast<char*>(buffers[i]);
while(a.template allocation_command<char>
( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
, preferred_size, received_size, static_cast<char*>(buffers[i])).first){
, received_size = preferred_size, reuse)){
//Check received size is bigger than minimum
if(received_size < min_size){
return false;
@@ -196,11 +198,12 @@ bool test_allocation_shrink_and_expand(Allocator &a)
//Allocate buffers wand store received sizes
for(int i = 0; true; ++i){
typename Allocator::size_type received_size;
char *reuse = 0;
void *ptr = a.template allocation_command<char>
( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, i, i*2, received_size).first;
( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, i, received_size = i*2, reuse);
if(!ptr){
ptr = a.template allocation_command<char>
( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, 1, i*2, received_size).first;
( boost::interprocess::allocate_new | boost::interprocess::nothrow_allocation, 1, received_size = i*2, reuse);
if(!ptr)
break;
}
@@ -213,9 +216,10 @@ bool test_allocation_shrink_and_expand(Allocator &a)
; i < max
; ++i){
typename Allocator::size_type received_size;
char *reuse = static_cast<char*>(buffers[i]);
if(a.template allocation_command<char>
( boost::interprocess::shrink_in_place | boost::interprocess::nothrow_allocation, received_sizes[i]
, i, received_size, static_cast<char*>(buffers[i])).first){
, received_size = i, reuse)){
if(received_size > std::size_t(received_sizes[i])){
return false;
}
@@ -232,9 +236,10 @@ bool test_allocation_shrink_and_expand(Allocator &a)
;++i){
typename Allocator::size_type received_size;
std::size_t request_size = received_sizes[i];
char *reuse = static_cast<char*>(buffers[i]);
if(a.template allocation_command<char>
( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, request_size
, request_size, received_size, static_cast<char*>(buffers[i])).first){
, received_size = request_size, reuse)){
if(received_size != received_sizes[i]){
return false;
}
@@ -297,9 +302,10 @@ bool test_allocation_deallocation_expand(Allocator &a)
std::size_t preferred_size = i*2;
preferred_size = min_size > preferred_size ? min_size : preferred_size;
char *reuse = static_cast<char*>(buffers[i]);
while(a.template allocation_command<char>
( boost::interprocess::expand_fwd | boost::interprocess::nothrow_allocation, min_size
, preferred_size, received_size, static_cast<char*>(buffers[i])).first){
, received_size = preferred_size, reuse)){
//Check received size is bigger than minimum
if(received_size < min_size){
return false;
@@ -367,17 +373,18 @@ bool test_allocation_with_reuse(Allocator &a)
for(int i = 0; true; ++i){
std::size_t min_size = (received_size + 1);
std::size_t prf_size = (received_size + (i+1)*2);
std::pair<void*, bool> ret = a.raw_allocation_command
void *reuse = ptr;
void *ret = a.raw_allocation_command
( boost::interprocess::expand_bwd | boost::interprocess::nothrow_allocation, min_size
, prf_size, received_size, static_cast<char*>(ptr), sizeof_object);
if(!ret.first)
, received_size = prf_size, reuse, sizeof_object);
if(!ret)
break;
//If we have memory, this must be a buffer reuse
if(!ret.second)
if(!reuse)
return 1;
if(received_size < min_size)
return 1;
ptr = ret.first;
ptr = ret;
}
//There is only a single block so deallocate it
a.deallocate(ptr);

View File

@@ -16,12 +16,16 @@
#include <boost/interprocess/containers/set.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <vector>
#include <iostream>
#include <cstddef>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <functional>
#include <iostream>
#include <vector>
#include <stdexcept>
#include <limits>
#include "get_process_id_name.hpp"
////////////////////////////////////////////////////////////////////////////////

View File

@@ -12,33 +12,25 @@
#define BOOST_INTERPROCESS_TEST_PRINTCONTAINER_HPP
#include <boost/interprocess/detail/config_begin.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
namespace boost{
namespace interprocess{
namespace test{
struct PrintValues : public std::unary_function<int, void>
{
void operator() (int value) const
{
std::cout << value << " ";
}
};
template<class Container>
void PrintContents(const Container &cont, const char *contName)
{
std::cout<< "Printing contents of " << contName << std::endl;
std::for_each(cont.begin(), cont.end(), PrintValues());
typename Container::iterator b(cont.begin()), e(cont.end());
for(; b != e; ++b){
std::cout << *b << " ";
}
std::cout<< std::endl << std::endl;
}
//Function to dump data
template<class MyShmCont
,class MyStdCont>
template<class MyShmCont, class MyStdCont>
void PrintContainers(MyShmCont *shmcont, MyStdCont *stdcont)
{
typename MyShmCont::iterator itshm = shmcont->begin(), itshmend = shmcont->end();

View File

@@ -33,6 +33,9 @@ struct atomic_func_test
{
object = rsm.template find<int>("atomic_func_find_object").first;
}
private:
atomic_func_test operator=(const atomic_func_test&);
atomic_func_test(const atomic_func_test&);
};
template <class SegmentManager>
@@ -213,7 +216,7 @@ bool test_segment_manager()
const char *const object2_name = "object2";
int const int_array_values[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for(std::size_t i = 0; i != 4; ++i){
for(std::size_t i = 0; i != 1/*4*/; ++i){
if(seg_mgr->template find<unsigned int>(object1_name).first)
return false;
//Single element construction

View File

@@ -13,14 +13,12 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include "check_equal_containers.hpp"
#include <memory>
#include <set>
#include <functional>
#include "print_container.hpp"
#include <boost/move/utility_core.hpp>
#include <string>
#include "get_process_id_name.hpp"
#include <functional>
namespace boost{
namespace interprocess{
namespace test{

View File

@@ -9,12 +9,6 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/stable_vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

View File

@@ -15,12 +15,10 @@
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstddef>
#include <new>
#include "dummy_test_allocator.hpp"
#include "check_equal_containers.hpp"
#include "expand_bwd_test_allocator.hpp"

View File

@@ -26,8 +26,6 @@
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <algorithm>
#include <iostream>
#include <boost/version.hpp>
namespace boost {

View File

@@ -9,12 +9,6 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

View File

@@ -12,12 +12,6 @@
#define BOOST_INTERPROCESS_TEST_VECTOR_TEST_HEADER
#include <boost/interprocess/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
#include <vector>
#include <iostream>
#include <functional>
#include <list>
#include <boost/interprocess/exceptions.hpp>
#include <boost/move/utility_core.hpp>
@@ -25,11 +19,17 @@
#include "print_container.hpp"
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include <string>
#include <vector>
#include "get_process_id_name.hpp"
#include "emplace_test.hpp"
#include <vector>
#include <list>
#include <string>
#include <iostream>
#include <cstddef>
namespace boost{
namespace interprocess{
namespace test{