$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r56991 - in sandbox/stm/branches/vbe: boost/stm boost/stm/detail boost/synchro boost/synchro/pthread libs/stm/src
From: vicente.botet_at_[hidden]
Date: 2009-10-18 19:03:03
Author: viboes
Date: 2009-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
New Revision: 56991
URL: http://svn.boost.org/trac/boost/changeset/56991
Log:
TBoost.STM vbe: 
* Added implicit_thread_specific_storage (tss.hpp)
* Change current_transaction implementation using implicit_thread_specific_storage
* synchro.hpp cleanup
* pthread mutex robustness
Added:
   sandbox/stm/branches/vbe/boost/synchro/tss.hpp   (contents, props changed)
Text files modified: 
   sandbox/stm/branches/vbe/boost/stm/detail/config.hpp           |     2                                         
   sandbox/stm/branches/vbe/boost/stm/detail/transaction_impl.hpp |    14 +++-----                                
   sandbox/stm/branches/vbe/boost/stm/synchro.hpp                 |    53 ++++++++++++---------------------       
   sandbox/stm/branches/vbe/boost/stm/transaction.hpp             |    62 +++++++-------------------------------- 
   sandbox/stm/branches/vbe/boost/synchro/pthread/mutex.hpp       |    11 +++---                                  
   sandbox/stm/branches/vbe/libs/stm/src/transaction.cpp          |    16 +---------                              
   6 files changed, 45 insertions(+), 113 deletions(-)
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-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -34,7 +34,7 @@
 //      OTHER: each TSS data has its specific TSS
 
 #define USE_SINGLE_THREAD_CONTEXT_MAP 1
-#define BOOST_STM_HAVE_SINGLE_TSS_CONTEXT_MAP 1
+//#define BOOST_STM_HAVE_SINGLE_TSS_CONTEXT_MAP 1
 
 
 ///////////////////////////////////////////////////////////////////////////////
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-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -444,8 +444,6 @@
    currentlyLockedLocksRef_(*threadCurrentlyLockedLocks_.find(threadId_)->second),
 #endif
 #endif
-   transactionsRef_(transactions_unsafe(threadId_)),
-
 ////////////////////////////////////////
 #else
 ////////////////////////////////////////
@@ -481,11 +479,9 @@
    currentlyLockedLocksRef_(*threadCurrentlyLockedLocks_.find(threadId_)->second),
 #endif
 ////////////////////////////////////////
-   transactionsRef_(transactions_unsafe(threadId_)),
-
 #endif
-
-   //hasMutex_(0), 
+    transaction_tss_storage_ref_(*transaction_tss_storage_),
+   //hasMutex_(0),
    priority_(0),
    state_(e_no_state),
    reads_(0),
@@ -706,8 +702,8 @@
       return;
    }
 
-    //if (!hasLock()) 
-    { 
+    //if (!hasLock())
+    {
        synchro::lock_guard<Mutex> lock(*mutex());
         abort();
     }
@@ -813,7 +809,7 @@
       direct_abort();
       //unlock_tx();
       synchro::unlock(*mutex());
-      
+
       //-----------------------------------------------------------------------
       // if this tx was writing, unlock the transaction mutex now
       //-----------------------------------------------------------------------
Modified: sandbox/stm/branches/vbe/boost/stm/synchro.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/synchro.hpp	(original)
+++ sandbox/stm/branches/vbe/boost/stm/synchro.hpp	2009-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -14,30 +14,17 @@
 #ifndef BOOST_STM_SYNCHO__HPP
 #define BOOST_STM_SYNCHO__HPP
 
-#include <boost/stm/detail/config.hpp>
-
-#ifdef BOOST_STM_USE_BOOST_SYNCHRO
-#include <boost/synchro.hpp>
-#endif
-
 //-----------------------------------------------------------------------------
-#include <stdarg.h>
 #include <pthread.h>
 //-----------------------------------------------------------------------------
-#include <list>
-#include <stdexcept>
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//#include <boost/stm/exceptions.hpp>
-//-----------------------------------------------------------------------------
-//#include <boost/stm/detail/memory_pool.hpp>
+#include <boost/stm/detail/config.hpp>
 //-----------------------------------------------------------------------------
-
-#ifdef BOOST_STM_USE_BOOST
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread_time.hpp>
+#ifdef BOOST_STM_USE_BOOST_SYNCHRO
+#include <boost/synchro.hpp>
+#else
+#include <stdexcept>
 #endif
+//-----------------------------------------------------------------------------
 
 #ifndef BOOST_STM_USE_BOOST_MUTEX
    typedef pthread_mutex_t Mutex;
@@ -49,7 +36,7 @@
 
 //-----------------------------------------------------------------------------
 
-namespace boost { 
+namespace boost {
 #ifndef BOOST_STM_USE_BOOST_SYNCHRO
 namespace synchro {
 
@@ -60,19 +47,19 @@
         ~lock_error() throw() {}
 
         virtual const char* what() const throw() {return "synchro::lock_error";}
-    };    
-    
+    };
+
     struct defer_lock_t
     {};
     struct try_to_lock_t
     {};
     struct adopt_lock_t
     {};
-    
+
     const defer_lock_t defer_lock={};
     const try_to_lock_t try_to_lock={};
     const adopt_lock_t adopt_lock={};
-        
+
     template< typename Lockable >
     inline void lock(Lockable& lockable) {
         lockable.lock();
@@ -97,7 +84,7 @@
     inline void unlock<pthread_mutex_t>(pthread_mutex_t& lockable) {
         pthread_mutex_unlock(&lockable);
     }
-    
+
     template<>
     inline bool try_lock<pthread_mutex_t>(pthread_mutex_t& lockable) {
         return pthread_mutex_trylock(&lockable);
@@ -124,7 +111,7 @@
         {
             synchro::unlock(m);
         }
-    };    
+    };
 
     template<typename Mutex>
     class lock_guard_if
@@ -150,8 +137,8 @@
         {
             if (cnd_) synchro::unlock(m);
         }
-    };    
-    
+    };
+
     template<typename Mutex>
     class unique_lock
     {
@@ -164,13 +151,13 @@
         unique_lock():
             m(0),is_locked(false)
         {}
-        
+
         explicit unique_lock(Mutex& m_):
             m(&m_),is_locked(false)
         {
             lock();
         }
-        
+
         unique_lock(Mutex& m_,adopt_lock_t):
             m(&m_),is_locked(true)
         {}
@@ -187,7 +174,7 @@
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
-        
+
         ~unique_lock()
         {
             if(owns_lock())
@@ -222,7 +209,7 @@
             synchro::unlock(*m);
             is_locked=false;
         }
-            
+
         typedef void (unique_lock::*bool_type)();
         operator bool_type() const
         {
@@ -255,7 +242,7 @@
     void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
     {
         lhs.swap(rhs);
-    }   
+    }
 }
 #endif
 namespace stm {
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-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -30,6 +30,7 @@
 //-----------------------------------------------------------------------------
 #include <boost/stm/base_transaction.hpp>
 #include <boost/stm/transaction_bookkeeping.hpp>
+#include <boost/synchro/tss.hpp>
 //-----------------------------------------------------------------------------
 #include <boost/stm/detail/datatypes.hpp>
 #include <boost/stm/detail/deleters.hpp>
@@ -130,8 +131,10 @@
    typedef std::list<detail::deleter_type*> MemoryContainerList;
 #endif
 
+   struct transaction_tss_storage {
+       TransactionsStack transactions_;
+   };
 
-   typedef std::map<size_t, TransactionsStack*> ThreadTransactionsStack;
    typedef std::map<size_t, WriteContainer*> ThreadWriteContainer;
    typedef std::map<size_t, TxType*> ThreadTxTypeContainer;
 
@@ -199,7 +202,6 @@
     {
         inline tss_context()
         : tx_()
-        , transactions_()
         #ifndef BOOST_STM_USE_BOOST_MUTEX
         #if WIN32
         , mutex_(PTHREAD_MUTEX_INITIALIZER)
@@ -212,8 +214,6 @@
         , blocked_(false)
         #endif
         {
-            // the current transaction is 0
-            transactions_.push(0);
             #ifndef BOOST_STM_USE_BOOST_MUTEX
             pthread_mutex_init(&mutex_, 0);
             #endif
@@ -223,7 +223,6 @@
         }
 
         tx_context tx_;
-        TransactionsStack transactions_;
         Mutex mutex_;
         #if PERFORMING_LATM
         int blocked_;
@@ -1050,7 +1049,7 @@
       else
       {
          in.transaction_thread(threadId_);
-          
+
          //unlock(&transactionMutex_);
          lock_m.unlock();
          // is this really necessary? in the deferred case it is, but in direct it
@@ -1195,7 +1194,7 @@
          //unlock_tx();
          lock.unlock();
 #else
-         
+
 #endif
 #if PERFORMING_WRITE_BLOOM
          wbloom().set_bv1(bloom().h1());
@@ -1672,20 +1671,6 @@
    inline static MutexSet ¤tlyLockedLocksRef(thread_id_t id) {return *threadCurrentlyLockedLocks_.find(id)->second;}
 #endif
 
-    static ThreadTransactionsStack threadTransactionsStack_;
-    TransactionsStack& transactionsRef_;
-   public:
-    inline TransactionsStack& transactions() {return transactionsRef_;}
-    inline static TransactionsStack &transactions(thread_id_t id) {
-        synchro::lock_guard<Mutex> auto_general_lock_(*general_lock());
-        return *threadTransactionsStack_.find(id)->second;
-    }
-    inline static TransactionsStack &transactions_unsafe(thread_id_t id) {
-        //synchro::lock_guard<Mutex> auto_general_lock_(*general_lock());
-        return *threadTransactionsStack_.find(id)->second;
-    }
-    private:
-
 
 ////////////////////////////////////////
 #else //BOOST_STM_HAVE_SINGLE_TSS_CONTEXT_MAP
@@ -1844,24 +1829,8 @@
     }
 #endif
 
-    TransactionsStack& transactionsRef_;
-   public:
-    inline TransactionsStack& transactions() {return transactionsRef_;}
-    inline static TransactionsStack &transactions(thread_id_t id) {
-        synchro::lock_guard<Mutex> auto_general_lock_(*general_lock());
-        tss_context_map_type::iterator i = tss_context_map_.find(id);
-        return i->second->transactions_;
-    }
-    inline static TransactionsStack &transactions_unsafe(thread_id_t id) {
-        tss_context_map_type::iterator i = tss_context_map_.find(id);
-        return i->second->transactions_;
-    }
-   private:
-
 #endif
 
-
-
 ////////////////////////////////////////
 #else   // USE_SINGLE_THREAD_CONTEXT_MAP
 ////////////////////////////////////////
@@ -1998,23 +1967,15 @@
    inline static MutexSet ¤tlyLockedLocksRef(thread_id_t id) {return *threadCurrentlyLockedLocks_.find(id)->second;}
 #endif
 
-    static ThreadTransactionsStack threadTransactionsStack_;
-    TransactionsStack& transactionsRef_;
-   public:
-    inline TransactionsStack& transactions() {return transactionsRef_;}
-    inline static TransactionsStack &transactions(thread_id_t id) {
-        synchro::lock_guard<Mutex> auto_general_lock_(*general_lock());
-        return *threadTransactionsStack_.find(id)->second;
-    }
-    inline static TransactionsStack &transactions_unsafe(thread_id_t id) {
-        return *threadTransactionsStack_.find(id)->second;
-    }
-    private:
 
 ////////////////////////////////////////
 #endif
 
 
+    static synchro::implicit_thread_specific_ptr<transaction_tss_storage> transaction_tss_storage_;
+    transaction_tss_storage & transaction_tss_storage_ref_;
+   public:
+    inline TransactionsStack& transactions() {return transaction_tss_storage_ref_.transactions_;}
 
    // transaction specific data
    //int hasMutex_; // bool - 1 bit
@@ -2031,8 +1992,7 @@
     #endif
 
 public:
-    inline static transaction* current_transaction() {return transactions(THREAD_ID).top();}
-
+    inline static transaction* current_transaction() {return transaction_tss_storage_->transactions_.top();}
 
 };
 
Modified: sandbox/stm/branches/vbe/boost/synchro/pthread/mutex.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/synchro/pthread/mutex.hpp	(original)
+++ sandbox/stm/branches/vbe/boost/synchro/pthread/mutex.hpp	2009-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -16,6 +16,7 @@
 
 //-----------------------------------------------------------------------------
 #include <pthread.h>
+#include <assert.h>
 //-----------------------------------------------------------------------------
 #include <boost/synchro/detail/config.hpp>
 //-----------------------------------------------------------------------------
@@ -28,15 +29,15 @@
 
     template<>
     inline void lock<pthread_mutex_t>(pthread_mutex_t& lockable) {
-        //int const res=
-        pthread_mutex_lock(&lockable);
+        int const res = pthread_mutex_lock(&lockable);
+        assert(res==0);
         //if (res!=0) throw lock_error();
     }
 
     template<>
     inline void unlock<pthread_mutex_t>(pthread_mutex_t& lockable) {
-        //int const res=
-        pthread_mutex_unlock(&lockable);
+        int const res= pthread_mutex_unlock(&lockable);
+        assert(res==0);
         //if (res!=0) throw lock_error();
     }
 
@@ -53,7 +54,7 @@
                 pthread_mutex_t& lockable, system_time const& abs_time) {
         struct timespec const timeout=detail::get_timespec(abs_time);
         int const res=pthread_mutex_timedlock(&lockable,&timeout);
-        //BOOST_ASSERT(!res || res==ETIMEDOUT);
+        assert(!res || res==ETIMEDOUT);
         return !res;
     }   
 #endif
Added: sandbox/stm/branches/vbe/boost/synchro/tss.hpp
==============================================================================
--- (empty file)
+++ sandbox/stm/branches/vbe/boost/synchro/tss.hpp	2009-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Justin E. Gottchlich 2009.
+// (C) Copyright Vicente J. Botet Escriba 2009.
+// 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/stm for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_SYNCHO_TSS_HPP
+#define BOOST_SYNCHO_TSS_HPP
+
+//-----------------------------------------------------------------------------
+#include "pthread.h"
+//-----------------------------------------------------------------------------
+#include <boost/synchro/lockers/lock_guard.hpp>
+#include <boost/synchro/pthread/mutex.hpp>
+//-----------------------------------------------------------------------------
+
+namespace boost { namespace synchro {
+
+    template <typename T>
+    class implicit_thread_specific_ptr
+    {
+    private:
+        implicit_thread_specific_ptr(implicit_thread_specific_ptr&);
+        implicit_thread_specific_ptr& operator=(implicit_thread_specific_ptr&);
+
+        typedef pthread_mutex_t mutex_type;
+        // Key that uniquely identifies the 'logically global' object that
+        // 'physically' resides locally in thread-specific storage.
+        mutable pthread_key_t key_;
+
+        // "First time in" flag
+        mutable bool once_;
+
+
+        // Avoid race conditions during initialization.
+        mutable mutex_type keylock_;
+
+        // A static cleanup hook method that deletes dynamically allocated memory.
+        static void cleanup_hook (void *ptr) {
+            // This cast invokes the destructor (if one exists).
+            delete (T*) ptr;
+        }
+
+    public:
+        implicit_thread_specific_ptr()
+            : key_(0) , once_ (false)
+        {
+            int const res=pthread_mutex_init(&keylock_,0);
+            assert(res==0);
+            //if(res) throw thread_resource_error();
+        }
+        ~implicit_thread_specific_ptr() {
+            int const res=pthread_mutex_destroy(&keylock_);
+            assert(res==0);
+        }
+
+        T* get() const {
+            T *tss_data = 0;
+            // Use the Double-Checked Locking Optimization pattern to avoid excessive locking.
+            if (!once_) {
+                // Use Scoped Locking idiom to ensure <keylock_>
+                // is acquired to serialize critical section.
+                synchro::lock_guard<mutex_type> guard (keylock_);
+                if (!once_) {
+                    pthread_key_create (&key_, &cleanup_hook);
+                    // Must come last so that other threads don't use the key until it's created.
+                    once_ = true;
+                }
+                // <Guard> destructor releases the lock.
+            }
+            // Get data from thread-specific storage. Note that no locks are required,
+            // because this thread's own copy of the thread-specific object will be accessed.
+            tss_data = static_cast<T*>(pthread_getspecific (key_));
+            // Check if it's the first time in for this thread.
+            if (tss_data == 0) {
+                // Allocate memory dynamically off the heap,
+                tss_data = new T;
+                // Store pointer in thread-specific storage.
+                pthread_setspecific (key_, (void *)tss_data);
+            }
+            return tss_data;
+        }
+        T* operator->() const
+        {
+            return get();
+        }
+        T& operator*() const
+        {
+            return *get();
+        }
+    };
+}}
+#endif // BOOST_SYNCHO_TAGS_HPP
+
Modified: sandbox/stm/branches/vbe/libs/stm/src/transaction.cpp
==============================================================================
--- sandbox/stm/branches/vbe/libs/stm/src/transaction.cpp	(original)
+++ sandbox/stm/branches/vbe/libs/stm/src/transaction.cpp	2009-10-18 19:03:02 EDT (Sun, 18 Oct 2009)
@@ -24,6 +24,8 @@
 
 }
 
+synchro::implicit_thread_specific_ptr<transaction::transaction_tss_storage> transaction::transaction_tss_storage_;
+
 ///////////////////////////////////////////////////////////////////////////////
 // Static initialization
 ///////////////////////////////////////////////////////////////////////////////
@@ -33,9 +35,6 @@
 transaction::MutexThreadMap transaction::latmLockedLocksOfThreadMap_;
 transaction::MutexSet transaction::tmConflictingLocks_;
 transaction::DeletionBuffer transaction::deletionBuffer_;
-#ifndef BOOST_STM_HAVE_SINGLE_TSS_CONTEXT_MAP
-transaction::ThreadTransactionsStack transaction::threadTransactionsStack_;
-#endif
 
 size_t transaction::global_clock_ = 0;
 size_t transaction::stalls_ = 0;
@@ -235,11 +234,6 @@
       threadCurrentlyLockedLocks_[threadId] = new MutexSet;
    }
 #endif
-   ThreadTransactionsStack::iterator transactionsdIter = threadTransactionsStack_.find(threadId);
-   if (threadTransactionsStack_.end() == transactionsdIter)
-   {
-      threadTransactionsStack_[threadId] = new TransactionsStack;
-   }
 
    ThreadBoolContainer::iterator blockedIter = threadBlockedLists_.find(threadId);
 
@@ -334,12 +328,6 @@
    }
 #endif
 
-   ThreadTransactionsStack::iterator transactionsdIter = threadTransactionsStack_.find(threadId);
-   if (threadTransactionsStack_.end() == transactionsdIter)
-   {
-      threadTransactionsStack_[threadId] = new TransactionsStack;
-   }
-
    if (threadMutexes_.end() == mutexIter)
    {
       Mutex *mutex = new Mutex;