]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / smart_ptr / detail / sp_counted_base_vacpp_ppc.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
3
4 //
5 //  detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
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 //  Copyright 2012 IBM Corp.
12 //
13 //  Distributed under the Boost Software License, Version 1.0. (See
14 //  accompanying file LICENSE_1_0.txt or copy at
15 //  http://www.boost.org/LICENSE_1_0.txt)
16 //
17 //
18 //  Lock-free algorithm by Alexander Terekhov
19 //
20 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
21 //  formulation
22 //
23
24 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
25 #include <boost/config.hpp>
26
27 extern "builtin" void __lwsync(void);
28 extern "builtin" void __isync(void);
29 extern "builtin" int __fetch_and_add(volatile int* addr, int val);
30 extern "builtin" int __compare_and_swap(volatile int*, int*, int);
31
32 namespace boost
33 {
34
35 namespace detail
36 {
37
38 inline void atomic_increment( int *pw )
39 {
40    // ++*pw;
41    __lwsync();
42    __fetch_and_add(pw, 1);
43    __isync();
44
45
46 inline int atomic_decrement( int *pw )
47 {
48    // return --*pw;
49    __lwsync();
50    int originalValue = __fetch_and_add(pw, -1);
51    __isync();
52
53    return (originalValue - 1);
54 }
55
56 inline int atomic_conditional_increment( int *pw )
57 {
58    // if( *pw != 0 ) ++*pw;
59    // return *pw;
60
61    __lwsync();
62    int v = *const_cast<volatile int*>(pw);
63    for (;;)
64    // loop until state is known
65    {
66       if (v == 0) return 0;
67       if (__compare_and_swap(pw, &v, v + 1))
68       {
69          __isync(); return (v + 1);
70       }
71    }
72 }
73
74 class BOOST_SYMBOL_VISIBLE sp_counted_base
75 {
76 private:
77
78     sp_counted_base( sp_counted_base const & );
79     sp_counted_base & operator= ( sp_counted_base const & );
80
81     int use_count_;        // #shared
82     int weak_count_;       // #weak + (#shared != 0)
83     char pad[64] __attribute__((__aligned__(64)));
84             // pad to prevent false sharing
85 public:
86
87     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
88     {
89     }
90
91     virtual ~sp_counted_base() // nothrow
92     {
93     }
94
95     // dispose() is called when use_count_ drops to zero, to release
96     // the resources managed by *this.
97
98     virtual void dispose() = 0; // nothrow
99
100     // destroy() is called when weak_count_ drops to zero.
101
102     virtual void destroy() // nothrow
103     {
104         delete this;
105     }
106
107     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
108     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
109     virtual void * get_untyped_deleter() = 0;
110
111     void add_ref_copy()
112     {
113         atomic_increment( &use_count_ );
114     }
115
116     bool add_ref_lock() // true on success
117     {
118         return atomic_conditional_increment( &use_count_ ) != 0;
119     }
120
121     void release() // nothrow
122     {
123         if( atomic_decrement( &use_count_ ) == 0 )
124         {
125             dispose();
126             weak_release();
127         }
128     }
129
130     void weak_add_ref() // nothrow
131     {
132         atomic_increment( &weak_count_ );
133     }
134
135     void weak_release() // nothrow
136     {
137         if( atomic_decrement( &weak_count_ ) == 0 )
138         {
139             destroy();
140         }
141     }
142
143     long use_count() const // nothrow
144     {
145         return *const_cast<volatile int*>(&use_count_); 
146     }
147 };
148
149 } // namespace detail
150
151 } // namespace boost
152
153 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED