source: vendor/nemo/current/NEMOGCM/EXTERNAL/XIOS/extern/boost/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @ 44

Last change on this file since 44 was 44, checked in by cholod, 12 years ago

Load NEMO_TMP into vendor/nemo/current.

File size: 3.4 KB
Line 
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
2#define BOOST_SMART_PTR_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 <boost/detail/sp_typeinfo.hpp>
23#include <inttypes.h> // int32_t
24
25namespace boost
26{
27
28namespace detail
29{
30
31inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
32{
33    __asm__ __volatile__( "cas [%1], %2, %0"
34                        : "+r" (swap_)
35                        : "r" (dest_), "r" (compare_)
36                        : "memory" );
37
38    return swap_;
39}
40
41inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
42{
43    // long r = *pw;
44    // *pw += dv;
45    // return r;
46
47    for( ;; )
48    {
49        int32_t r = *pw;
50
51        if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
52        {
53            return r;
54        }
55    }
56}
57
58inline void atomic_increment( int32_t * pw )
59{
60    atomic_fetch_and_add( pw, 1 );
61}
62
63inline int32_t atomic_decrement( int32_t * pw )
64{
65    return atomic_fetch_and_add( pw, -1 );
66}
67
68inline int32_t atomic_conditional_increment( int32_t * pw )
69{
70    // long r = *pw;
71    // if( r != 0 ) ++*pw;
72    // return r;
73
74    for( ;; )
75    {
76        int32_t r = *pw;
77
78        if( r == 0 )
79        {
80            return r;
81        }
82
83        if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
84        {
85            return r;
86        }
87    }   
88}
89
90class sp_counted_base
91{
92private:
93
94    sp_counted_base( sp_counted_base const & );
95    sp_counted_base & operator= ( sp_counted_base const & );
96
97    int32_t use_count_;        // #shared
98    int32_t weak_count_;       // #weak + (#shared != 0)
99
100public:
101
102    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
103    {
104    }
105
106    virtual ~sp_counted_base() // nothrow
107    {
108    }
109
110    // dispose() is called when use_count_ drops to zero, to release
111    // the resources managed by *this.
112
113    virtual void dispose() = 0; // nothrow
114
115    // destroy() is called when weak_count_ drops to zero.
116
117    virtual void destroy() // nothrow
118    {
119        delete this;
120    }
121
122    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
123
124    void add_ref_copy()
125    {
126        atomic_increment( &use_count_ );
127    }
128
129    bool add_ref_lock() // true on success
130    {
131        return atomic_conditional_increment( &use_count_ ) != 0;
132    }
133
134    void release() // nothrow
135    {
136        if( atomic_decrement( &use_count_ ) == 1 )
137        {
138            dispose();
139            weak_release();
140        }
141    }
142
143    void weak_add_ref() // nothrow
144    {
145        atomic_increment( &weak_count_ );
146    }
147
148    void weak_release() // nothrow
149    {
150        if( atomic_decrement( &weak_count_ ) == 1 )
151        {
152            destroy();
153        }
154    }
155
156    long use_count() const // nothrow
157    {
158        return const_cast< int32_t const volatile & >( use_count_ );
159    }
160};
161
162} // namespace detail
163
164} // namespace boost
165
166#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.