$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: Boris.Gubenko_at_[hidden]
Date: 2007-10-30 08:48:44
Author: bgubenko
Date: 2007-10-30 08:48:44 EDT (Tue, 30 Oct 2007)
New Revision: 40604
URL: http://svn.boost.org/trac/boost/changeset/40604
Log:
add support for aC++ on HP-UX ia64
Added:
   trunk/boost/detail/sp_counted_base_acc_ia64.hpp   (contents, props changed)
Added: trunk/boost/detail/sp_counted_base_acc_ia64.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/detail/sp_counted_base_acc_ia64.hpp	2007-10-30 08:48:44 EDT (Tue, 30 Oct 2007)
@@ -0,0 +1,150 @@
+#ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
+#define BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
+
+//
+//  detail/sp_counted_base_gcc_ia64.hpp - aC++ on HP-UX IA64
+//
+//  Copyright 2007 Baruch Zilber
+//  Copyright 2007 Boris Gubenko
+//
+//  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)
+//
+//
+//  Lock-free algorithm by Alexander Terekhov
+//
+
+#include "sp_typeinfo.hpp"
+#include <machine/sys/inline.h>
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void atomic_increment( int * pw )
+{
+    // ++*pw;
+
+    _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
+} 
+
+inline int atomic_decrement( int * pw )
+{
+    // return --*pw;
+
+    int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
+    if (1 == r)
+    {
+        _Asm_mf();
+    }
+    
+    return r - 1;
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+    // if( *pw != 0 ) ++*pw;
+    // return *pw;
+
+    int v = *pw;
+    
+    for (;;)
+    {
+        if (0 == v)
+        {
+            return 0;
+        }
+        
+        _Asm_mov_to_ar(_AREG_CCV,
+                       v,
+                       (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
+        int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
+        if (r == v)
+        {
+            return r + 1;
+        }
+        
+        v = r;
+    }
+}
+
+class sp_counted_base
+{
+private:
+
+    sp_counted_base( sp_counted_base const & );
+    sp_counted_base & operator= ( sp_counted_base const & );
+
+    int use_count_;        // #shared
+    int weak_count_;       // #weak + (#shared != 0)
+
+public:
+
+    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+    {
+    }
+
+    virtual ~sp_counted_base() // nothrow
+    {
+    }
+
+    // dispose() is called when use_count_ drops to zero, to release
+    // the resources managed by *this.
+
+    virtual void dispose() = 0; // nothrow
+
+    // destroy() is called when weak_count_ drops to zero.
+
+    virtual void destroy() // nothrow
+    {
+        delete this;
+    }
+
+    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+
+    void add_ref_copy()
+    {
+        atomic_increment( &use_count_ );
+    }
+
+    bool add_ref_lock() // true on success
+    {
+        return atomic_conditional_increment( &use_count_ ) != 0;
+    }
+
+    void release() // nothrow
+    {
+        if( atomic_decrement( &use_count_ ) == 0 )
+        {
+            dispose();
+            weak_release();
+        }
+    }
+
+    void weak_add_ref() // nothrow
+    {
+        atomic_increment( &weak_count_ );
+    }
+
+    void weak_release() // nothrow
+    {
+        if( atomic_decrement( &weak_count_ ) == 0 )
+        {
+            destroy();
+        }
+    }
+
+    long use_count() const // nothrow
+    {
+        return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
+    }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED