source: NonGTP/Boost/boost/detail/sp_counted_base_gcc_ppc.hpp @ 857

Revision 857, 3.5 KB checked in by igarcia, 19 years ago (diff)
Line 
1#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
2#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_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//
11//  detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
12//
13//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
14//  Copyright 2004-2005 Peter Dimov
15//
16//  Distributed under the Boost Software License, Version 1.0. (See
17//  accompanying file LICENSE_1_0.txt or copy at
18//  http://www.boost.org/LICENSE_1_0.txt)
19//
20//
21//  Lock-free algorithm by Alexander Terekhov
22//
23//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
24//  formulation
25//
26
27#include <typeinfo>
28
29namespace boost
30{
31
32namespace detail
33{
34
35inline void atomic_increment( int * pw )
36{
37    // ++*pw;
38
39    int tmp;
40
41    __asm__
42    (
43        "0:\n\t"
44        "lwarx %1, 0, %2\n\t"
45        "addi %1, %1, 1\n\t"
46        "stwcx. %1, 0, %2\n\t"
47        "bne- 0b":
48
49        "=m"( *pw ), "=&b"( tmp ):
50        "r"( pw ):
51        "cc"
52    );
53}
54
55inline int atomic_decrement( int * pw )
56{
57    // return --*pw;
58
59    int rv;
60
61    __asm__ __volatile__
62    (
63        "sync\n\t"
64        "0:\n\t"
65        "lwarx %1, 0, %2\n\t"
66        "addi %1, %1, -1\n\t"
67        "stwcx. %1, 0, %2\n\t"
68        "bne- 0b\n\t"
69        "isync":
70
71        "=m"( *pw ), "=&b"( rv ):
72        "r"( pw ):
73        "memory", "cc"
74    );
75
76    return rv;
77}
78
79inline int atomic_conditional_increment( int * pw )
80{
81    // if( *pw != 0 ) ++*pw;
82    // return *pw;
83
84    int rv;
85
86    __asm__
87    (
88        "0:\n\t"
89        "lwarx %1, 0, %2\n\t"
90        "cmpwi %1, 0\n\t"
91        "beq 1f\n\t"
92        "addi %1, %1, 1\n\t"
93        "1:\n\t"
94        "stwcx. %1, 0, %2\n\t"
95        "bne- 0b":
96
97        "=m"( *pw ), "=&b"( rv ):
98        "r"( pw ):
99        "cc"
100    );
101
102    return rv;
103}
104
105class sp_counted_base
106{
107private:
108
109    sp_counted_base( sp_counted_base const & );
110    sp_counted_base & operator= ( sp_counted_base const & );
111
112    int use_count_;        // #shared
113    int weak_count_;       // #weak + (#shared != 0)
114
115public:
116
117    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
118    {
119    }
120
121    virtual ~sp_counted_base() // nothrow
122    {
123    }
124
125    // dispose() is called when use_count_ drops to zero, to release
126    // the resources managed by *this.
127
128    virtual void dispose() = 0; // nothrow
129
130    // destroy() is called when weak_count_ drops to zero.
131
132    virtual void destroy() // nothrow
133    {
134        delete this;
135    }
136
137    virtual void * get_deleter( std::type_info const & ti ) = 0;
138
139    void add_ref_copy()
140    {
141        atomic_increment( &use_count_ );
142    }
143
144    bool add_ref_lock() // true on success
145    {
146        return atomic_conditional_increment( &use_count_ ) != 0;
147    }
148
149    void release() // nothrow
150    {
151        if( atomic_decrement( &use_count_ ) == 0 )
152        {
153            dispose();
154            weak_release();
155        }
156    }
157
158    void weak_add_ref() // nothrow
159    {
160        atomic_increment( &weak_count_ );
161    }
162
163    void weak_release() // nothrow
164    {
165        if( atomic_decrement( &weak_count_ ) == 0 )
166        {
167            destroy();
168        }
169    }
170
171    long use_count() const // nothrow
172    {
173        return static_cast<int const volatile &>( use_count_ );
174    }
175};
176
177} // namespace detail
178
179} // namespace boost
180
181#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.