Boost logo

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