|
Boost-Commit : |
From: igaztanaga_at_[hidden]
Date: 2007-10-21 05:01:19
Author: igaztanaga
Date: 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
New Revision: 40267
URL: http://svn.boost.org/trac/boost/changeset/40267
Log:
Doxygen bug workaround. Corrected Solaris errors. Experimental grow/shrink_to_fit for managed_shared_memory and managed_mapped_file.
Added:
trunk/boost/interprocess/detail/interprocess_tester.hpp (contents, props changed)
Text files modified:
trunk/boost/interprocess/containers/detail/tree.hpp | 24 +--
trunk/boost/interprocess/containers/list.hpp | 16 +
trunk/boost/interprocess/containers/slist.hpp | 19 +
trunk/boost/interprocess/detail/atomic.hpp | 297 +++++++++++++++------------------------
trunk/boost/interprocess/detail/file_wrapper.hpp | 9 +
trunk/boost/interprocess/detail/managed_memory_impl.hpp | 85 ++++++++--
trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp | 26 ++
trunk/boost/interprocess/detail/workaround.hpp | 7
trunk/boost/interprocess/ipc/message_queue.hpp | 10
trunk/boost/interprocess/managed_mapped_file.hpp | 72 +++-----
trunk/boost/interprocess/managed_shared_memory.hpp | 32 ++++
trunk/boost/interprocess/managed_windows_shared_memory.hpp | 7
trunk/boost/interprocess/mapped_region.hpp | 13 +
trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 115 ++++++++++----
trunk/boost/interprocess/segment_manager.hpp | 7
trunk/boost/interprocess/shared_memory_object.hpp | 9
trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp | 6
trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp | 2
trunk/boost/interprocess/sync/named_condition.hpp | 29 ++-
trunk/boost/interprocess/sync/named_mutex.hpp | 25 ++-
trunk/boost/interprocess/sync/named_recursive_mutex.hpp | 12 +
trunk/boost/interprocess/sync/named_semaphore.hpp | 26 ++-
trunk/boost/interprocess/sync/named_upgradable_mutex.hpp | 12 +
trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 14 +
24 files changed, 501 insertions(+), 373 deletions(-)
Modified: trunk/boost/interprocess/containers/detail/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/tree.hpp (original)
+++ trunk/boost/interprocess/containers/detail/tree.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -671,7 +671,7 @@
iterator insert_equal(const value_type& v)
{
NodePtr p(AllocHolder::create_node(v));
- return iterator(this->icont().insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -679,14 +679,14 @@
iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
{
NodePtr p(AllocHolder::create_node(mv));
- return iterator(this->icont().insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
}
#else
template<class MovableConvertible>
iterator insert_equal(MovableConvertible &&mv)
{
NodePtr p(AllocHolder::create_node(forward<MovableConvertible>(mv)));
- return iterator(this->icont().insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
}
#endif
@@ -715,17 +715,11 @@
template <class InputIterator>
void insert_equal(InputIterator first, InputIterator last)
{
- if(this->empty()){
- //Insert with end hint, to achieve linear
- //complexity if [first, last) is ordered
- iterator end(this->end());
- for( ; first != last; ++first)
- this->insert_equal(end, *first);
- }
- else{
- for( ; first != last; ++first)
- this->insert_equal(*first);
- }
+ //Insert with end hint, to achieve linear
+ //complexity if [first, last) is ordered
+ iterator end(this->end());
+ for( ; first != last; ++first)
+ this->insert_equal(end, *first);
}
iterator erase(const_iterator position)
@@ -824,7 +818,7 @@
{}
void operator()(Node &n)
- { this->icont_.insert_equal_upper_bound(n); }
+ { this->icont_.insert_equal(this->icont_.end(), n); }
};
Modified: trunk/boost/interprocess/containers/list.hpp
==============================================================================
--- trunk/boost/interprocess/containers/list.hpp (original)
+++ trunk/boost/interprocess/containers/list.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -211,11 +211,12 @@
public:
//! Const iterator used to iterate through a list.
class const_iterator
+ /// @cond
: public std::iterator<std::bidirectional_iterator_tag,
value_type, list_difference_type,
list_const_pointer, list_const_reference>
{
- /// @cond
+
protected:
typename Icont::iterator m_it;
explicit const_iterator(typename Icont::iterator it) : m_it(it){}
@@ -225,7 +226,6 @@
private:
typename Icont::iterator get()
{ return this->m_it; }
- /// @endcond
public:
friend class list<T, A>;
@@ -262,13 +262,16 @@
bool operator!= (const const_iterator& r) const
{ return m_it != r.m_it; }
- };
+ }
+ /// @endcond
+ ;
//! Iterator used to iterate through a list
class iterator
+ /// @cond
: public const_iterator
{
- /// @cond
+
private:
explicit iterator(typename Icont::iterator it)
: const_iterator(it)
@@ -276,7 +279,6 @@
typename Icont::iterator get()
{ return this->m_it; }
- /// @endcond
public:
friend class list<T, A>;
@@ -302,7 +304,9 @@
iterator operator--(int)
{ iterator tmp = *this; --*this; return tmp; }
- };
+ }
+ /// @endcond
+ ;
//! Iterator used to iterate backwards through a list.
typedef std::reverse_iterator<iterator> reverse_iterator;
Modified: trunk/boost/interprocess/containers/slist.hpp
==============================================================================
--- trunk/boost/interprocess/containers/slist.hpp (original)
+++ trunk/boost/interprocess/containers/slist.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -226,11 +226,12 @@
public:
//! Const iterator used to iterate through a list.
class const_iterator
+ /// @cond
: public std::iterator<std::forward_iterator_tag,
value_type, list_difference_type,
list_const_pointer, list_const_reference>
{
- /// @cond
+
protected:
typename Icont::iterator m_it;
explicit const_iterator(typename Icont::iterator it) : m_it(it){}
@@ -239,7 +240,6 @@
private:
typename Icont::iterator get()
{ return this->m_it; }
- /// @endcond
public:
friend class slist<T, A>;
@@ -270,12 +270,16 @@
bool operator!= (const const_iterator& r) const
{ return m_it != r.m_it; }
- };
+ }
+ /// @endcond
+ ;
//! Iterator used to iterate through a list
- class iterator : public const_iterator
- {
+ class iterator
/// @cond
+ : public const_iterator
+ {
+
private:
explicit iterator(typename Icont::iterator it)
: const_iterator(it)
@@ -283,7 +287,6 @@
typename Icont::iterator get()
{ return this->m_it; }
- /// @endcond
public:
friend class slist<T, A>;
@@ -303,7 +306,9 @@
iterator operator++(int)
{ typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
- };
+ }
+ /// @endcond
+ ;
public:
//! <b>Effects</b>: Constructs a list taking the allocator as parameter.
Modified: trunk/boost/interprocess/detail/atomic.hpp
==============================================================================
--- trunk/boost/interprocess/detail/atomic.hpp (original)
+++ trunk/boost/interprocess/detail/atomic.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -1,23 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
-//! Copyright 2000-2005 The Apache Software Foundation or its licensors, as
-//! applicable.
-//!
-//! Licensed under the Apache License, Version 2.0 (the "License");
-//! you may not use this file except in compliance with the License.
-//! You may obtain a copy of the License at
-//!
-//! http://www.apache.org/licenses/LICENSE-2.0
-//!
-//! Unless required by applicable law or agreed to in writing, software
-//! distributed under the License is distributed on an "AS IS" BASIS,
-//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//! See the License for the specific language governing permissions and
-//! limitations under the License.
-//////////////////////////////////////////////////////////////////////////////
-//
-// This is a modified file (apr_atomic.c) of Apache APR project
//
-// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2006-2007. 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)
//
@@ -36,27 +19,11 @@
namespace interprocess{
namespace detail{
-//! Atomically add 'val' to an boost::uint32_t
-//! "mem": pointer to the object
-//! "val": amount to add
-//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val);
-
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val);
-
//! Atomically increment an apr_uint32_t by 1
//! "mem": pointer to the object
//! Returns the old value pointed to by mem
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem);
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem);
-
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem);
@@ -74,46 +41,23 @@
inline boost::uint32_t atomic_cas32
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp);
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val);
-
-/*
-//! Compare the pointer's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the pointer
-//! "with": what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of the pointer
-inline void *atomic_casptr(volatile void **mem, void *with, const void *cmp);
-*/
-
} //namespace detail{
} //namespace interprocess{
} //namespace boost{
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
-# include <boost/interprocess/detail/win32_api.hpp>
+#include <boost/interprocess/detail/win32_api.hpp>
namespace boost{
namespace interprocess{
namespace detail{
-//! Atomically add 'val' to an boost::uint32_t
-//! "mem": pointer to the object
-//! "val": amount to add
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
//! Returns the old value pointed to by mem
-inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return winapi::interlocked_exchange_add((volatile long*)mem, val); }
-
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ winapi::interlocked_exchange_add((volatile long*)mem, (boost::uint32_t)(-val)); }
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return winapi::interlocked_decrement((volatile long*)mem) + 1; }
//! Atomically increment an apr_uint32_t by 1
//! "mem": pointer to the object
@@ -121,12 +65,6 @@
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
{ return winapi::interlocked_increment((volatile long*)mem)-1; }
-//! Atomically decrement an boost::uint32_t by 1
-//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{ return winapi::interlocked_decrement((volatile long*)mem) != 0; }
-
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
{ return *mem; }
@@ -147,42 +85,42 @@
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
{ return winapi::interlocked_compare_exchange((volatile long*)mem, with, cmp); }
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return winapi::interlocked_exchange((volatile long*)mem, val); }
-/*
-//! Compare the pointer's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the pointer
-//! "with": what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of the pointer
-inline void *atomic_casptr(volatile void **mem, void *with, const void *cmp);
-{ return winapi::interlocked_compare_exchange_pointer(mem, with, cmp); }
-*/
} //namespace detail{
} //namespace interprocess{
} //namespace boost{
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-//#include <stdlib.h>
-
namespace boost {
namespace interprocess {
namespace detail{
-static boost::uint32_t inline intel_atomic_add32
- (volatile boost::uint32_t *mem, boost::uint32_t val)
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
+//! "mem": pointer to the value
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
+//! Returns the old value of *mem
+inline boost::uint32_t atomic_cas32
+ (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
{
- asm volatile ("lock; xaddl %0,%1"
- : "=r"(val), "=m"(*mem) // outputs
- : "0"(val), "m"(*mem) // inputs
+ boost::uint32_t prev = cmp;
+ asm volatile( "lock\n\t"
+ "cmpxchg %3,%1"
+ : "=a" (prev), "=m" (*(mem))
+ : "0" (prev), "r" (with)
: "memory", "cc");
- return val;
+ return prev;
+/*
+ boost::uint32_t prev;
+
+ asm volatile ("lock; cmpxchgl %1, %2"
+ : "=a" (prev)
+ : "r" (with), "m" (*(mem)), "0"(cmp));
+ asm volatile("" : : : "memory");
+
+ return prev;
+*/
}
//! Atomically add 'val' to an boost::uint32_t
@@ -191,77 +129,48 @@
//! Returns the old value pointed to by mem
inline boost::uint32_t atomic_add32
(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return intel_atomic_add32(mem, val); }
-
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
{
- asm volatile ("lock; subl %1, %0"
- :
- : "m" (*(mem)), "r" (val)
- : "memory", "cc");
+ // int r = *pw;
+ // *mem += val;
+ // return r;
+ int r;
+
+ asm volatile
+ (
+ "lock\n\t"
+ "xadd %1, %0":
+ "+m"( *mem ), "=r"( r ): // outputs (%0, %1)
+ "1"( val ): // inputs (%2 == %1)
+ "memory", "cc" // clobbers
+ );
+
+ return r;
+/*
+ asm volatile( "lock\n\t; xaddl %0,%1"
+ : "=r"(val), "=m"(*mem)
+ : "0"(val), "m"(*mem));
+ asm volatile("" : : : "memory");
+
+ return val;
+*/
}
//! Atomically increment an apr_uint32_t by 1
//! "mem": pointer to the object
//! Returns the old value pointed to by mem
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
-{ return intel_atomic_add32(mem, 1); }
+{ return atomic_add32(mem, 1); }
//! Atomically decrement an boost::uint32_t by 1
//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{
- unsigned char prev;
-
- asm volatile ("lock; decl %1;\n\t"
- "setnz %%al"
- : "=a" (prev)
- : "m" (*(mem))
- : "memory", "cc");
- return prev != 0;
-}
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, (boost::uint32_t)-1); }
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
{ return *mem; }
-//! Compare an boost::uint32_t's value with "cmp".
-//! If they are the same swap the value with "with"
-//! "mem": pointer to the value
-//! "with" what to swap it with
-//! "cmp": the value to compare it to
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_cas32
- (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{
- boost::uint32_t prev;
-
- asm volatile ("lock; cmpxchgl %1, %2"
- : "=a" (prev)
- : "r" (with), "m" (*(mem)), "0"(cmp)
- : "memory", "cc");
- return prev;
-}
-
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{
- boost::uint32_t prev = val;
-
- asm volatile ("lock; xchgl %0, %1"
- : "=r" (prev)
- : "m" (*(mem)), "0"(prev)
- : "memory");
- return prev;
-}
-
//! Atomically set an boost::uint32_t in memory
//! "mem": pointer to the object
//! "param": val value that the object will assume
@@ -310,7 +219,7 @@
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
{
boost::uint32_t prev;
-
+
asm volatile ("0:\n\t" // retry local label
"lwarx %0,0,%1\n\t" // load prev and reserve
"cmpw %0,%3\n\t" // does it match cmp?
@@ -327,11 +236,45 @@
return prev;
}
-//! Atomically subtract 'val' from an apr_uint32_t
+//! Atomically increment an apr_uint32_t by 1
+//! "mem": pointer to the object
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, 1); }
+
+//! Atomically decrement an boost::uint32_t by 1
+//! "mem": pointer to the atomic value
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, boost::uint32_t(-1u)); }
+
+//! Atomically read an boost::uint32_t from memory
+inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
+{ return *mem; }
+
+//! Atomically set an boost::uint32_t in memory
+//! "mem": pointer to the object
+//! "param": val value that the object will assume
+inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
+{ *mem = val; }
+
+} //namespace detail{
+} //namespace interprocess{
+} //namespace boost{
+
+#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+namespace boost {
+namespace interprocess {
+namespace detail{
+
+//! Atomically add 'val' to an boost::uint32_t
//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ atomic_add32(mem, boost::uint32_t(-val)); }
+//! "val": amount to add
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_add32
+ (volatile boost::uint32_t *mem, boost::uint32_t val)
+{ return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val); }
//! Atomically increment an apr_uint32_t by 1
//! "mem": pointer to the object
@@ -341,32 +284,29 @@
//! Atomically decrement an boost::uint32_t by 1
//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{ return 0 != (atomic_add32(mem, boost::uint32_t(-1u)) - 1u); }
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add32(mem, (boost::uint32_t)-1); }
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
{ return *mem; }
-//! Exchange an boost::uint32_t's value with "val".
+//! Compare an boost::uint32_t's value with "cmp".
+//! If they are the same swap the value with "with"
//! "mem": pointer to the value
-//! "val": what to swap it with
+//! "with" what to swap it with
+//! "cmp": the value to compare it to
//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{
- boost::uint32_t prev;
- do {
- prev = *mem;
- } while (atomic_cas32(mem, val, prev) != prev);
- return prev;
-}
+inline boost::uint32_t atomic_cas32
+ (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
+{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), with, cmp); }
//! Atomically set an boost::uint32_t in memory
//! "mem": pointer to the object
//! "param": val value that the object will assume
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ atomic_xchg32(mem, val); }
+{ *mem = val; }
} //namespace detail{
} //namespace interprocess{
@@ -397,12 +337,6 @@
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
{ return atomic_cas_32(reinterpret_cast<volatile ::uint32_t*>(mem), cmp, with); }
-//! Atomically subtract 'val' from an apr_uint32_t
-//! "mem": pointer to the object
-//! "val": amount to subtract
-inline void atomic_sub32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return atomic_add_32(reinterpret_cast<volatile ::uint32_t*>(mem), -val); }
-
//! Atomically increment an apr_uint32_t by 1
//! "mem": pointer to the object
//! Returns the old value pointed to by mem
@@ -411,21 +345,14 @@
//! Atomically decrement an boost::uint32_t by 1
//! "mem": pointer to the atomic value
-//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
-{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), -1) != 0; }
+//! Returns the old value pointed to by mem
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
+{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), (boost::uint32_t)-1) + 1; }
//! Atomically read an boost::uint32_t from memory
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
{ return *mem; }
-//! Exchange an boost::uint32_t's value with "val".
-//! "mem": pointer to the value
-//! "val": what to swap it with
-//! Returns the old value of *mem
-inline boost::uint32_t atomic_xchg32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ return atomic_swap_32(reinterpret_cast<volatile ::uint32_t*>(mem), val); }
-
//! Atomically set an boost::uint32_t in memory
//! "mem": pointer to the object
//! "param": val value that the object will assume
@@ -454,7 +381,7 @@
//! Atomically decrement an boost::uint32_t by 1
//! "mem": pointer to the atomic value
//! Returns false if the value becomes zero on decrement, otherwise true
-inline bool atomic_dec32(volatile boost::uint32_t *mem)
+inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
{ return __ATOMIC_DECREMENT_LONG(mem); }
// Rational for the implementation of the atomic read and write functions.
@@ -513,7 +440,7 @@
} //namespace boost{
#else
-
+
#error No atomic operations implemented for this platform, sorry!
#endif
Modified: trunk/boost/interprocess/detail/file_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/file_wrapper.hpp (original)
+++ trunk/boost/interprocess/detail/file_wrapper.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -86,7 +86,7 @@
//!Returns false on error. Never throws
static bool remove(const char *name);
- //!Sets the size of the fil
+ //!Sets the size of the file
void truncate(offset_t length);
//!Closes the
@@ -97,6 +97,10 @@
//!used in the constructor
const char *get_name() const;
+ //!Returns the name of the file
+ //!used in the constructor
+ bool get_size(offset_t &size) const;
+
//!Returns access mode
//!used in the constructor
mode_t get_mode() const;
@@ -126,6 +130,9 @@
inline const char *file_wrapper::get_name() const
{ return m_filename.c_str(); }
+inline bool file_wrapper::get_size(offset_t &size) const
+{ return get_file_size((file_handle_t)m_handle, size); }
+
inline void file_wrapper::swap(file_wrapper &other)
{
std::swap(m_handle, other.m_handle);
Added: trunk/boost/interprocess/detail/interprocess_tester.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/interprocess_tester.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007. 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_INTERPROCESS_TESTER_HPP
+#define BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
+
+namespace boost{
+namespace interprocess{
+namespace detail{
+
+class interprocess_tester
+{
+ public:
+ template<class T>
+ static void dont_close_on_destruction(T &t)
+ { t.dont_close_on_destruction(); }
+};
+
+} //namespace detail{
+} //namespace interprocess{
+} //namespace boost{
+
+#endif //#ifndef BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
+
Modified: trunk/boost/interprocess/detail/managed_memory_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_memory_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_memory_impl.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -22,6 +22,7 @@
#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
#include <boost/interprocess/sync/mutex_family.hpp>
#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
@@ -64,11 +65,11 @@
//!algorithm to place a named_allocator_algo, who takes care of name mappings.
//!The class can be customized with the char type used for object names
//!and the memory allocation algorithm to be used.*/
-template<
- class CharType,
- class MemoryAlgorithm,
- template<class IndexConfig> class IndexType
- >
+template < class CharType
+ , class MemoryAlgorithm
+ , template<class IndexConfig> class IndexType
+ , std::size_t Offset = 0
+ >
class basic_managed_memory_impl
{
//Non-copyable
@@ -103,11 +104,57 @@
private:
typedef basic_managed_memory_impl
- <CharType, MemoryAlgorithm, IndexType> self_t;
+ <CharType, MemoryAlgorithm, IndexType, Offset> self_t;
typedef typename
segment_manager::char_ptr_holder_t char_ptr_holder_t;
protected:
+ template<class ManagedMemory>
+ static bool grow(const char *filename, std::size_t extra_bytes)
+ {
+ typedef typename ManagedMemory::device_type device_type;
+ //Increase file size
+ try{
+ offset_t old_size;
+ {
+ device_type f(open_or_create, filename, read_write);
+ if(!f.get_size(old_size))
+ return false;
+ f.truncate(old_size + extra_bytes);
+ }
+ ManagedMemory managed_memory(open_only, filename);
+ //Grow always works
+ managed_memory.self_t::grow(extra_bytes);
+ }
+ catch(...){
+ return false;
+ }
+ return true;
+ }
+
+ template<class ManagedMemory>
+ static bool shrink_to_fit(const char *filename)
+ {
+ typedef typename ManagedMemory::device_type device_type;
+ std::size_t new_size, old_size;
+ try{
+ ManagedMemory managed_memory(open_only, filename);
+ old_size = managed_memory.get_size();
+ managed_memory.self_t::shrink_to_fit();
+ new_size = managed_memory.get_size();
+ }
+ catch(...){
+ return false;
+ }
+
+ //Decrease file size
+ {
+ device_type f(open_or_create, filename, read_write);
+ f.truncate(new_size);
+ }
+ return true;
+ }
+
//!Constructor. Allocates basic resources. Never throws.
basic_managed_memory_impl()
: mp_header(0){}
@@ -196,14 +243,17 @@
if(!mp_header) return false;
//Create memory
- return instream.read(detail::char_ptr_cast(mp_header),
- (std::streamsize)size).good();
+ return instream.read(detail::char_ptr_cast(this->get_address()),
+ (std::streamsize)this->get_size).good();
}
//!
void grow(std::size_t extra_bytes)
{ mp_header->grow(extra_bytes); }
+ void shrink_to_fit()
+ { mp_header->shrink_to_fit(); }
+
public:
//!Returns segment manager. Never throws.
@@ -212,11 +262,11 @@
//!Returns the base address of the memory in this process. Never throws.
void * get_address () const
- { return mp_header; }
+ { return (char*)mp_header - Offset; }
//!Returns the size of memory segment. Never throws.
std::size_t get_size () const
- { return mp_header->get_size(); }
+ { return mp_header->get_size() + Offset; }
//!Returns the number of free bytes of the memory
//!segment
@@ -241,7 +291,7 @@
//!Transforms an absolute address into an offset from base address.
//!The address must belong to the memory segment. Never throws.
handle_t get_handle_from_address (const void *ptr) const
- {
+ {
return detail::char_ptr_cast(ptr) -
detail::char_ptr_cast(this->get_address());
}
@@ -641,8 +691,8 @@
//!Never throws.
bool save_to_ostream (std::ostream &outstream)
{
- return outstream.write(char_ptr_cast(mp_header),
- (std::streamsize)get_size()).good();
+ return outstream.write(char_ptr_cast(this->get_address()),
+ (std::streamsize)this->get_size()).good();
}
//!Returns a constant iterator to the index storing the
@@ -696,15 +746,6 @@
{ return mp_header->get_deleter<T>(); }
protected:
- //!Sets the base address of the memory in this process.
- //!This is very low level, so use it only if you know what are
- //!you doing. Never throws.
- void set_base (void *addr)
- {
- assert(addr);
- mp_header = static_cast<segment_manager*>(addr);
- }
-
//!Swaps the segment manager's managed by this managed memory segment.
//!NOT thread-safe. Never throws.
void swap(basic_managed_memory_impl &other)
Modified: trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -18,12 +18,18 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/atomic.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/cstdint.hpp>
namespace boost {
namespace interprocess {
+
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
namespace detail {
template<class DeviceAbstraction, bool FileBased = true>
@@ -44,13 +50,11 @@
public:
- enum
- {
+ static const std::size_t
ManagedOpenOrCreateUserOffset =
detail::ct_rounded_size
< sizeof(boost::uint32_t)
- , detail::alignment_of<detail::max_align>::value>::value
- };
+ , detail::alignment_of<detail::max_align>::value>::value;
managed_open_or_create_impl(create_only_t,
const char *name,
@@ -178,12 +182,18 @@
~managed_open_or_create_impl()
{}
- std::size_t get_size() const
+ std::size_t get_user_size() const
{ return m_mapped_region.get_size() - ManagedOpenOrCreateUserOffset; }
- void *get_address() const
+ void *get_user_address() const
{ return (char*)m_mapped_region.get_address() + ManagedOpenOrCreateUserOffset; }
+ std::size_t get_real_size() const
+ { return m_mapped_region.get_size(); }
+
+ void *get_real_address() const
+ { return (char*)m_mapped_region.get_address(); }
+
void swap(managed_open_or_create_impl &other)
{
this->m_name.swap(other.m_name);
@@ -388,6 +398,10 @@
}
private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction()
+ { detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
+
mapped_region m_mapped_region;
std::string m_name;
};
Modified: trunk/boost/interprocess/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/detail/workaround.hpp (original)
+++ trunk/boost/interprocess/detail/workaround.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -26,6 +26,9 @@
#if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES - 0 > 0)
#define BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #if defined(__CYGWIN__)
+ #define BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK
+ #endif
#endif
#if ((defined _V6_ILP32_OFFBIG) &&(_V6_ILP32_OFFBIG - 0 > 0)) ||\
@@ -48,10 +51,6 @@
#define BOOST_INTERPROCESS_POSIX_TIMEOUTS
#endif
- #if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES - 0 > 0)
- #define BOOST_INTERPROCESS_POSIX_SEMAPHORES
- #endif
-
#endif
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
Modified: trunk/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- trunk/boost/interprocess/ipc/message_queue.hpp (original)
+++ trunk/boost/interprocess/ipc/message_queue.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -433,7 +433,7 @@
const void *buffer, std::size_t buffer_size,
unsigned int priority, const boost::posix_time::ptime &abs_time)
{
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
//Check if buffer is smaller than maximum allowed
if (buffer_size > p_hdr->m_max_msg_size) {
throw interprocess_exception(size_error);
@@ -517,7 +517,7 @@
std::size_t &recvd_size, unsigned int &priority,
const boost::posix_time::ptime &abs_time)
{
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
//Check if buffer is big enough for any message
if (buffer_size < p_hdr->m_max_msg_size) {
throw interprocess_exception(size_error);
@@ -586,18 +586,18 @@
inline std::size_t message_queue::get_max_msg() const
{
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
return p_hdr ? p_hdr->m_max_num_msg : 0; }
inline std::size_t message_queue::get_max_msg_size() const
{
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
return p_hdr ? p_hdr->m_max_msg_size : 0;
}
inline std::size_t message_queue::get_num_msg()
{
- detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_address());
+ detail::mq_hdr_t *p_hdr = static_cast<detail::mq_hdr_t*>(m_shmem.get_user_address());
if(p_hdr){
//---------------------------------------------
scoped_lock<interprocess_mutex> lock(p_hdr->m_mutex);
Modified: trunk/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- trunk/boost/interprocess/managed_mapped_file.hpp (original)
+++ trunk/boost/interprocess/managed_mapped_file.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -40,14 +40,20 @@
>
class basic_managed_mapped_file
: public detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType>
+ <CharType, AllocationAlgorithm, IndexType
+ ,detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset>
{
/// @cond
+ public:
+ typedef detail::basic_managed_memory_impl
+ <CharType, AllocationAlgorithm, IndexType,
+ detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset> base_t;
+ typedef detail::file_wrapper device_type;
+
private:
- typedef detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType> base_t;
typedef detail::create_open_func<base_t> create_open_func_t;
+ typedef detail::managed_open_or_create_impl<detail::file_wrapper> managed_open_or_create_type;
basic_managed_mapped_file *get_this_pointer()
{ return this; }
@@ -130,50 +136,28 @@
//!Tries to resize mapped file so that we have room for
//!more objects.
- //!WARNING: The memory mapping can change. To be able to use
- //!this function, all pointers constructed in this buffer
- //!must be offset pointers. Otherwise, the result is undefined.
- //!Returns true if the growth has been successful, so you will
- //!have some extra bytes to allocate new objects. If returns
- //!false, the heap allocation has failed.
-/*
- bool grow(std::size_t extra_bytes)
- {
- //If memory is reallocated, data will
- //be automatically copied
- std::size_t old_size = m_mfile.get_size();
- std::size_t new_size = old_size + extra_bytes;
- m_mfile.close();
- //Increase file size
- {
- std::ofstream file(m_filename.c_str(),
- std::ios::binary |std::ios::in | std::ios::out);
- if(!file){
- return false;
- }
- if(!file.seekp(static_cast<std::streamoff>(new_size - 1))){
- return false;
- }
- if(!file.write("", 1)){
- return false;
- }
- }
-
- if(!m_mfile.open(m_filename.c_str(), 0, new_size,
- (file_mapping::mode_t)read_write)){
- return false;
- }
-
- //Grow always works
- base_t::close_impl();
- base_t::open_impl(m_mfile.get_address(), new_size);
- base_t::grow(extra_bytes);
- return true;
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool grow(const char *filename, std::size_t extra_bytes)
+ {
+ return base_t::template grow
+ <basic_managed_mapped_file>(filename, extra_bytes);
}
-*/
+
+ //!Tries to resize mapped file to minimized the size of the file.
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool shrink_to_fit(const char *filename)
+ {
+ return base_t::template shrink_to_fit
+ <basic_managed_mapped_file>(filename);
+ }
+
/// @cond
private:
- detail::managed_open_or_create_impl<detail::file_wrapper> m_mfile;
+ managed_open_or_create_type m_mfile;
/// @endcond
};
Modified: trunk/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_shared_memory.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -40,12 +40,19 @@
template<class IndexConfig> class IndexType
>
class basic_managed_shared_memory
- : public detail::basic_managed_memory_impl <CharType, AllocationAlgorithm, IndexType>
+ : public detail::basic_managed_memory_impl
+ <CharType, AllocationAlgorithm, IndexType
+ ,detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset>
, private detail::managed_open_or_create_impl<shared_memory_object>
{
/// @cond
+ public:
+ typedef shared_memory_object device_type;
+
+ private:
typedef detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType> base_t;
+ <CharType, AllocationAlgorithm, IndexType,
+ detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset> base_t;
typedef detail::managed_open_or_create_impl
<shared_memory_object> base2_t;
@@ -129,6 +136,27 @@
base_t::swap(other);
base2_t::swap(other);
}
+
+ //!Tries to resize the managed shared memory object so that we have
+ //!room for more objects.
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool grow(const char *filename, std::size_t extra_bytes)
+ {
+ return base_t::template grow
+ <basic_managed_shared_memory>(filename, extra_bytes);
+ }
+
+ //!Tries to resize the managed shared memory to minimized the size of the file.
+ //!
+ //!This function is not synchronized so no other thread or process should
+ //!be reading or writing the file
+ static bool shrink_to_fit(const char *filename)
+ {
+ return base_t::template shrink_to_fit
+ <basic_managed_shared_memory>(filename);
+ }
};
} //namespace interprocess {
Modified: trunk/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_windows_shared_memory.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -48,13 +48,14 @@
>
class basic_managed_windows_shared_memory
: public detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType>
+ <CharType, AllocationAlgorithm, IndexType
+ ,detail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset>
{
/// @cond
private:
typedef detail::basic_managed_memory_impl
- <CharType, AllocationAlgorithm, IndexType> base_t;
-
+ <CharType, AllocationAlgorithm, IndexType,
+ detail::managed_open_or_create_impl<windows_shared_memory>::ManagedOpenOrCreateUserOffset> base_t;
typedef detail::create_open_func<base_t> create_open_func_t;
basic_managed_windows_shared_memory *get_this_pointer()
Modified: trunk/boost/interprocess/mapped_region.hpp
==============================================================================
--- trunk/boost/interprocess/mapped_region.hpp (original)
+++ trunk/boost/interprocess/mapped_region.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -42,6 +42,10 @@
namespace boost {
namespace interprocess {
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
//!The mapped_region class represents a portion or region created from a
//!memory_mappable object.
class mapped_region
@@ -133,6 +137,9 @@
#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
file_handle_t m_file_mapping_hnd;
#endif
+
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
/// @endcond
};
@@ -356,6 +363,9 @@
#endif
}
+inline void mapped_region::dont_close_on_destruction()
+{}
+
#else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
inline mapped_region::mapped_region()
@@ -503,6 +513,9 @@
}
}
+inline void mapped_region::dont_close_on_destruction()
+{ m_base = MAP_FAILED; }
+
#endif //##if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
template<int dummy>
Modified: trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -29,7 +29,6 @@
#include <boost/interprocess/detail/math_functions.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <boost/intrusive/set.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <algorithm>
@@ -40,6 +39,14 @@
#include <assert.h>
#include <new>
+//#define BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
+
+#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
+#include <boost/intrusive/set.hpp>
+#else
+#include <boost/intrusive/splay_set.hpp>
+#endif
+
//!\file
//!Describes a best-fit algorithm based in an intrusive red-black tree used to allocate
//!objects in shared memory. This class is intended as a base class for single segment
@@ -77,9 +84,13 @@
typedef typename detail::
pointer_to_other<void_pointer, char>::type char_ptr;
+#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
typedef typename bi::make_set_base_hook
+#else
+ typedef typename bi::make_splay_set_base_hook
+#endif
< bi::void_pointer<VoidPointer>
- , bi::link_mode<bi::normal_link> >::type TreeHook;
+ , bi::link_mode<bi::normal_link> >::type TreeHook;
typedef detail::multi_allocation_next<void_pointer> multi_allocation_next_t;
typedef typename multi_allocation_next_t::
@@ -119,8 +130,13 @@
//!Shared interprocess_mutex to protect memory allocate/deallocate
typedef typename MutexFamily::mutex_type interprocess_mutex;
+#ifndef BOOST_INTERPROCESS_RBTREE_BEST_FIT_USE_SPLAY
typedef typename bi::make_multiset
+#else
+ typedef typename bi::make_splay_multiset
+#endif
<block_ctrl, bi::base_hook<TreeHook> >::type Imultiset;
+
typedef typename Imultiset::iterator imultiset_iterator;
//!This struct includes needed data and derives from
@@ -186,13 +202,18 @@
//!This function is normally used for security reasons.
void zero_free_memory();
- //!Increases managed memory in extra_size bytes more
+ //!Increases managed memory in
+ //!extra_size bytes more
void grow(std::size_t extra_size);
+ //!Decreases managed memory as much as possible
+ void shrink_to_fit();
+
//!Returns true if all allocated memory has been deallocated
bool all_memory_deallocated();
- //!Makes an internal sanity check and returns true if success
+ //!Makes an internal sanity check
+ //!and returns true if success
bool check_sanity();
template<class T>
@@ -380,6 +401,57 @@
}
template<class MutexFamily, class VoidPointer>
+void rbtree_best_fit<MutexFamily, VoidPointer>::shrink_to_fit()
+{
+ //Get the address of the first block
+ std::size_t block1_off =
+ algo_impl_t::multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
+
+ block_ctrl *first_block = reinterpret_cast<block_ctrl *>
+ (detail::char_ptr_cast(this) + block1_off);
+ block_ctrl *old_end_block = priv_prev_block(first_block);
+ assert(priv_is_allocated_block(old_end_block));
+ assert(old_end_block->m_end);
+ std::size_t old_end_block_size = old_end_block->m_size;
+
+ block_ctrl *last_block = priv_prev_block(old_end_block);
+
+ void *unique_block = 0;
+ if(last_block == first_block){
+ std::size_t ignore;
+ unique_block = priv_allocate(allocate_new, 0, 0, ignore).first;
+ if(!unique_block)
+ return;
+ last_block = priv_prev_block(old_end_block);
+ }
+
+ //The last block must be free to be able to shrink
+ if(priv_is_allocated_block(last_block))
+ return;
+
+ std::size_t last_block_size = last_block->m_size;
+
+ //Update managed buffer's size
+ m_header.m_size -= last_block->m_size*Alignment;
+
+ //Erase block from the free tree, since we will erase it
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*last_block));
+
+ std::size_t shrunk_border_offset = (detail::char_ptr_cast(last_block) -
+ detail::char_ptr_cast(this)) + EndCtrlBlockBytes;
+
+ block_ctrl *new_end_block = last_block;
+ priv_mark_as_allocated_block(new_end_block);
+ new_end_block->m_end = 1;
+ new_end_block->m_size = old_end_block_size + last_block_size;
+ priv_tail_size(new_end_block, new_end_block->m_size);
+ assert(priv_prev_block(first_block) == new_end_block);
+ assert(shrunk_border_offset == m_header.m_size);
+ if(unique_block)
+ priv_deallocate(unique_block);
+}
+
+template<class MutexFamily, class VoidPointer>
void rbtree_best_fit<MutexFamily, VoidPointer>::
priv_add_segment(void *addr, std::size_t size)
{
@@ -419,7 +491,6 @@
//Check that the alignment is power of two (we use some optimizations based on this)
//assert((Alignment % 2) == 0);
-
//Insert it in the intrusive containers
m_header.m_imultiset.insert(*first_big_block);
}
@@ -507,7 +578,8 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
std::size_t ignore;
- return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ void * ret = priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ return ret;
}
template<class MutexFamily, class VoidPointer>
@@ -984,38 +1056,7 @@
{
std::size_t upper_nunits = nunits + BlockCtrlUnits;
imultiset_iterator it_old = Imultiset::s_iterator_to(*block);
-/*
- if (block->m_size >= upper_nunits){
- //Now we have to update the data in the tree
- m_header.m_imultiset.erase(ittree);
- //This block is bigger than needed, split it in
- //two blocks, the first's size will be "units" and
- //the second's size "block->m_size-units"
- std::size_t block_old_size = block->m_size;
- block->m_size = nunits;
- assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, block->m_size);
-
- //This is the remaining block
- block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + Alignment*nunits))block_ctrl;
- new_block->m_size = block_old_size - nunits;
- assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_free_block(new_block);
-
- //Insert the new block in the container
- m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *new_block);
- }
- else if (block->m_size >= nunits){
- m_header.m_imultiset.erase(ittree);
- }
- else{
- assert(0);
- return 0;
- }
-*/
if (block->m_size >= upper_nunits){
//This block is bigger than needed, split it in
//two blocks, the first's size will be "units" and
Modified: trunk/boost/interprocess/segment_manager.hpp
==============================================================================
--- trunk/boost/interprocess/segment_manager.hpp (original)
+++ trunk/boost/interprocess/segment_manager.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -195,10 +195,15 @@
{ MemoryAlgorithm::deallocate(addr); }
//!Increases managed memory in extra_size bytes more. This only works
- //!with single-segment management*
+ //!with single-segment management.
void grow(std::size_t extra_size)
{ MemoryAlgorithm::grow(extra_size); }
+ //!Decreases managed memory to the minimum. This only works
+ //!with single-segment management.
+ void shrink_to_fit()
+ { MemoryAlgorithm::shrink_to_fit(); }
+
//!Returns the result of "all_memory_deallocated()" function
//!of the used memory algorithm
bool all_memory_deallocated()
Modified: trunk/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- trunk/boost/interprocess/shared_memory_object.hpp (original)
+++ trunk/boost/interprocess/shared_memory_object.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -20,8 +20,6 @@
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <cstddef>
-
-
#include <string>
#ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
@@ -124,6 +122,10 @@
//!Returns the name of the file.
const char *get_name() const;
+ //!Returns the name of the file
+ //!used in the constructor
+ bool get_size(offset_t &size) const;
+
//!Returns access mode
mode_t get_mode() const;
@@ -156,6 +158,9 @@
inline const char *shared_memory_object::get_name() const
{ return m_filename.c_str(); }
+inline bool shared_memory_object::get_size(offset_t &size) const
+{ return detail::get_file_size((file_handle_t)m_handle, size); }
+
inline void shared_memory_object::swap(shared_memory_object &other)
{
std::swap(m_handle, other.m_handle);
Modified: trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -68,14 +68,14 @@
}
}
- bool ref_release() // nothrow
- { return !detail::atomic_dec32( &use_count_ ); }
+ bool ref_release() // nothrow
+ { return 1 == detail::atomic_dec32( &use_count_ ); }
void weak_add_ref() // nothrow
{ detail::atomic_inc32( &weak_count_ ); }
bool weak_release() // nothrow
- { return !detail::atomic_dec32( &weak_count_ ); }
+ { return 1 == detail::atomic_dec32( &weak_count_ ); }
long use_count() const // nothrow
{ return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }
Modified: trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -167,7 +167,7 @@
else{
//If it is a NOTIFY_ALL command, all threads should return
//from do_timed_wait function. Decrement wait count.
- unlock_enter_mut = !detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
+ unlock_enter_mut = 1 == detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
//Check if this is the last thread of notify_all waiters
//Only the last thread will release the interprocess_mutex
if(unlock_enter_mut){
Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp (original)
+++ trunk/boost/interprocess/sync/named_condition.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -24,7 +24,7 @@
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#endif
@@ -34,9 +34,12 @@
//!Describes process-shared variables interprocess_condition class
namespace boost {
-
namespace interprocess {
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
class named_condition
{
/// @cond
@@ -116,17 +119,17 @@
interprocess_condition cond_;
//If named_mutex is implemented using semaphores
//we need to store an additional mutex
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
interprocess_mutex mutex_;
#endif
};
interprocess_condition *condition() const
- { return &static_cast<condition_holder*>(m_shmem.get_address())->cond_; }
+ { return &static_cast<condition_holder*>(m_shmem.get_user_address())->cond_; }
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
interprocess_mutex *mutex() const
- { return &static_cast<condition_holder*>(m_shmem.get_address())->mutex_; }
+ { return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; }
template <class Lock>
void do_wait(Lock& lock)
@@ -146,7 +149,10 @@
lock.lock();
return r;
}
- #endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #endif
+
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
@@ -188,7 +194,10 @@
,construct_func_t(detail::DoOpen))
{}
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+inline void named_condition::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
+#if defined BOOST_INTERPROCESS_POSIX_SEMAPHORES && defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
inline void named_condition::notify_one()
{
@@ -243,7 +252,7 @@
return true;
}
-#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#else
inline void named_condition::notify_one()
{ this->condition()->notify_one(); }
@@ -293,7 +302,7 @@
return true;
}
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#endif
inline bool named_condition::remove(const char *name)
{ return shared_memory_object::remove(name); }
Modified: trunk/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_mutex.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -20,8 +20,9 @@
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
#include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
#else
#include <boost/interprocess/shared_memory_object.hpp>
@@ -34,7 +35,6 @@
//!Describes a named mutex class for inter-process synchronization
namespace boost {
-
namespace interprocess {
class named_condition;
@@ -103,11 +103,14 @@
/// @cond
private:
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
+ #if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
detail::named_semaphore_wrapper m_sem;
- #else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #else
interprocess_mutex *mutex() const
- { return static_cast<interprocess_mutex*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_mutex*>(m_shmem.get_user_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
typedef detail::named_creation_functor<interprocess_mutex> construct_func_t;
@@ -117,7 +120,7 @@
/// @cond
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
inline named_mutex::named_mutex(create_only_t, const char *name)
: m_sem(detail::DoCreate, name, read_write, 1)
@@ -131,6 +134,9 @@
: m_sem(detail::DoOpen, name, read_write, 1)
{}
+inline void named_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_sem); }
+
inline named_mutex::~named_mutex()
{}
@@ -149,7 +155,10 @@
inline bool named_mutex::remove(const char *name)
{ return detail::named_semaphore_wrapper::remove(name); }
-#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#else
+
+inline void named_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
inline named_mutex::~named_mutex()
{}
@@ -199,7 +208,7 @@
inline bool named_mutex::remove(const char *name)
{ return shared_memory_object::remove(name); }
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#endif
/// @endcond
Modified: trunk/boost/interprocess/sync/named_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_recursive_mutex.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -31,6 +31,10 @@
namespace boost {
namespace interprocess {
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
//!A recursive mutex with a global name, so it can be found from different
//!processes. This mutex can't be placed in shared memory, and
//!each process should have it's own named_recursive_mutex.
@@ -93,8 +97,11 @@
/// @cond
private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
interprocess_recursive_mutex *mutex() const
- { return static_cast<interprocess_recursive_mutex*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_recursive_mutex*>(m_shmem.get_user_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
typedef detail::named_creation_functor<interprocess_recursive_mutex> construct_func_t;
@@ -104,6 +111,9 @@
inline named_recursive_mutex::~named_recursive_mutex()
{}
+inline void named_recursive_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
inline named_recursive_mutex::named_recursive_mutex(create_only_t, const char *name)
: m_shmem (create_only
,name
Modified: trunk/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/named_semaphore.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -1,4 +1,4 @@
-//////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -19,9 +19,10 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/interprocess_tester.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
#include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
#else
#include <boost/interprocess/shared_memory_object.hpp>
@@ -103,11 +104,14 @@
/// @cond
private:
- #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
+ #if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
detail::named_semaphore_wrapper m_sem;
- #else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #else
interprocess_semaphore *semaphore() const
- { return static_cast<interprocess_semaphore*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_semaphore*>(m_shmem.get_user_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
typedef detail::named_creation_functor<interprocess_semaphore, int> construct_func_t;
@@ -117,7 +121,7 @@
/// @cond
-#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES) && !defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES_NO_UNLINK)
inline named_semaphore::named_semaphore
(create_only_t, const char *name, int initialCount)
@@ -137,6 +141,9 @@
inline named_semaphore::~named_semaphore()
{}
+inline void named_semaphore::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_sem); }
+
inline void named_semaphore::wait()
{ m_sem.wait(); }
@@ -152,11 +159,14 @@
inline bool named_semaphore::remove(const char *name)
{ return detail::named_semaphore_wrapper::remove(name); }
-#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#else
inline named_semaphore::~named_semaphore()
{}
+inline void named_semaphore::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
inline named_semaphore::named_semaphore
(create_only_t, const char *name, int initialCount)
: m_shmem (create_only
@@ -205,7 +215,7 @@
inline bool named_semaphore::remove(const char *name)
{ return shared_memory_object::remove(name); }
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#endif
/// @endcond
Modified: trunk/boost/interprocess/sync/named_upgradable_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_upgradable_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_upgradable_mutex.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -31,6 +31,10 @@
namespace boost {
namespace interprocess {
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
class named_condition;
//!A upgradable mutex with a global name, so it can be found from different
@@ -218,8 +222,11 @@
/// @cond
private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction();
+
interprocess_upgradable_mutex *mutex() const
- { return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_address()); }
+ { return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_user_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
typedef detail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
@@ -262,6 +269,9 @@
,construct_func_t(detail::DoOpen))
{}
+inline void named_upgradable_mutex::dont_close_on_destruction()
+{ detail::interprocess_tester::dont_close_on_destruction(m_shmem); }
+
inline void named_upgradable_mutex::lock()
{ this->mutex()->lock(); }
Modified: trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp (original)
+++ trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2007-10-21 05:01:16 EDT (Sun, 21 Oct 2007)
@@ -26,6 +26,11 @@
namespace boost {
namespace interprocess {
+
+/// @cond
+namespace detail{ class interprocess_tester; }
+/// @endcond
+
namespace detail {
inline bool semaphore_open
@@ -206,7 +211,10 @@
{ semaphore_open(mp_sem, type, name, mode, count); }
~named_semaphore_wrapper()
- { semaphore_close(mp_sem); }
+ {
+ if(mp_sem != SEM_FAILED)
+ semaphore_close(mp_sem);
+ }
void post()
{ semaphore_post(mp_sem); }
@@ -224,6 +232,10 @@
{ return semaphore_unlink(name); }
private:
+ friend class detail::interprocess_tester;
+ void dont_close_on_destruction()
+ { mp_sem = SEM_FAILED; }
+
sem_t *mp_sem;
};
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk