|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r56055 - in sandbox/stm/branches/vbe: boost/stm boost/stm/detail libs/stm/example libs/stm/test
From: vicente.botet_at_[hidden]
Date: 2009-09-05 20:08:26
Author: viboes
Date: 2009-09-05 20:08:25 EDT (Sat, 05 Sep 2009)
New Revision: 56055
URL: http://svn.boost.org/trac/boost/changeset/56055
Log:
TBoost.Stm vbe
Text files modified:
sandbox/stm/branches/vbe/boost/stm/base_transaction.hpp | 122 +++++++++++------
sandbox/stm/branches/vbe/boost/stm/detail/tx_ptr.hpp | 261 +++++++++++++++++++++++++--------------
sandbox/stm/branches/vbe/boost/stm/transaction.hpp | 113 +++++++++-------
sandbox/stm/branches/vbe/libs/stm/example/bank.cpp | 6
sandbox/stm/branches/vbe/libs/stm/example/counter.cpp | 61 +++++++--
sandbox/stm/branches/vbe/libs/stm/example/list.cpp | 58 +++++---
sandbox/stm/branches/vbe/libs/stm/test/Jamfile.v2 | 7
7 files changed, 400 insertions(+), 228 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-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -50,9 +50,15 @@
//-----------------------------------------------------------------------------
namespace boost { namespace stm {
+
+//-----------------------------------------------------------------------------
+// forward declarations
+//-----------------------------------------------------------------------------
+
template <class T> void cache_deallocate(T*);
template <class T> void cache_restore(const T* const ori, T* target);
template <class T> inline T* cache_new_copy_constructor(const T&);
+class transaction;
#ifndef BOOST_STM_USE_BOOST_MUTEX
typedef pthread_mutex_t PLOCK;
@@ -60,7 +66,6 @@
typedef boost::mutex PLOCK;
#endif
-
//-----------------------------------------------------------------------------
// boolean which is used to invoke "begin_transaction()" upon transaction
// object construction (so two lines of code aren't needed to make a
@@ -171,13 +176,24 @@
inline void unlock(PLOCK &lock) { lock.unlock(); }
inline void unlock(PLOCK *lock) { lock->unlock(); }
#endif
-//-----------------------------------------------------------------------------
-// forward declaration
-//-----------------------------------------------------------------------------
-class transaction;
//-----------------------------------------------------------------------------
+// this is the base class of all the transactional objects.
+// it tracks:
+// transactionThread_: the thread identifier holding the write acces to this transactional object
+// transaction_: the pointer to the transaction
+// version: the version when performing validation
+// newMemory_: states whether this object is a new object
+// 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
+// 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
+// when USE_STM_MEMORY_MANAGER is defined this class provides two functions (retrieve_mem and return_mem) and to manage a pool of memory
//-----------------------------------------------------------------------------
+
class base_transaction_object
{
public:
@@ -190,8 +206,8 @@
#endif
{}
-#if 0
- base_transaction_object(const base_transaction_object &t)
+#if 0
+ base_transaction_object(const base_transaction_object &t)
: transactionThread_(kInvalidThread)
, newMemory_(0)
, transaction_(t)
@@ -199,8 +215,8 @@
, version_(0)
#endif
{}
-#endif
-
+#endif
+
virtual void copy_state(base_transaction_object const * const rhs) = 0;
#if BUILD_MOVE_SEMANTICS
virtual void move_state(base_transaction_object * rhs) = 0;
@@ -208,9 +224,9 @@
virtual void move_state(base_transaction_object * rhs) {};
#endif
virtual ~base_transaction_object() {};
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_UNASIGNED_COPY
virtual void cache_deallocate()=0;
-#endif
+#endif
void transaction_thread(size_t rhs) const { transactionThread_ = rhs; }
size_t const & transaction_thread() const { return transactionThread_; }
@@ -226,7 +242,7 @@
transaction*& get_transaction() const {return transaction_;}
//transaction* get_transaction() const {return transaction_;}
-
+
#if PERFORMING_VALIDATION
size_t version_;
#endif
@@ -291,6 +307,12 @@
//-----------------------------------------------------------------------------
+// transaction object mixin
+// Provides the definition of the virtual functions
+// copy_state: relaying on the cache_restore<T> generic function
+// 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
//-----------------------------------------------------------------------------
template <class Derived>
class transaction_object : public base_transaction_object
@@ -300,7 +322,7 @@
//--------------------------------------------------------------------------
virtual void copy_state(base_transaction_object const * const rhs)
{
- cache_restore(static_cast<Derived const * const>(rhs), static_cast<Derived *>(this));
+ boost::stm::cache_restore(static_cast<Derived const * const>(rhs), static_cast<Derived *>(this));
}
#if BUILD_MOVE_SEMANTICS
@@ -311,12 +333,12 @@
}
#endif
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_UNASIGNED_COPY
virtual void cache_deallocate() {
boost::stm::cache_deallocate(this);
}
-
-#endif
+
+#endif
#if USE_STM_MEMORY_MANAGER
void* operator new(size_t size) throw ()
@@ -390,61 +412,66 @@
//-----------------------------------------------------------------------------
// transactional object wrapper
// A transactional_object<T> is a base_transaction_object wrapping an instance of type T
-//
+// Provides the definition of the virtual functions
+// forward constructors to the wrapped type
+// copy_state: relaying on the cache_restore<T> generic function
+// 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
+//
// If a class D inherits from B we have that transactional_object<D> dont inherits from transactional_object<B>, but
-// we can static/dynamic cast them robustly.
+// we can static/dynamic cast them robustly.
// Evidently the std::static_cast/std::dynamic_cast do not works. We need to define the specific cast
-//
-// transactional_object<D>* d=...;
+//
+// transactional_object<D>* d=...;
// transactional_object<B>* b=tx_static_cast<B>(d);
-//
-// transactional_object<B>* b=...;
+//
+// transactional_object<B>* b=...;
// transactional_object<D>* d=tx_dynamic_cast<B>(b);
-//
+//
//-----------------------------------------------------------------------------
-
template <typename T>
class transactional_object : public base_transaction_object {
-public:
+public:
T value;
-
+
transactional_object() {}
- transactional_object(const T*ptr)
+ transactional_object(const T*ptr)
: base_transaction_object()
, value(*ptr) {}
-
- transactional_object(transactional_object<T> const & r)
+
+ transactional_object(transactional_object<T> const & r)
: base_transaction_object(r)
, value(r.value) {}
-
+
template <typename T1>
- transactional_object(T1 const &p1)
+ transactional_object(T1 const &p1)
: base_transaction_object()
, value(p1) {}
template <typename T1, typename T2>
- transactional_object(T1 const &p1, T2 const &p2)
+ transactional_object(T1 const &p1, T2 const &p2)
: base_transaction_object()
, value(p1,p2) {}
- transactional_object & operator=(transactional_object const & r) // never throws
+ transactional_object & operator=(transactional_object const & r) // =default never throws
{
this->transaction_=r.transaction_;
value = r.value;
return *this;
}
-
+
virtual void copy_state(base_transaction_object const * const rhs) {
- cache_restore(static_cast<transactional_object<T> const * const>(rhs),
+ cache_restore(static_cast<transactional_object<T> const * const>(rhs),
static_cast<transactional_object<T> *>(this));
}
-#ifdef BOOST_STM_USE_UNASIGNED_COPY
+#ifdef BOOST_STM_USE_UNASIGNED_COPY
virtual void cache_deallocate() {
boost::stm::cache_deallocate(this);
}
-#endif
+#endif
#if USE_STM_MEMORY_MANAGER
void* operator new(size_t size) throw ()
@@ -457,26 +484,33 @@
return_mem(mem, sizeof(transactional_object<T>));
}
#endif
-
+
};
+//-----------------------------------------------------------------------------
// gets the transactional_object<T> pointer wrapping the T pointer
+//-----------------------------------------------------------------------------
template <typename T>
-static transactional_object<T>* up_cast(T* ptr) {
+static transactional_object<T>* tx_up_cast(T* ptr) {
return reinterpret_cast<transactional_object<T>*>(reinterpret_cast<char*>(ptr)-offsetof(transactional_object<T>, value));
}
-
-//
+
+//-----------------------------------------------------------------------------
+// static_cast two transactional_object's
+//-----------------------------------------------------------------------------
template <typename T, typename U>
static transactional_object<T>* tx_static_cast(transactional_object<U>* ptr) {
- return up_cast(static_cast<T*>(&ptr->value));
+ return tx_up_cast(static_cast<T*>(&ptr->value));
}
-
+
+//-----------------------------------------------------------------------------
+// dynamic_cast two transactional_object's
+//-----------------------------------------------------------------------------
template <typename T, typename U>
static transactional_object<T>* tx_dynamic_cast(transactional_object<U>* ptr) {
T* p = dynamic_cast<T*>(&ptr->value);
if (p==0) return 0;
- return up_cast(p);
+ return tx_up_cast(p);
}
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-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -30,6 +30,97 @@
template <typename T>
class upgrd_ptr;
+//-----------------------------------------------------------------------------
+// class tx_obj wraps a transactional_object providing builting operators
+//-----------------------------------------------------------------------------
+
+template <typename T>
+class tx_obj {
+public:
+ transactional_object<T> obj_;
+
+ //-----------------------------------------------------------------------------
+ // default constructor valid ony if T has a default constructor
+
+ tx_obj() : obj_() {}
+
+ //
+ template<class Y>
+ tx_obj(tx_obj<Y> const& r) : obj_(r.ref()) {} // throws only if obj_ contructor throws
+
+ template <typename T1>
+ tx_obj(T1 p1) : obj_(p1) {}
+
+ bool operator==(const tx_obj<T>& rhs) const {
+ return this->ref()==rhs.ref();
+ }
+
+ bool operator==(const T& rhs) const {
+ return this->ref()==rhs;
+ }
+
+ //operator T() const { return *this->get(); }
+
+ T* operator->() {
+ return this->get();
+ }
+ const T* operator->() const {
+ return this->get();
+ }
+ T& operator*() {
+ return this->ref();
+ }
+ const T& operator*() const {
+ return this->ref();
+ }
+ T* get() {
+ return &this->ref();
+ }
+ const T* get() const {
+ return &this->ref();
+ }
+ T& ref() {
+ transaction* tx=transaction::current_transaction();
+ if (tx!=0) {
+ if (tx->forced_to_abort()) {
+ tx->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+ return tx->write(obj_).value;
+ }
+ return obj_.value;
+ }
+
+ const T& ref() const {
+ transaction* tx=transaction::current_transaction();
+ if (tx!=0) {
+ if (tx->forced_to_abort()) {
+ tx->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+ return tx->read(obj_).value;
+ }
+ return obj_.value;
+ }
+
+
+ tx_obj& operator--() { --ref(); return *this; }
+ T operator--(int) { T n = obj_.value_; --ref(); return n; }
+
+ tx_obj& operator++() { ++ref(); return *this; }
+ T operator++(int) { T n = obj_.value_; ++ref(); return n; }
+
+ tx_obj& operator+=(T const &rhs) {
+ ref() += rhs;
+ return *this;
+ }
+
+ T operator+(T const &rhs) const {
+ return ref()+rhs;
+ }
+
+};
+
//-----------------------------------------------------------------------------
// a tx_ptr<T> is an smart pointer to a transactional_object<T> (which contains an instance of T).
@@ -52,6 +143,8 @@
explicit tx_ptr(Y * ptr) : ptr_(new transactional_object<Y>(ptr)) {}
explicit tx_ptr(transactional_object<T>* ptr) : ptr_(ptr) {}
+
+ tx_ptr(tx_obj<T>& r) : ptr_(r->obj_) {}
template<class Y>
tx_ptr(tx_ptr<Y> const& r) : ptr_(r.ptr_) {}// never throws
@@ -72,15 +165,14 @@
return *this;
}
template<class Y>
- tx_ptr & operator=(transactional_object<Y>* ptr) { // never throws
+ tx_ptr& operator=(transactional_object<Y>* ptr) { // never throws
ptr_=ptr;
return *this;
}
- // two transactional pointers are equal if they point to the same cache on the current transaction.
- bool operator==(const tx_ptr<T>& rhs) {
- return ptr_==rhs.ptr_ || this->get()==rhs.ptr_ || ptr_==rhs.get();
- }
+ //bool operator==(const tx_ptr<T>& rhs) const {
+ // return ptr_==rhs.ptr_ || this->get()==rhs.ptr_ || ptr_==rhs.get();
+ //}
T* operator->() const {
return this->get();
@@ -100,35 +192,29 @@
}
return &ptr_->value;
}
- operator T*() const { return this->get(); }
typedef transactional_object<T>* this_type::*unspecified_bool_type;
- #if 0
- operator unspecified_bool_type() const
- {
+ operator unspecified_bool_type() const {
return ptr_ == 0? 0: &this_type::ptr_;
}
- #endif
- void swap(tx_ptr & other) // never throws
- {
+ void swap(tx_ptr & other) { // never throws
std::swap(ptr_, other.ptr_);
}
};
+// two transactional pointers are equal if they point to the same cache on the current transaction.
template <typename T, typename U>
bool operator==(const tx_ptr<T>& lhs, const tx_ptr<U>& rhs) {
- return lhs.get()==rhs.get();
+ return lhs.ptr_==rhs.ptr_ || lhs.get()==rhs.ptr_ || lhs.ptr_==rhs.get();
}
template <typename T, typename U>
bool operator!=(const tx_ptr<T>& lhs, const tx_ptr<U>& rhs) {
- return lhs.get()!=rhs.get();
+ return lhs.ptr_!=rhs.ptr_ && lhs.get()!=rhs.ptr_ && lhs.ptr_!=rhs.get();
}
-
-template<class T> inline void swap(tx_ptr<T> & a, tx_ptr<T> & b)
-{
+template<class T> inline void swap(tx_ptr<T> & a, tx_ptr<T> & b) {
a.swap(b);
}
@@ -146,8 +232,9 @@
template <typename T>
void delete_ptr(tx_ptr<T> ptr) {
if (ptr.ptr_==0) return;
- if (ptr.ptr_->transaction_==0) delete ptr.ptr_;
- ptr.ptr_->transaction_->delete_tx_ptr(ptr.ptr_);
+ transaction* tx=transaction::current_transaction();
+ if (tx==0) delete ptr.ptr_;
+ tx->delete_tx_ptr(ptr.ptr_);
}
@@ -163,45 +250,11 @@
}
template <typename T, typename U>
-static tx_ptr<T>* tx_dynamic_cast(tx_ptr<U>* ptr) {
+static tx_ptr<T>* tx_dynamic_cast(tx_ptr<U> ptr) {
return tx_ptr<T>(tx_dynamic_cast<T>(ptr->ptr_));
}
-template <typename T>
-class tx_obj {
-public:
- transactional_object<T> obj_;
- transactional_object<T> * ptr_;
-
- tx_obj() : obj_(), ptr_(&obj_) {}
- template <typename T1>
- tx_obj(T1 p1) : obj_(p1), ptr_(&obj_) {}
-
- bool operator==(const tx_obj<T>& rhs) {
- return *this->get()==*rhs.get();
- }
- T* operator->() {
- return this->get();
- }
- T& operator*() {
- return *this->get();
- }
- T* get() {
- if (0==ptr_->transaction_) {
- transaction* tx=transaction::current_transaction();
- if (tx!=0) {
- if (tx->forced_to_abort()) {
- tx->lock_and_abort();
- throw aborted_transaction_exception("aborting transaction");
- }
- ptr_=tx->write_ptr(ptr_);
- }
- }
- return &ptr_->value;
- }
-};
-
//-----------------------------------------------------------------------------
// A rd_ptr<T> ("read pointer") points to an object that the current
// transaction has opened for read only access.
@@ -217,63 +270,78 @@
template <typename T>
class rd_ptr {
- typedef tx_ptr<T> this_type;
+ typedef rd_ptr<T> this_type;
public:
+ mutable transactional_object<T>* ptr_;
inline rd_ptr(transaction &t, tx_ptr<T> tx_obj) :
ptr_(&t.insert_and_return_read_memory(*tx_obj.ptr_))
{}
+ inline rd_ptr(transaction &t, tx_obj<T> const& tx_obj) :
+ ptr_(&t.insert_and_return_read_memory(tx_obj.obj_))
+ {}
+
template<class Y>
- rd_ptr & operator=(tx_ptr<Y> const & r) { // never throws
+ rd_ptr & operator=(tx_ptr<Y> r) { // never throws
//this_type(r).swap(*this);
ptr_=r.ptr_;
return *this;
}
+ template<class Y>
+ rd_ptr& operator=(tx_obj<Y> const & r) { // never throws
+ //this_type(r).swap(*this);
+ ptr_=r.get();
+ return *this;
+ }
+
const T* get() const {
- //if (ptr_->transaction_->forced_to_abort()) {
- // ptr_->transaction_->lock_and_abort();
- // throw aborted_transaction_exception("aborting transaction");
- //}
-
return &ptr_->value;
}
inline const T & operator*() const { return *get(); }
inline const T* operator->() const { return get(); }
- operator const T*() const { return get(); }
typedef transactional_object<T>* this_type::*unspecified_bool_type;
- #if 0
operator unspecified_bool_type() const
{
return ptr_ == 0? 0: &this_type::ptr_;
}
- #endif
-//private:
- mutable transactional_object<T>* ptr_;
+
};
template <typename T>
-rd_ptr<T> make_rd_ptr(transaction& tx, tx_ptr<T>& ptr) {
+rd_ptr<T> make_rd_ptr(transaction& tx, tx_ptr<T> ptr) {
return rd_ptr<T>(tx, ptr);
}
+template <typename T>
+rd_ptr<T> make_rd_ptr(transaction& tx, tx_obj<T> const & ref) {
+ return rd_ptr<T>(tx, ref);
+}
template <typename T>
-rd_ptr<T> make_rd_ptr(tx_ptr<T>& ptr) {
+rd_ptr<T> make_rd_ptr(tx_ptr<T> ptr) {
transaction* tx = transaction::current_transaction();
assert(tx==0);
return rd_ptr<T>(*tx, ptr);
}
template <typename T>
+rd_ptr<T> make_rd_ptr(tx_obj<T> const & ref) {
+ transaction* tx = transaction::current_transaction();
+ assert(tx==0);
+ return rd_ptr<T>(*tx, ref);
+}
+
+template <typename T>
void delete_ptr(rd_ptr<T> ptr) {
if (ptr.ptr_==0) return;
- if (ptr.ptr_->transaction_==0) delete ptr.ptr_;
- ptr.ptr_->transaction_->delete_tx_ptr(ptr.ptr_);
+ transaction* tx=transaction::current_transaction();
+ if (tx==0) delete ptr.ptr_;
+ tx->delete_tx_ptr(ptr.ptr_);
}
template <typename T>
@@ -299,14 +367,20 @@
class upgrd_ptr {
typedef tx_ptr<T> this_type;
public:
+ mutable transaction* tx_;
+ mutable transactional_object<T>* ptr_;
+ mutable bool written_;
- inline upgrd_ptr() : tx_(0) {}
+ //inline upgrd_ptr() : tx_(0) {}
inline upgrd_ptr(transaction &t, tx_ptr<T> tx_obj) : tx_(&t),
ptr_(const_cast<transactional_object<T>*>(t.read_ptr(tx_obj.ptr_))), written_(false) {}
template<class Y>
upgrd_ptr & operator=(tx_ptr<Y> const& r) { // never throws
//this_type(r).swap(*this);
+ transaction* tx=transaction::current_transaction();
+ if (tx==0) throw "error";
+ tx_=tx;
ptr_=r.ptr_;
written_=false;
return *this;
@@ -340,12 +414,10 @@
typedef transactional_object<T>* this_type::*unspecified_bool_type;
- #if 1
operator unspecified_bool_type() const
{
return ptr_ == 0? 0: &this_type::ptr_;
}
- #endif
void write_ptr(transactional_object<T>* ptr) {
ptr_ = ptr;
written_ = true;
@@ -374,17 +446,19 @@
return ptr_;
}
-//private:
- mutable transaction* tx_;
- mutable transactional_object<T>* ptr_;
- mutable bool written_;
};
template <typename T>
-void delete_ptr(upgrd_ptr<T> ptr) {
+void delete_ptr(upgrd_ptr<T> const& ptr) {
+ if (ptr.ptr_==0) return;
+ if (ptr.tx_==0) delete ptr.ptr_;
+ ptr.tx_->delete_tx_ptr(ptr.ptr_);
+}
+
+template <typename T>
+void delete_ptr(transaction& tx, upgrd_ptr<T> const& ptr) {
if (ptr.ptr_==0) return;
- if (ptr.ptr_->transaction_==0) delete ptr.ptr_;
- ptr.ptr_->transaction_->delete_tx_ptr(ptr.ptr_);
+ tx.delete_tx_ptr(ptr.ptr_);
}
//-----------------------------------------------------------------------------
@@ -397,20 +471,22 @@
class wr_ptr {
typedef tx_ptr<T> this_type;
public:
+ mutable transaction& tx_;
+ mutable transactional_object<T>* ptr_;
- inline wr_ptr(transaction &t, tx_ptr<T> tx_obj) :
+ inline wr_ptr(transaction &t, tx_ptr<T> tx_obj) : tx_(t),
ptr_(t.write_ptr(tx_obj.ptr_))
{}
- inline wr_ptr(transaction &t, upgrd_ptr<T> tx_obj) :
+ inline wr_ptr(transaction &t, upgrd_ptr<T> tx_obj) : tx_(t),
ptr_(t.write_ptr(tx_obj.ptr_))
{
tx_obj.write_ptr(ptr_);
}
T* get() {
- if (ptr_->transaction_->forced_to_abort()) {
- ptr_->transaction_->lock_and_abort();
+ if (tx_.forced_to_abort()) {
+ tx_.lock_and_abort();
throw aborted_transaction_exception("aborting transaction");
}
return &ptr_->value;
@@ -418,19 +494,13 @@
inline T& operator*() { return *get(); }
inline T* operator->() { return get(); }
-
- operator const T*() const { return get(); }
-
+
typedef transactional_object<T>* this_type::*unspecified_bool_type;
- #if 0
operator unspecified_bool_type() const
{
return ptr_ == 0? 0: &this_type::ptr_;
}
- #endif
-//private:
- mutable transactional_object<T>* ptr_;
};
template <typename T>
@@ -442,17 +512,20 @@
template <typename T>
wr_ptr<T> make_wr_ptr(tx_ptr<T>& ptr) {
transaction* tx = transaction::current_transaction();
- if (tx==0) throw "error";
return wr_ptr<T>(*tx, ptr);
}
template <typename T>
void delete_ptr(wr_ptr<T> ptr) {
if (ptr.ptr_==0) return;
- if (ptr.ptr_->transaction_==0) delete ptr.ptr_;
- ptr.ptr_->transaction_->delete_tx_ptr(ptr.ptr_);
+ ptr.tx_.delete_tx_ptr(ptr.ptr_);
}
+template <typename T>
+void delete_ptr(transaction& tx, wr_ptr<T> const& ptr) {
+ if (ptr.ptr_==0) return;
+ tx.delete_tx_ptr(ptr.ptr_);
+}
//=========================
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-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -70,13 +70,13 @@
//-----------------------------------------------------------------------------
namespace boost { namespace stm {
-
+
#if defined(BOOST_STM_CM_STATIC_CONF)
#if defined(BOOST_STM_CM_STATIC_CONF_ExceptAndBackOffOnAbortNoticeCM)
- typedef except_and_back_off_on_abort_notice_cm contention_manager_type;
-#endif
-#endif
-
+ typedef except_and_back_off_on_abort_notice_cm contention_manager_type;
+#endif
+#endif
+
enum LatmType
{
kMinLatmType = 0,
@@ -97,15 +97,15 @@
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)
- template <std::size_t size>
+ template <std::size_t size>
struct monotonic_storage {
char storage_[size];
char* ptr_;
public:
monotonic_storage() : ptr_(&storage_[0]) {}
- template <typename T>
+ template <typename T>
char* allocate() {
union aligned_storage {
char val[sizeof(T)] ;
@@ -117,7 +117,7 @@
}
void reset() {ptr_=&storage_[0];}
};
-#endif
+#endif
class transaction;
struct TransactionsStack {
@@ -132,7 +132,7 @@
std::size_t size() {return stack_.size();}
transaction* top() {return stack_.top();}
};
-
+
///////////////////////////////////////////////////////////////////////////////
// transaction Class
///////////////////////////////////////////////////////////////////////////////
@@ -212,7 +212,7 @@
{
#if defined(BOOST_STM_USE_UNASIGNED_COPY) && defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
monotonic_storage<6*1000*1000> mstorage_;
- #endif
+ #endif
MemoryContainerList newMem;
MemoryContainerList delMem;
WriteContainer writeMem;
@@ -287,8 +287,8 @@
#if defined(BOOST_STM_CM_STATIC_CONF)
//static contention_manager_type cm_;
//inline static void contention_manager(base_contention_manager *rhs) { delete cm_; cm_ = rhs; }
- inline static contention_manager_type* get_contention_manager() {
- static contention_manager_type cm_;return &cm_;
+ inline static contention_manager_type* get_contention_manager() {
+ static contention_manager_type cm_;return &cm_;
}
static void cm_abort_on_new(transaction const &t) {return contention_manager_type::abort_on_new(t); }
static void cm_abort_on_delete(transaction const &t,
@@ -313,7 +313,7 @@
static void cm_perform_isolated_tx_wait_priority_promotion(transaction &t) {return contention_manager_type::perform_isolated_tx_wait_priority_promotion(t); }
static void cm_perform_irrevocable_tx_wait_priority_promotion(transaction &t) {return contention_manager_type::perform_irrevocable_tx_wait_priority_promotion(t); }
- #else
+ #else
static base_contention_manager *cm_;
inline static void contention_manager(base_contention_manager *rhs) { delete cm_; cm_ = rhs; }
inline static base_contention_manager* get_contention_manager() { return cm_; }
@@ -340,7 +340,7 @@
static void cm_perform_isolated_tx_wait_priority_promotion(transaction &t) {return cm_->perform_isolated_tx_wait_priority_promotion(t); }
static void cm_perform_irrevocable_tx_wait_priority_promotion(transaction &t) {return cm_->perform_irrevocable_tx_wait_priority_promotion(t); }
- #endif
+ #endif
inline static void enableLoggingOfAbortAndCommitSetSize() { bookkeeping_.setIsLoggingAbortAndCommitSize(true); }
inline static void disableLoggingOfAbortAndCommitSetSize() { bookkeeping_.setIsLoggingAbortAndCommitSize(false); }
@@ -905,7 +905,7 @@
inline size_t const & thread_id() const { return threadId_; }
private:
-
+
#ifdef LOGGING_BLOCKS
static std::string outputBlockedThreadsAndLockedLocks();
@@ -1230,7 +1230,9 @@
#endif
return *static_cast<T*>(returnValue);
}
- else return *static_cast<T*>(i->second);
+ else {
+ return *static_cast<T*>(i->second);
+ }
}
//--------------------------------------------------------------------------
@@ -1851,7 +1853,7 @@
#endif
-
+
////////////////////////////////////////
#else // USE_SINGLE_THREAD_CONTEXT_MAP
////////////////////////////////////////
@@ -2018,7 +2020,7 @@
public:
inline static transaction* current_transaction() {return transactions(THREAD_ID).top();}
-
+
};
@@ -2027,22 +2029,22 @@
#if defined(BOOST_STM_CACHE_USE_MEMORY_MANAGER)
return reinterpret_cast<T*>(T::retrieve_mem(sizeof(T)));
#elif defined(BOOST_STM_CACHE_USE_MALLOC)
- return reinterpret_cast<T*>(malloc(sizeof(T)));
+ return reinterpret_cast<T*>(malloc(sizeof(T)));
#elif defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
return reinterpret_cast<T*>(context_.mstorage_.allocate<T>());
- #else
+ #else
#error "BOOST_STM_CACHE_USE_MEMORY_MANAGER, BOOST_STM_CACHE_USE_MALLOC or BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER must be defined"
#endif
}
-// this function must be specialized for objects that are non transactional
+// this function must be specialized for objects that are non transactional
// by deleting the object
#ifdef BOOST_STM_NO_PARTIAL_SPECIALIZATION
namespace partial_specialization_workaround {
template <class T>
struct cache_deallocate;
-
+
template <class T>
struct cache_deallocate {
static void apply(T* ptr) {
@@ -2053,7 +2055,7 @@
#elif defined(BOOST_STM_CACHE_USE_MALLOC)
free(ptr);
#elif defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
- #else
+ #else
#error "BOOST_STM_CACHE_USE_MEMORY_MANAGER, BOOST_STM_CACHE_USE_MALLOC or BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER must be defined"
#endif
}
@@ -2074,12 +2076,12 @@
#else //!BOOST_STM_NO_PARTIAL_SPECIALIZATION
-template <class T>
+template <class T>
inline void cache_deallocate(transactional_object<std::vector<T> >* ptr) {
delete ptr;
}
-template <class T>
+template <class T>
inline void cache_deallocate(T* ptr) {
if (ptr) {
#if defined(BOOST_STM_CACHE_USE_MEMORY_MANAGER)
@@ -2088,7 +2090,7 @@
#elif defined(BOOST_STM_CACHE_USE_MALLOC)
free(ptr);
#elif defined(BOOST_STM_CACHE_USE_TSS_MONOTONIC_MEMORY_MANAGER)
- #else
+ #else
#error "BOOST_STM_CACHE_USE_MEMORY_MANAGER or BOOST_STM_CACHE_USE_MALLOC must be defined"#endif
#endif
}
@@ -2096,13 +2098,13 @@
#endif //BOOST_STM_NO_PARTIAL_SPECIALIZATION
// this function must be specialized for objects that are non transactional,
-// by calling to new of the copy constructor
+// by calling to new of the copy constructor
#ifdef BOOST_STM_NO_PARTIAL_SPECIALIZATION
namespace partial_specialization_workaround {
template <class T>
struct cache_new_copy_constructor;
-
+
template <class T>
struct cache_new_copy_constructor {
static inline T* apply(const T& val) {
@@ -2112,7 +2114,7 @@
throw std::bad_alloc();
}
boost::stm::cache_restore(&val, p);
- //std::uninitialized_copy(&val,(&val)+1, p);
+ //std::uninitialized_copy(&val,(&val)+1, p);
return p;
}
};
@@ -2120,7 +2122,7 @@
template <class T, class A>
struct cache_new_copy_constructor<transactional_object<std::vector<T,A> > > {
static inline transactional_object<std::vector<T,A> >* apply(const transactional_object<std::vector<T,A> >& val) {
- return new transactional_object<std::vector<T,A> >(val);
+ return new transactional_object<std::vector<T,A> >(val);
}
};
} // partial_specialization_workaround
@@ -2131,12 +2133,12 @@
}
#else //BOOST_STM_NO_PARTIAL_SPECIALIZATION
-template <class T>
+template <class T>
inline transactional_object<std::vector<T> >* cache_new_copy_constructor(const transactional_object<std::vector<T> >& val) {
- return new transactional_object<std::vector<T> >(val);
+ return new transactional_object<std::vector<T> >(val);
}
-template <class T>
+template <class T>
inline T* cache_new_copy_constructor(const T& val) {
T* p = cache_allocate<T>();
if (p==0) {
@@ -2144,7 +2146,7 @@
throw std::bad_alloc();
}
cache_restore(&val, p);
- //std::uninitialized_copy(&val,(&val)+1, p);
+ //std::uninitialized_copy(&val,(&val)+1, p);
return p;
}
#endif // BOOST_STM_NO_PARTIAL_SPECIALIZATION
@@ -2155,21 +2157,21 @@
//cache_deallocate(ptr);
ptr->cache_deallocate();
#else
- delete ptr;
+ delete ptr;
#endif
}
-template <class T>
+template <class T>
inline T* cache_new_copy(const T& val) {
#ifdef BOOST_STM_USE_UNASIGNED_COPY
return cache_new_copy_constructor(val);
#else
- return new T(val);
+ return new T(val);
#endif
}
template <class T> void cache_restore(const T* const ori, T* target);
-// When BOOST_STM_USE_UNASIGNED_COPY is defined
+// When BOOST_STM_USE_UNASIGNED_COPY 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
@@ -2181,7 +2183,7 @@
template <class T>
struct cache_restore {
static inline void apply(const T* const ori, T* target) {
- std::uninitialized_copy(ori,ori+1, target);
+ std::uninitialized_copy(ori,ori+1, target);
}
};
@@ -2212,18 +2214,22 @@
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);
+ std::uninitialized_copy(ori,ori+1, target);
#else
*target=*ori;
#endif
}
#endif
-
+//-----------------------------------------------------------------------------
+// scoped thread initializer calling transaction::initialize_thread() in the
+// constructor and transaction::terminate_thread() in the destructor
+//-----------------------------------------------------------------------------
struct thread_initializer {
thread_initializer() {transaction::initialize_thread();}
~thread_initializer() {transaction::terminate_thread();}
};
+
#if 0
template <>
@@ -2252,18 +2258,29 @@
// rand()+1 check is necessarily complex so smart compilers can't
// optimize the if away
//---------------------------------------------------------------------------
-#define use_atomic(T) if (0 != rand()+1) for (boost::stm::transaction T; !T.committed() && T.restart(); T.end())
-#define try_atomic(T) if (0 != rand()+1) for (boost::stm::transaction T; !T.committed() && T.restart(); T.no_throw_end()) try
-#define atomic(T) if (0 != rand()+1) for (boost::stm::transaction T; !T.committed() && T.check_throw_before_restart() && T.restart_if_not_inflight(); T.no_throw_end()) try
-
+//#define use_atomic(T) if (0 != rand()+1) for (boost::stm::transaction T; !T.committed() && T.restart(); T.end())
+//#define try_atomic(T) if (0 != rand()+1) for (boost::stm::transaction T; !T.committed() && T.restart(); T.no_throw_end()) try
+//#define atomic(T) if (0 != rand()+1) for (boost::stm::transaction T; !T.committed() && T.check_throw_before_restart() && T.restart_if_not_inflight(); T.no_throw_end()) try
+
+#define use_atomic(T) for (boost::stm::transaction T; !T.committed() && T.restart(); T.end())
+#define try_atomic(T) for (boost::stm::transaction T; !T.committed() && T.restart(); T.no_throw_end()) try
+#define atomic(T) for (boost::stm::transaction T; !T.committed() && T.check_throw_before_restart() && T.restart_if_not_inflight(); T.no_throw_end()) try
#define catch_before_retry(E) catch (boost::stm::aborted_tx &E)
#define before_retry catch (boost::stm::aborted_tx &)
#define end_atom catch (boost::stm::aborted_tx &) {}
-} // core namespace
-}
+#define BOOST_STM_NEW(T, P) \
+ ((T).throw_if_forced_to_abort_on_new(), \
+ (T).as_new(new P))
+
+#define BOOST_STM_NEW_1(P) \
+ ((boost::stm::transaction::current_transaction()!=0)?BOOST_STM_NEW(*boost::stm::transaction::current_transaction(), P):new P)
+
+} // stm namespace
+} // boost namespace
+
#include <boost/stm/detail/transaction_impl.hpp>
#include <boost/stm/detail/latm_general_impl.hpp>
#include <boost/stm/detail/auto_lock.hpp>
Modified: sandbox/stm/branches/vbe/libs/stm/example/bank.cpp
==============================================================================
--- sandbox/stm/branches/vbe/libs/stm/example/bank.cpp (original)
+++ sandbox/stm/branches/vbe/libs/stm/example/bank.cpp 2009-09-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -51,17 +51,17 @@
typedef BankAccount account;
-struct bank{ //persistent object
+struct bank{
vector<tx_ptr<BankAccount> > accounts;
int overall_balance() const{
int tmp=0;
- foreach(BankAccount const* a,this->accounts){
+ foreach(tx_ptr<BankAccount> const &a, this->accounts){
tmp+=a->Balance();
}
return tmp;
}
void print_balance() const{
- foreach(BankAccount const* a,this->accounts){
+ foreach(tx_ptr<BankAccount> const &a, this->accounts){
cerr << a->Nb() << "=" << a->Balance() << endl;
}
}
Modified: sandbox/stm/branches/vbe/libs/stm/example/counter.cpp
==============================================================================
--- sandbox/stm/branches/vbe/libs/stm/example/counter.cpp (original)
+++ sandbox/stm/branches/vbe/libs/stm/example/counter.cpp 2009-09-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -12,41 +12,71 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/stm.hpp>
-#include <boost/foreach.hpp>
#include <boost/thread.hpp>
-#include <boost/shared_ptr.hpp>
-//#include <string>
#include <vector>
#include <list>
-//#include <iostream>
#include <stdlib.h>
-#define foreach BOOST_FOREACH
using namespace std;
using namespace boost;
using namespace boost::stm;
-stm::tx_ptr<int> counter;
+stm::tx_obj<int> counter(0);
+stm::tx_obj<int> counter2(0);
void inc() {
thread_initializer thi;
use_atomic(_) {
- *counter+=*counter;
+ ++counter;
}
}
-void check() {
- //thread_initializer thi;
+void decr() {
+ thread_initializer thi;
use_atomic(_) {
- assert(*counter==4);
+ --counter;
+ }
+}
+bool check(int val) {
+ //thread_initializer thi;
+ bool res;
+ use_atomic(_) {
+ res =(*counter==val);
+ }
+ return res;
+}
+
+bool assign() {
+ //thread_initializer thi;
+ use_atomic(_) {
+ counter=1;
+ counter2=counter;
}
+ bool res;
+ use_atomic(_) {
+ res =(*counter==1) && (*counter2==1) && (counter==counter2) ;
+ }
+ return res;
}
+
+bool test_const(stm::tx_obj<int> const& c) {
+ //thread_initializer thi;
+ use_atomic(_) {
+ counter2=c;
+ }
+ bool res;
+ use_atomic(_) {
+ res =(c==counter2) ;
+ }
+ return res;
+}
+
int test_counter() {
- counter=make_tx_ptr<int>(0);
+ //counter=make_tx_ptr<int>(0);
thread th1(inc);
- thread th2(inc);
+ thread th2(decr);
thread th3(inc);
thread th4(inc);
@@ -55,9 +85,10 @@
th3.join();
th4.join();
- check();
- boost::stm::delete_ptr(counter);
- return 0;
+ bool fails=!check(2);
+ fails = fails || !assign();
+ fails = fails || !test_const(counter);
+ return fails;
}
int main() {
Modified: sandbox/stm/branches/vbe/libs/stm/example/list.cpp
==============================================================================
--- sandbox/stm/branches/vbe/libs/stm/example/list.cpp (original)
+++ sandbox/stm/branches/vbe/libs/stm/example/list.cpp 2009-09-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -11,8 +11,6 @@
//
//////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
#include <boost/stm.hpp>
#include <boost/thread.hpp>
#include <stdlib.h>
@@ -21,14 +19,8 @@
using namespace boost;
using namespace boost::stm;
-#define BOOST_STM_NEW(T, P) \
- ((T).throw_if_forced_to_abort_on_new(), \
- (T).as_new(new P))
-
-#define BOOST_STM_NEW_1(P) \
- ((boost::stm::transaction::current_transaction()!=0)?BOOST_STM_NEW(*boost::stm::transaction::current_transaction(), P):new P)
+//--------------------------------------------------------------------------
-///////////////////////////////////////////////////////////////////////////////
namespace test {
template <typename T>
class list_node
@@ -47,7 +39,7 @@
tx_ptr<list_node<T> > next_;
};
-////////////////////////////////////////////////////////////////////////////
+//--------------------------------------------------------------------------
template <typename T>
class list
{
@@ -63,7 +55,7 @@
~list() { }
- std::size_t size() {
+ std::size_t size() const {
std::size_t res=0;
use_atomic(_) {
rd_ptr<std::size_t> s(_, size_);
@@ -77,9 +69,11 @@
//--------------------------------------------------------------------------
void insert(const T& val) {
use_atomic(_) {
+ cerr << "try" << endl;
upgrd_ptr<list_node<T> > prev(_, head_);
upgrd_ptr<list_node<T> > curr(_, head_->next_);
while (curr) {
+ cerr << "curr" << curr << endl;
if (curr->value_ == val) return;
else if (curr->value_ > val) break;
prev = curr;
@@ -138,21 +132,34 @@
};
}
+//--------------------------------------------------------------------------
+
tx_ptr<test::list<int> > l;
+void create() {
+ //l=boost::stm::make_tx_ptr<test::list<int> >();
+ atomic(_) {
+ cerr << "create" << endl;
+ l=BOOST_STM_NEW(_,transactional_object<test::list<int> >());
+ cerr << "create" << endl;
+ cerr << l->size() << endl;
+ } catch (...) {
+ cerr << "aborted" << endl;
+ }
+ cerr << l->size() << endl;
+}
void insert1() {
thread_initializer thi;
- use_atomic(_) {
- //wr_ptr<test::list<int> > w(_,l);
- //w->insert(1);
+ atomic(_) {
+ cerr << "try" << endl;
make_wr_ptr(_,l)->insert(1);
+ } catch(...) {
+ cerr << "aborted" << endl;
}
}
void insert2() {
thread_initializer thi;
use_atomic(_) {
- //wr_ptr<test::list<int> > w(_,l);
- //w->insert(2);
make_wr_ptr(_,l)->insert(2);
}
}
@@ -160,13 +167,20 @@
void insert3() {
thread_initializer thi;
use_atomic(_) {
- //wr_ptr<test::list<int> > w(_,l);
- //w->insert(3);
make_wr_ptr(_,l)->insert(3);
}
}
+bool check_size(std::size_t val) {
+ int res;
+ use_atomic(_) {
+ cerr << "size" <<make_rd_ptr(_,l)->size()<< endl;
+ res = make_rd_ptr(_,l)->size()==val;
+ }
+ return res;
+}
int test1() {
- l=boost::stm::make_tx_ptr<test::list<int> >();
+ create();
+ #if 1
thread th1(insert1);
//thread th2(insert2);
//thread th3(insert2);
@@ -176,9 +190,11 @@
//th2.join();
//th3.join();
//th4.join();
- int res = (l->size()==1?0:1);
+ #endif
+ bool fails=true;
+ fails= !check_size(1);
//boost::stm::delete_ptr(l);
- return res;
+ return fails;
}
int main() {
Modified: sandbox/stm/branches/vbe/libs/stm/test/Jamfile.v2
==============================================================================
--- sandbox/stm/branches/vbe/libs/stm/test/Jamfile.v2 (original)
+++ sandbox/stm/branches/vbe/libs/stm/test/Jamfile.v2 2009-09-05 20:08:25 EDT (Sat, 05 Sep 2009)
@@ -44,7 +44,8 @@
test-suite "tests"
:
- #[ run stm.cpp testatom.cpp pointer_test.cpp smart.cpp globalIntArr.cpp testHashMapAndLinkedListsWithLocks.cpp irrevocableInt.cpp testHashMapWithLocks.cpp isolatedComposedIntLockInTx.cpp testInt.cpp isolatedComposedIntLockInTx2.cpp testLL_latm.cpp isolatedInt.cpp testLinkedList.cpp isolatedIntLockInTx.cpp testLinkedListWithLocks.cpp litExample.cpp testPerson.cpp lotExample.cpp testRBTree.cpp transferFun.cpp nestedTxs.cpp txLinearLock.cpp testHT_latm.cpp usingLockTx.cpp testHashMap.cpp ]
- #[ run ../example/bank.cpp ]
- [ run ../example/list.cpp ]
+ [ run stm.cpp testatom.cpp pointer_test.cpp smart.cpp globalIntArr.cpp testHashMapAndLinkedListsWithLocks.cpp irrevocableInt.cpp testHashMapWithLocks.cpp isolatedComposedIntLockInTx.cpp testInt.cpp isolatedComposedIntLockInTx2.cpp testLL_latm.cpp isolatedInt.cpp testLinkedList.cpp isolatedIntLockInTx.cpp testLinkedListWithLocks.cpp litExample.cpp testPerson.cpp lotExample.cpp testRBTree.cpp transferFun.cpp nestedTxs.cpp txLinearLock.cpp testHT_latm.cpp usingLockTx.cpp testHashMap.cpp ]
+ [ run ../example/bank.cpp ]
+ #[ run ../example/list.cpp ]
+ [ run ../example/counter.cpp ]
;
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