source: vendor/nemo/current/NEMOGCM/EXTERNAL/XIOS/extern/boost/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.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.0 KB
Line 
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
2#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
3
4//
5//  detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64
6//
7//  Copyright 2007 Baruch Zilber
8//  Copyright 2007 Boris Gubenko
9//
10//  Distributed under the Boost Software License, Version 1.0. (See
11//  accompanying file LICENSE_1_0.txt or copy at
12//  http://www.boost.org/LICENSE_1_0.txt)
13//
14//
15//  Lock-free algorithm by Alexander Terekhov
16//
17
18#include <boost/detail/sp_typeinfo.hpp>
19#include <machine/sys/inline.h>
20
21namespace boost
22{
23
24namespace detail
25{
26
27inline void atomic_increment( int * pw )
28{
29    // ++*pw;
30
31    _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE);
32} 
33
34inline int atomic_decrement( int * pw )
35{
36    // return --*pw;
37
38    int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE));
39    if (1 == r)
40    {
41        _Asm_mf();
42    }
43   
44    return r - 1;
45}
46
47inline int atomic_conditional_increment( int * pw )
48{
49    // if( *pw != 0 ) ++*pw;
50    // return *pw;
51
52    int v = *pw;
53   
54    for (;;)
55    {
56        if (0 == v)
57        {
58            return 0;
59        }
60       
61        _Asm_mov_to_ar(_AREG_CCV,
62                       v,
63                       (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE));
64        int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE));
65        if (r == v)
66        {
67            return r + 1;
68        }
69       
70        v = r;
71    }
72}
73
74class sp_counted_base
75{
76private:
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
84public:
85
86    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
87    {
88    }
89
90    virtual ~sp_counted_base() // nothrow
91    {
92    }
93
94    // dispose() is called when use_count_ drops to zero, to release
95    // the resources managed by *this.
96
97    virtual void dispose() = 0; // nothrow
98
99    // destroy() is called when weak_count_ drops to zero.
100
101    virtual void destroy() // nothrow
102    {
103        delete this;
104    }
105
106    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
107
108    void add_ref_copy()
109    {
110        atomic_increment( &use_count_ );
111    }
112
113    bool add_ref_lock() // true on success
114    {
115        return atomic_conditional_increment( &use_count_ ) != 0;
116    }
117
118    void release() // nothrow
119    {
120        if( atomic_decrement( &use_count_ ) == 0 )
121        {
122            dispose();
123            weak_release();
124        }
125    }
126
127    void weak_add_ref() // nothrow
128    {
129        atomic_increment( &weak_count_ );
130    }
131
132    void weak_release() // nothrow
133    {
134        if( atomic_decrement( &weak_count_ ) == 0 )
135        {
136            destroy();
137        }
138    }
139
140    long use_count() const // nothrow
141    {
142        return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
143    }
144};
145
146} // namespace detail
147
148} // namespace boost
149
150#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.