|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r56280 - in sandbox/stm/branches/vbe/boost/stm: . detail
From: vicente.botet_at_[hidden]
Date: 2009-09-17 16:59:45
Author: viboes
Date: 2009-09-17 16:59:44 EDT (Thu, 17 Sep 2009)
New Revision: 56280
URL: http://svn.boost.org/trac/boost/changeset/56280
Log:
TBoost.Stm vbe
* Changing UNASSIGNED_COPY by MEMCOPY and uinitialized_copy by memcpy
* Adding clone virtual function and changing cache_new_copy calls by clone()
* removing get_transaction calls
* addind opacity on rd_ptr
* adding transactional_reference_cache and the associated non_tx_rd_ptr (non tested DRAFT)
Text files modified:
sandbox/stm/branches/vbe/boost/stm/base_transaction.hpp | 105 +++++++++++++++++++++++++++++++++++++--
sandbox/stm/branches/vbe/boost/stm/detail/config.hpp | 10 +-
sandbox/stm/branches/vbe/boost/stm/detail/transaction_impl.hpp | 2
sandbox/stm/branches/vbe/boost/stm/detail/tx_ptr.hpp | 85 +++++++++++++++++++++++++++++++-
sandbox/stm/branches/vbe/boost/stm/transaction.hpp | 44 +++++-----------
5 files changed, 202 insertions(+), 44 deletions(-)
Modified: sandbox/stm/branches/vbe/boost/stm/base_transaction.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/base_transaction.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/base_transaction.hpp 2009-09-17 16:59:44 EDT (Thu, 17 Sep 2009)
@@ -186,7 +186,7 @@
// transactional objets must specialize the pure virtual functions
// copy_state(base_transaction_object const * const rhs)
// move_state(base_transaction_object * rhs) if BUILD_MOVE_SEMANTICS
-// cache_deallocate() if BOOST_STM_USE_UNASIGNED_COPY
+// cache_deallocate() if BOOST_STM_USE_MEMCOPY
// copy_state is used to copy the backup/working copy to the shared transactional object when the roolback/commit is done direct/defered policy is used
// move_state is used to move the backup/working copy to the shared transactional object when the roolback/commit is done direct/defered policy is used
// cache_deallocate is used to release the backup/working copy when the transaction ends if direct/defered policy is used
@@ -214,6 +214,7 @@
{}
#endif
+ virtual base_transaction_object* clone() const = 0;
virtual void copy_state(base_transaction_object const * const rhs) = 0;
#if BUILD_MOVE_SEMANTICS
virtual void move_state(base_transaction_object * rhs) = 0;
@@ -221,7 +222,7 @@
virtual void move_state(base_transaction_object * rhs) {};
#endif
virtual ~base_transaction_object() {};
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
virtual void cache_deallocate()=0;
#endif
@@ -304,12 +305,22 @@
// move_state and
// cache_deallocate: relaying on the cache_restore<T> generic function
// Defines in addition the functions new and delete when USE_STM_MEMORY_MANAGER is defined
+
+// The parameter Base=base_transaction_object allows to mic transaction_object and polymorphism
+// class B : transaction_object<B> {}
+// class D : transaction_object<D, B> {}
+// the single issue is the forward constructors from transaction_object<D, B> to B
//-----------------------------------------------------------------------------
-template <class Derived>
+template <class Derived, typename Base=base_transaction_object>
class transaction_object : public base_transaction_object
{
public:
+ //--------------------------------------------------------------------------
+ virtual base_transaction_object* clone() const {
+ return cache_new_copy(*this);
+ }
+
//--------------------------------------------------------------------------
virtual void copy_state(base_transaction_object const * const rhs)
{
@@ -324,7 +335,7 @@
}
#endif
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
virtual void cache_deallocate() {
boost::stm::cache_deallocate(this);
}
@@ -452,12 +463,17 @@
return *this;
}
+ virtual base_transaction_object* clone() const {
+ return cache_new_copy(*this);
+ }
+
virtual void copy_state(base_transaction_object const * const rhs) {
cache_restore(static_cast<transactional_object<T> const * const>(rhs),
- static_cast<transactional_object<T> *>(this));
+ //static_cast<transactional_object<T> *>(this));
+ this);
}
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
virtual void cache_deallocate() {
boost::stm::cache_deallocate(this);
}
@@ -503,6 +519,83 @@
return tx_up_cast(p);
}
+//-----------------------------------------------------------------------------
+// This class defines the transactional cache of a non transactional variable.
+// There is a map from the address of the variable of type T to an instance of this class
+//
+//-----------------------------------------------------------------------------
+
+template <typename T>
+class transactional_reference_cache : public base_transaction_object {
+public:
+ T* const value_;
+ mutable T* ptr_;
+
+ transactional_reference_cache(T& ref)
+ : base_transaction_object()
+ , value_(&ref), ptr_(0) {}
+
+ transactional_reference_cache(T* ptr)
+ : base_transaction_object()
+ , value_(ptr), ptr_(0) {}
+
+ ~transactional_reference_cache() {
+ delete ptr_;
+ }
+ T* get() const {
+ if(ptr_!=0) return ptr_;
+ else return value_;
+ }
+
+ virtual base_transaction_object* clone() const {
+ transactional_reference_cache tmp = cache_new_copy(*this);
+ if (tmp.value!=0) {
+ tmp.ptr_ = new T(*value_);
+ }
+ return tmp;
+ }
+
+ virtual void copy_state(base_transaction_object const * const rhs) {
+ if (value_==0) return;
+ *value_= *(static_cast<transactional_reference_cache<T> const * const>(rhs)->ptr_);
+ delete ptr_;
+ ptr_=0;
+ }
+
+#ifdef BOOST_STM_USE_MEMCOPY
+ virtual void cache_deallocate() {
+ delete ptr_;
+ ptr_=0;
+ boost::stm::cache_deallocate(this);
+ }
+#endif
+
+#if USE_STM_MEMORY_MANAGER
+ void* operator new(size_t size) throw ()
+ {
+ return retrieve_mem(size);
+ }
+
+ void operator delete(void* mem)
+ {
+ return_mem(mem, sizeof(transactional_object<T>));
+ }
+#endif
+
+private:
+ transactional_reference_cache(transactional_reference_cache<T> const & r)
+ : base_transaction_object(r)
+ , value_(r.value_), ptr_(r.ptr_) {}
+
+
+ transactional_reference_cache & operator=(transactional_reference_cache const & r)
+ {
+ value_ = r.value_;
+ ptr_ = r.ptr_;
+ return *this;
+ }
+
+};
//-----------------------------------------------------------------------------
class base_contention_manager
Modified: sandbox/stm/branches/vbe/boost/stm/detail/config.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/detail/config.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/detail/config.hpp 2009-09-17 16:59:44 EDT (Thu, 17 Sep 2009)
@@ -19,7 +19,7 @@
//#define PERFORMING_VALIDATION 1
#define PERFORMING_LATM 1
#define PERFORMING_COMPOSITION 1
-#define USE_STM_MEMORY_MANAGER 1
+//#define USE_STM_MEMORY_MANAGER 1
#define BUILD_MOVE_SEMANTICS 0
#define USING_TRANSACTION_SPECIFIC_LATM 1
#define USE_BLOOM_FILTER 1
@@ -31,12 +31,12 @@
#define BOOST_STM_TX_CONTAINS_REFERENCES_TO_TSS_FIELDS 1
// BOOST_STM_CM_STATIC_CONF: configuration manager is static
-//#define BOOST_STM_CM_STATIC_CONF 1
+#define BOOST_STM_CM_STATIC_CONF 1
// BOOST_STM_CM_STATIC_CONF_ExceptAndBackOffOnAbortNoticeCM: configuration manager is ExceptAndBackOffOnAbortNoticeCM
-//#define BOOST_STM_CM_STATIC_CONF_ExceptAndBackOffOnAbortNoticeCM 1
+#define BOOST_STM_CM_STATIC_CONF_ExceptAndBackOffOnAbortNoticeCM 1
-// BOOST_STM_USE_UNASIGNED_COPY: STM uses uninitialized_copy insted of the copy constructor
-#define BOOST_STM_USE_UNASIGNED_COPY 1
+// BOOST_STM_USE_MEMCOPY: STM uses memcpy insted of the copy constructor
+#define BOOST_STM_USE_MEMCOPY 1
//// The cache using uninitialized_copy can use the following memeory manager
////BOOST_STM_CACHE_USE_MALLOC: uses malloc/free
Modified: sandbox/stm/branches/vbe/boost/stm/detail/transaction_impl.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/detail/transaction_impl.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/detail/transaction_impl.hpp 2009-09-17 16:59:44 EDT (Thu, 17 Sep 2009)
@@ -796,7 +796,7 @@
invalidating_deferred_end_transaction();
#endif
}
-#if defined(BOOST_STM_USE_UNASIGNED_COPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
+#if defined(BOOST_STM_USE_MEMCOPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
context_.mstorage_.reset();
#endif
}
Modified: sandbox/stm/branches/vbe/boost/stm/detail/tx_ptr.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/detail/tx_ptr.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/detail/tx_ptr.hpp 2009-09-17 16:59:44 EDT (Thu, 17 Sep 2009)
@@ -17,6 +17,7 @@
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include <assert.h>
+#include <map>
#include <boost/stm/transaction.hpp>
//-----------------------------------------------------------------------------
@@ -172,7 +173,8 @@
template<class Y>
explicit tx_ptr(Y * ptr) : ptr_(new transactional_object<Y>(ptr)) {}
- explicit tx_ptr(transactional_object<T>* ptr) : ptr_(ptr) {}
+ template<class Y>
+ explicit tx_ptr(transactional_object<Y>* ptr) : ptr_(ptr) {}
tx_ptr(tx_obj<T>& r) : ptr_(r->obj_) {}
@@ -303,12 +305,13 @@
typedef rd_ptr<T> this_type;
public:
mutable transactional_object<T>* ptr_;
+ mutable transaction* tx_;
- inline rd_ptr(transaction &t, tx_ptr<T> tx_obj) :
+ inline rd_ptr(transaction &t, tx_ptr<T> tx_obj) : tx_(&t),
ptr_(&t.insert_and_return_read_memory(*tx_obj.ptr_))
{}
- inline rd_ptr(transaction &t, tx_obj<T> const& tx_obj) :
+ inline rd_ptr(transaction &t, tx_obj<T> const& tx_obj) : tx_(&t),
ptr_(&t.insert_and_return_read_memory(tx_obj.obj_))
{}
@@ -327,6 +330,10 @@
}
const T* get() const {
+ if (tx_->forced_to_abort()) {
+ tx_->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
return &ptr_->value;
}
@@ -667,6 +674,78 @@
mutable T &tx_obj_;
};
+/////////
+//-----------------------------------------------------------------------------
+// A rd_ptr<T> ("read pointer") points to an object that the current
+// transaction has opened for read only access.
+// You can only call a const method through a read pointer.
+// A rd_ptr<T> is constructed from an tx_ptr<T> through an explicit constructor.
+// Once a rd_ptr<T> has been constructed, an tx_ptr<T> can be opened for
+// reading simply by assignment (operator=()) into the constructed rd_ptr<T>.
+// It is not safe to derreference a rd_ptr<T> after having assigned the same
+// tx_ptr<T> to a wr_ptr<T>. If this is the case the readen value do not match
+// the writen one. If it is possible to write on the same transaction use
+// upgrd_ptr instead which is safe.
+//-----------------------------------------------------------------------------
+
+class non_transactional_vars_cache {
+ typedef std::map<void*, base_transaction_object*> map_type;
+ static std::map<void*, base_transaction_object*> map_;
+public:
+ template <typename T>
+ static transactional_reference_cache<T>* get(T* ptr) {
+ map_type::iterator it = map_.find(ptr);
+ transactional_reference_cache<T>* res=0;
+ if (it == map_.end()) {
+ res= new transactional_reference_cache<T>(ptr);
+ map_.insert(std::make_pair(ptr, res));
+ } else {
+ res=static_cast<transactional_reference_cache<T>*>(it->second);
+ }
+ return res;
+ }
+};
+
+template <typename T>
+class non_tx_rd_ptr {
+ typedef non_tx_rd_ptr<T> this_type;
+public:
+ mutable transactional_reference_cache<T>* ptr_;
+ mutable transaction* tx_;
+
+ inline non_tx_rd_ptr(transaction &t, T* ptr) : tx_(&t),
+ ptr_(&t.insert_and_return_read_memory(non_transactional_vars_cache::get(ptr)))
+ {}
+
+ inline non_tx_rd_ptr(transaction &t, T& obj) : tx_(&t),
+ ptr_(&t.insert_and_return_read_memory(non_transactional_vars_cache::get(&obj)))
+ {}
+
+
+
+ const T* get() const {
+ if (tx_->forced_to_abort()) {
+ tx_->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+ return ptr_->get();
+ }
+
+ inline const T & operator*() const { return *get(); }
+ inline const T* operator->() const { return get(); }
+
+
+ typedef transactional_reference_cache<T>* this_type::*unspecified_bool_type;
+
+ operator unspecified_bool_type() const
+ {
+ return ptr_ == 0? 0: &this_type::ptr_;
+ }
+
+};
+
+/////////
+
}}
#endif
Modified: sandbox/stm/branches/vbe/boost/stm/transaction.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/transaction.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/transaction.hpp 2009-09-17 16:59:44 EDT (Thu, 17 Sep 2009)
@@ -98,7 +98,7 @@
typedef std::pair<base_transaction_object*, base_transaction_object*> tx_pair;
-#if defined(BOOST_STM_USE_UNASIGNED_COPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
+#if defined(BOOST_STM_USE_MEMCOPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
template <std::size_t size>
struct monotonic_storage {
char storage_[size];
@@ -210,7 +210,7 @@
#ifdef USE_SINGLE_THREAD_CONTEXT_MAP
struct tx_context
{
- #if defined(BOOST_STM_USE_UNASIGNED_COPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
+ #if defined(BOOST_STM_USE_MEMCOPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
monotonic_storage<6*1000*1000> mstorage_;
#endif
MemoryContainerList newMem;
@@ -763,7 +763,6 @@
T *newNode = new T;
newNode->transaction_thread(threadId_);
- newNode->get_transaction()=this;
newNode->new_memory(1);
newMemoryList().push_back(newNode);
@@ -788,7 +787,6 @@
}
T *newNode = new T();
newNode->transaction_thread(threadId_);
- newNode->get_transaction()=this;
newNode->new_memory(1);
newMemoryList().push_back(newNode);
@@ -812,7 +810,6 @@
}
T *newNode = new T(rhs);
newNode->transaction_thread(threadId_);
- newNode->get_transaction()=this;
newNode->new_memory(1);
newMemoryList().push_back(newNode);
@@ -834,9 +831,7 @@
template <typename T>
T* as_new(T *newNode)
{
- //std::auto_ptr<T> newNode(ptr);
newNode->transaction_thread(threadId_);
- newNode->get_transaction()=this;
newNode->new_memory(1);
newMemoryList().push_back(newNode);
@@ -1076,8 +1071,7 @@
}
in.transaction_thread(threadId_);
- in.get_transaction()=this;
- writeList().insert(tx_pair((base_transaction_object*)&in, cache_new_copy(in)));
+ writeList().insert(tx_pair((base_transaction_object*)&in, in.clone()));
#if USE_BLOOM_FILTER
bloom().insert((size_t)&in);
#endif
@@ -1111,7 +1105,6 @@
else
{
in.transaction_thread(threadId_);
- in.get_transaction()=this;
unlock(&transactionMutex_);
// is this really necessary? in the deferred case it is, but in direct it
// doesn't actually save any time for anything
@@ -1221,9 +1214,8 @@
wbloom().set_bv2(bloom().h2());
//sm_wbv().set_bit((size_t)&in % sm_wbv().size());
#endif
- base_transaction_object* returnValue = cache_new_copy(in);
+ base_transaction_object* returnValue = in.clone();
returnValue->transaction_thread(threadId_);
- returnValue->get_transaction()=this;
writeList().insert(tx_pair((base_transaction_object*)&in, returnValue));
#ifndef USE_BLOOM_FILTER
unlock_tx();
@@ -2024,7 +2016,7 @@
};
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
template <class T> T* cache_allocate() {
#if defined(BOOST_STM_CACHE_USE_MEMORY_MANAGER)
return reinterpret_cast<T*>(T::retrieve_mem(sizeof(T)));
@@ -2050,7 +2042,6 @@
static void apply(T* ptr) {
if (ptr) {
#if defined(BOOST_STM_CACHE_USE_MEMORY_MANAGER)
- //ptr->return_this_mem();
base_transaction_object::return_mem(ptr,sizeof(T));
#elif defined(BOOST_STM_CACHE_USE_MALLOC)
free(ptr);
@@ -2085,7 +2076,6 @@
inline void cache_deallocate(T* ptr) {
if (ptr) {
#if defined(BOOST_STM_CACHE_USE_MEMORY_MANAGER)
- //ptr->return_this_mem();
base_transaction_object::return_mem(ptr,sizeof(T));
#elif defined(BOOST_STM_CACHE_USE_MALLOC)
free(ptr);
@@ -2110,11 +2100,9 @@
static inline T* apply(const T& val) {
T* p = cache_allocate<T>();
if (p==0) {
- //std::cout << __LINE__ << " malloc ERROR" << std::endl;
throw std::bad_alloc();
}
boost::stm::cache_restore(&val, p);
- //std::uninitialized_copy(&val,(&val)+1, p);
return p;
}
};
@@ -2146,15 +2134,13 @@
throw std::bad_alloc();
}
cache_restore(&val, p);
- //std::uninitialized_copy(&val,(&val)+1, p);
return p;
}
#endif // BOOST_STM_NO_PARTIAL_SPECIALIZATION
-#endif // BOOST_STM_USE_UNASIGNED_COPY
+#endif // BOOST_STM_USE_MEMCOPY
inline void cache_release(base_transaction_object* ptr) {
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
- //cache_deallocate(ptr);
+#ifdef BOOST_STM_USE_MEMCOPY
ptr->cache_deallocate();
#else
delete ptr;
@@ -2163,7 +2149,7 @@
template <class T>
inline T* cache_new_copy(const T& val) {
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
return cache_new_copy_constructor(val);
#else
return new T(val);
@@ -2171,11 +2157,11 @@
}
template <class T> void cache_restore(const T* const ori, T* target);
-// When BOOST_STM_USE_UNASIGNED_COPY is defined
+// When BOOST_STM_USE_MEMCOPY is defined
// this function must be specialized for objects that are non transactional by deleting the object, e.g.
#ifdef BOOST_STM_NO_PARTIAL_SPECIALIZATION
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
namespace partial_specialization_workaround {
template <class T> struct cache_restore;
@@ -2183,7 +2169,7 @@
template <class T>
struct cache_restore {
static inline void apply(const T* const ori, T* target) {
- std::uninitialized_copy(ori,ori+1, target);
+ memcpy(target, ori, sizeof(T));
}
};
@@ -2198,7 +2184,7 @@
#endif
template <class T> void cache_restore(const T* const ori, T* target) {
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
partial_specialization_workaround::cache_restore<T>::apply(ori, target);
#else
*target=*ori;
@@ -2206,15 +2192,15 @@
}
#else
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_MEMCOPY
template <class T> void cache_restore(const transactional_object<std::vector<T> >* const ori, transactional_object<std::vector<T> >* target) {
*target=*ori;
}
#endif
template <class T> void cache_restore(const T* const ori, T* target) {
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
- std::uninitialized_copy(ori,ori+1, target);
+#ifdef BOOST_STM_USE_MEMCOPY
+ memcpy(target, ori, sizeof(T));
#else
*target=*ori;
#endif
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