fixing stuff
[dyninst.git] / dynutil / h / dyn_detail / boost / detail / sp_counted_base_gcc_sparc.hpp
1 #ifndef DYN_DETAIL_BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
2 #define DYN_DETAIL_BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
3
4 // MS compatible compilers support #pragma once
5
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 # pragma once
8 #endif
9
10 //  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
11 //
12 //  Copyright (c) 2006 Piotr Wyderski
13 //  Copyright (c) 2006 Tomas Puverle
14 //  Copyright (c) 2006 Peter Dimov
15 //
16 //  Distributed under the Boost Software License, Version 1.0.
17 //  See accompanying file LICENSE_1_0.txt or copy at
18 //  http://www.boost.org/LICENSE_1_0.txt
19 //
20 //  Thanks to Michael van der Westhuizen
21
22 #include <dyn_detail/boost/detail/sp_typeinfo.hpp>
23 #include <inttypes.h> // int32_t
24
25 namespace dyn_detail
26 {
27   
28 namespace boost
29 {
30
31 namespace detail
32 {
33
34 inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
35 {
36     __asm__ __volatile__( "cas %0, %2, %1"
37                         : "+m" (*dest_), "+r" (swap_)
38                         : "r" (compare_)
39                         : "memory" );
40
41     return swap_;
42 }
43
44 inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
45 {
46     // long r = *pw;
47     // *pw += dv;
48     // return r;
49
50     for( ;; )
51     {
52         int32_t r = *pw;
53
54         if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
55         {
56             return r;
57         }
58     }
59 }
60
61 inline void atomic_increment( int32_t * pw )
62 {
63     atomic_fetch_and_add( pw, 1 );
64 }
65
66 inline int32_t atomic_decrement( int32_t * pw )
67 {
68     return atomic_fetch_and_add( pw, -1 );
69 }
70
71 inline int32_t atomic_conditional_increment( int32_t * pw )
72 {
73     // long r = *pw;
74     // if( r != 0 ) ++*pw;
75     // return r;
76
77     for( ;; )
78     {
79         int32_t r = *pw;
80
81         if( r == 0 )
82         {
83             return r;
84         }
85
86         if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
87         {
88             return r;
89         }
90     }    
91 }
92
93 class sp_counted_base
94 {
95 private:
96
97     sp_counted_base( sp_counted_base const & );
98     sp_counted_base & operator= ( sp_counted_base const & );
99
100     int32_t use_count_;        // #shared
101     int32_t weak_count_;       // #weak + (#shared != 0)
102
103 public:
104
105     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
106     {
107     }
108
109     virtual ~sp_counted_base() // nothrow
110     {
111     }
112
113     // dispose() is called when use_count_ drops to zero, to release
114     // the resources managed by *this.
115
116     virtual void dispose() = 0; // nothrow
117
118     // destroy() is called when weak_count_ drops to zero.
119
120     virtual void destroy() // nothrow
121     {
122         delete this;
123     }
124
125     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
126
127     void add_ref_copy()
128     {
129         atomic_increment( &use_count_ );
130     }
131
132     bool add_ref_lock() // true on success
133     {
134         return atomic_conditional_increment( &use_count_ ) != 0;
135     }
136
137     void release() // nothrow
138     {
139         if( atomic_decrement( &use_count_ ) == 1 )
140         {
141             dispose();
142             weak_release();
143         }
144     }
145
146     void weak_add_ref() // nothrow
147     {
148         atomic_increment( &weak_count_ );
149     }
150
151     void weak_release() // nothrow
152     {
153         if( atomic_decrement( &weak_count_ ) == 1 )
154         {
155             destroy();
156         }
157     }
158
159     long use_count() const // nothrow
160     {
161         return const_cast< int32_t const volatile & >( use_count_ );
162     }
163 };
164
165 } // namespace detail
166
167 } // namespace boost
168  
169 } // namespace dyn_detail
170
171 #endif  // #ifndef DYN_DETAIL_BOOST_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED