Merge c:/dyninst/pc_bluegene/dyninst into dyn_pc_integration
[dyninst.git] / external / boost / detail / sp_counted_base_solaris.hpp
1 #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
2 #define BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED
3
4 //
5 //  detail/sp_counted_base_solaris.hpp
6 //   based on: detail/sp_counted_base_w32.hpp
7 //
8 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
9 //  Copyright 2004-2005 Peter Dimov
10 //  Copyright 2006 Michael van der Westhuizen
11 //
12 //  Distributed under the Boost Software License, Version 1.0. (See
13 //  accompanying file LICENSE_1_0.txt or copy at
14 //  http://www.boost.org/LICENSE_1_0.txt)
15 //
16 //
17 //  Lock-free algorithm by Alexander Terekhov
18 //
19 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
20 //  formulation
21 //
22
23 #include <boost/detail/sp_typeinfo.hpp>
24 #include <atomic.h>
25
26 namespace boost
27 {
28
29 namespace detail
30 {
31
32 class sp_counted_base
33 {
34 private:
35
36     sp_counted_base( sp_counted_base const & );
37     sp_counted_base & operator= ( sp_counted_base const & );
38
39     uint32_t use_count_;        // #shared
40     uint32_t weak_count_;       // #weak + (#shared != 0)
41
42 public:
43
44     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
45     {
46     }
47
48     virtual ~sp_counted_base() // nothrow
49     {
50     }
51
52     // dispose() is called when use_count_ drops to zero, to release
53     // the resources managed by *this.
54
55     virtual void dispose() = 0; // nothrow
56
57     // destroy() is called when weak_count_ drops to zero.
58
59     virtual void destroy() // nothrow
60     {
61         delete this;
62     }
63
64     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
65
66     void add_ref_copy()
67     {
68         atomic_inc_32( &use_count_ );
69     }
70
71     bool add_ref_lock() // true on success
72     {
73         for( ;; )
74         {
75             uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ );
76             if( tmp == 0 ) return false;
77             if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true;
78         }
79     }
80
81     void release() // nothrow
82     {
83         if( atomic_dec_32_nv( &use_count_ ) == 0 )
84         {
85             dispose();
86             weak_release();
87         }
88     }
89
90     void weak_add_ref() // nothrow
91     {
92         atomic_inc_32( &weak_count_ );
93     }
94
95     void weak_release() // nothrow
96     {
97         if( atomic_dec_32_nv( &weak_count_ ) == 0 )
98         {
99             destroy();
100         }
101     }
102
103     long use_count() const // nothrow
104     {
105         return static_cast<long const volatile &>( use_count_ );
106     }
107 };
108
109 } // namespace detail
110
111 } // namespace boost
112
113 #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED