Update of /cvsroot/boost/boost/boost/interprocess/mem_algo/detail
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv17930/mem_algo/detail
Modified Files:
simple_seq_fit_impl.hpp
Log Message:
Changes for official inclusion in the regression tests
Index: simple_seq_fit_impl.hpp
===================================================================
RCS file:
/cvsroot/boost/boost/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- simple_seq_fit_impl.hpp 7 Aug 2006 14:01:54 -0000 1.2
+++ simple_seq_fit_impl.hpp 4 May 2007 20:53:10 -0000 1.3
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztañaga 2005-2006. Distributed under the Boost
+// (C) Copyright Ion Gaztañaga 2005-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)
//
@@ -24,12 +24,12 @@
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/multi_segment_services.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <algorithm>
#include <utility>
+#include <cstring>
#include <assert.h>
#include <new>
@@ -143,20 +143,21 @@
/*!Makes an internal sanity check and returns true if success*/
bool check_sanity();
+ //!Initializes to zero all the memory that's not in use.
+ //!This function is normally used for security reasons.
+ void clear_free_memory();
+
std::pair<void *, bool>
allocation_command (allocation_type command, std::size_t limit_size,
std::size_t preferred_size,std::size_t
&received_size,
- void *reuse_ptr = 0);
+ void *reuse_ptr = 0, std::size_t backwards_multiple
= 1);
/*!Returns the size of the buffer previously allocated pointed by ptr*/
std::size_t size(void *ptr) const;
- /*!Allocates bytes, if there is no more memory, it executes functor
- f(std::size_t) to allocate a new segment to manage. The functor returns
- std::pair<void*, std::size_t> indicating the base address and size of
- the new segment. If the new segment can't be allocated, allocate
- it will return 0.*/
- void* multi_allocate(std::size_t nbytes);
+ /*!Allocates aligned bytes, returns 0 if there is not more memory.
+ Alignment must be power of 2*/
+ void* allocate_aligned (std::size_t nbytes, std::size_t alignment);
private:
/*!Real allocation algorithm with min allocation option*/
@@ -191,6 +192,9 @@
,std::size_t max_size, std::size_t preferred_size
,std::size_t &received_size);
+ //!Real private aligned allocation function
+ void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment);
+
/*!Checks if block has enough memory and splits/unlinks the block
returning the address to the users*/
void* priv_check_and_allocate(std::size_t units
@@ -207,6 +211,9 @@
enum { BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl),
Alignment>::value };
enum { BlockCtrlSize = BlockCtrlBytes/Alignment };
enum { MinBlockSize = BlockCtrlSize + Alignment };
+
+ public:
+ enum { PayloadPerAllocation = BlockCtrlBytes };
};
template<class MutexFamily, class VoidPointer>
@@ -299,6 +306,25 @@
}
template<class MutexFamily, class VoidPointer>
+inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::clear_free_memory()
+{
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ block_ctrl *block = detail::get_pointer(m_header.m_root.m_next);
+
+ //Iterate through all free portions
+ do{
+ //Just clear user the memory part reserved for the user
+ std::memset( detail::char_ptr_cast(block) + BlockCtrlBytes
+ , 0
+ , block->m_size*Alignment - BlockCtrlBytes);
+ block = detail::get_pointer(block->m_next);
+ }
+ while(block != &m_header.m_root);
+}
+
+template<class MutexFamily, class VoidPointer>
inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
check_sanity()
{
@@ -345,14 +371,28 @@
}
template<class MutexFamily, class VoidPointer>
+inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
+ allocate_aligned(std::size_t nbytes, std::size_t alignment)
+{
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ return priv_allocate_aligned(nbytes, alignment);
+}
+
+template<class MutexFamily, class VoidPointer>
inline std::pair<void *, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
allocation_command (allocation_type command, std::size_t min_size,
std::size_t preferred_size,std::size_t &received_size,
- void *reuse_ptr)
+ void *reuse_ptr, std::size_t backwards_multiple)
{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
+ (void)backwards_multiple;
+ command &= ~expand_bwd;
+ if(!command)
+ return std::pair<void *, bool>(0, false);
return priv_allocate(command, min_size, preferred_size, received_size,
reuse_ptr);
}
@@ -369,43 +409,6 @@
}
template<class MutexFamily, class VoidPointer>
-inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
- multi_allocate(std::size_t nbytes)
-{
- //-----------------------
- boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
- //-----------------------
- //Multisegment pointer. Let's try first the normal allocation
- //since it's faster.
- std::size_t ignore;
- void *addr = this->priv_allocate(allocate_new, nbytes, nbytes,
ignore).first;
- if(!addr){
- //If this fails we will try the allocation through the segment
- //creator.
- std::size_t group, id;
- //Obtain the segment group of this segment
- void_pointer::get_group_and_id(this, group, id);
- if(group == 0){
- //Ooops, group 0 is not valid.
- return 0;
- }
- //Now obtain the polymorphic functor that creates
- //new segments and try to allocate again.
- boost::interprocess::multi_segment_services *p_services =
- static_cast<boost::interprocess::multi_segment_services*>
- (void_pointer::find_group_data(group));
- assert(p_services);
- std::pair<void *, std::size_t> ret =
- p_services->create_new_segment(MinBlockSize > nbytes ? MinBlockSize :
nbytes);
- if(ret.first){
- priv_add_segment(ret.first, ret.second);
- addr = this->priv_allocate(allocate_new, nbytes, nbytes,
ignore).first;
- }
- }
- return addr;
-}
-
-template<class MutexFamily, class VoidPointer>
void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_expand_both_sides(allocation_type command
,std::size_t min_size
@@ -748,6 +751,56 @@
return true;
}
+template<class MutexFamily, class VoidPointer>
+inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
+ priv_allocate_aligned(std::size_t nbytes, std::size_t alignment)
+{
+ //Ensure power of 2
+ if ((alignment & (alignment - std::size_t(1u))) != 0){
+ //Alignment is not power of two
+ assert((alignment & (alignment - std::size_t(1u))) != 0);
+ return 0;
+ }
+
+ std::size_t ignore;
+ if(alignment <= Alignment){
+ return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
+ }
+
+ std::size_t request =
+ nbytes + alignment + MinBlockSize*Alignment - BlockCtrlBytes;
+ void *buffer = priv_allocate(allocate_new, request, request, ignore).first;
+ if(!buffer)
+ return 0;
+ else if ((((std::size_t)(buffer)) % alignment) == 0)
+ return buffer;
+
+ char *aligned_portion = (char*)
+ ((std::size_t)((char*)buffer + alignment - 1) & -alignment);
+
+ char *pos = ((aligned_portion - (char*)buffer) >= (MinBlockSize*Alignment))
?
+ aligned_portion : (aligned_portion + alignment);
+
+
+ block_ctrl *first = reinterpret_cast<block_ctrl*>
+ (detail::char_ptr_cast(buffer) - BlockCtrlBytes);
+
+ block_ctrl *second = reinterpret_cast<block_ctrl*>
+ (detail::char_ptr_cast(pos) - BlockCtrlBytes);
+
+ std::size_t old_size = first->m_size;
+
+ first->m_size = ((char*)second - (char*)first)/Alignment;
+ second->m_size = old_size - first->m_size;
+
+ //Write control data to simulate this new block was previously allocated
+ second->m_next = 0;
+
+ //Now deallocate the new block to insert it in the free list
+ this->priv_deallocate(detail::char_ptr_cast(first) + BlockCtrlBytes);
+ return detail::char_ptr_cast(second) + BlockCtrlBytes;
+}
+
template<class MutexFamily, class VoidPointer> inline
void* simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_check_and_allocate
(std::size_t nunits
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs