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