Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / atomic / detail / linux-arm.hpp @ 2486

History | View | Annotate | Download (5.2 kB)

1 2486 sjacqu01
#ifndef BOOST_ATOMIC_DETAIL_LINUX_ARM_HPP
2 2486 sjacqu01
#define BOOST_ATOMIC_DETAIL_LINUX_ARM_HPP
3 2486 sjacqu01
4 2486 sjacqu01
//  Distributed under the Boost Software License, Version 1.0.
5 2486 sjacqu01
//  See accompanying file LICENSE_1_0.txt or copy at
6 2486 sjacqu01
//  http://www.boost.org/LICENSE_1_0.txt)
7 2486 sjacqu01
//
8 2486 sjacqu01
//  Copyright (c) 2009, 2011 Helge Bahmann
9 2486 sjacqu01
//  Copyright (c) 2009 Phil Endecott
10 2486 sjacqu01
//  Copyright (c) 2013 Tim Blechmann
11 2486 sjacqu01
//  Linux-specific code by Phil Endecott
12 2486 sjacqu01
13 2486 sjacqu01
// Different ARM processors have different atomic instructions.  In particular,
14 2486 sjacqu01
// architecture versions before v6 (which are still in widespread use, e.g. the
15 2486 sjacqu01
// Intel/Marvell XScale chips like the one in the NSLU2) have only atomic swap.
16 2486 sjacqu01
// On Linux the kernel provides some support that lets us abstract away from
17 2486 sjacqu01
// these differences: it provides emulated CAS and barrier functions at special
18 2486 sjacqu01
// addresses that are guaranteed not to be interrupted by the kernel.  Using
19 2486 sjacqu01
// this facility is slightly slower than inline assembler would be, but much
20 2486 sjacqu01
// faster than a system call.
21 2486 sjacqu01
//
22 2486 sjacqu01
// While this emulated CAS is "strong" in the sense that it does not fail
23 2486 sjacqu01
// "spuriously" (i.e.: it never fails to perform the exchange when the value
24 2486 sjacqu01
// found equals the value expected), it does not return the found value on
25 2486 sjacqu01
// failure. To satisfy the atomic API, compare_exchange_{weak|strong} must
26 2486 sjacqu01
// return the found value on failure, and we have to manually load this value
27 2486 sjacqu01
// after the emulated CAS reports failure. This in turn introduces a race
28 2486 sjacqu01
// between the CAS failing (due to the "wrong" value being found) and subsequently
29 2486 sjacqu01
// loading (which might turn up the "right" value). From an application's
30 2486 sjacqu01
// point of view this looks like "spurious failure", and therefore the
31 2486 sjacqu01
// emulated CAS is only good enough to provide compare_exchange_weak
32 2486 sjacqu01
// semantics.
33 2486 sjacqu01
34 2486 sjacqu01
#include <cstddef>
35 2486 sjacqu01
#include <boost/cstdint.hpp>
36 2486 sjacqu01
#include <boost/memory_order.hpp>
37 2486 sjacqu01
#include <boost/atomic/detail/config.hpp>
38 2486 sjacqu01
39 2486 sjacqu01
#ifdef BOOST_HAS_PRAGMA_ONCE
40 2486 sjacqu01
#pragma once
41 2486 sjacqu01
#endif
42 2486 sjacqu01
43 2486 sjacqu01
namespace boost {
44 2486 sjacqu01
namespace atomics {
45 2486 sjacqu01
namespace detail {
46 2486 sjacqu01
47 2486 sjacqu01
inline void
48 2486 sjacqu01
arm_barrier(void)
49 2486 sjacqu01
{
50 2486 sjacqu01
    void (*kernel_dmb)(void) = (void (*)(void)) 0xffff0fa0;
51 2486 sjacqu01
    kernel_dmb();
52 2486 sjacqu01
}
53 2486 sjacqu01
54 2486 sjacqu01
inline void
55 2486 sjacqu01
platform_fence_before(memory_order order)
56 2486 sjacqu01
{
57 2486 sjacqu01
    switch(order) {
58 2486 sjacqu01
        case memory_order_release:
59 2486 sjacqu01
        case memory_order_acq_rel:
60 2486 sjacqu01
        case memory_order_seq_cst:
61 2486 sjacqu01
            arm_barrier();
62 2486 sjacqu01
        case memory_order_consume:
63 2486 sjacqu01
        default:;
64 2486 sjacqu01
    }
65 2486 sjacqu01
}
66 2486 sjacqu01
67 2486 sjacqu01
inline void
68 2486 sjacqu01
platform_fence_after(memory_order order)
69 2486 sjacqu01
{
70 2486 sjacqu01
    switch(order) {
71 2486 sjacqu01
        case memory_order_acquire:
72 2486 sjacqu01
        case memory_order_acq_rel:
73 2486 sjacqu01
        case memory_order_seq_cst:
74 2486 sjacqu01
            arm_barrier();
75 2486 sjacqu01
        default:;
76 2486 sjacqu01
    }
77 2486 sjacqu01
}
78 2486 sjacqu01
79 2486 sjacqu01
inline void
80 2486 sjacqu01
platform_fence_before_store(memory_order order)
81 2486 sjacqu01
{
82 2486 sjacqu01
    platform_fence_before(order);
83 2486 sjacqu01
}
84 2486 sjacqu01
85 2486 sjacqu01
inline void
86 2486 sjacqu01
platform_fence_after_store(memory_order order)
87 2486 sjacqu01
{
88 2486 sjacqu01
    if (order == memory_order_seq_cst)
89 2486 sjacqu01
        arm_barrier();
90 2486 sjacqu01
}
91 2486 sjacqu01
92 2486 sjacqu01
inline void
93 2486 sjacqu01
platform_fence_after_load(memory_order order)
94 2486 sjacqu01
{
95 2486 sjacqu01
    platform_fence_after(order);
96 2486 sjacqu01
}
97 2486 sjacqu01
98 2486 sjacqu01
template<typename T>
99 2486 sjacqu01
inline bool
100 2486 sjacqu01
platform_cmpxchg32(T & expected, T desired, volatile T * ptr)
101 2486 sjacqu01
{
102 2486 sjacqu01
    typedef T (*kernel_cmpxchg32_t)(T oldval, T newval, volatile T * ptr);
103 2486 sjacqu01
104 2486 sjacqu01
    if (((kernel_cmpxchg32_t) 0xffff0fc0)(expected, desired, ptr) == 0) {
105 2486 sjacqu01
        return true;
106 2486 sjacqu01
    } else {
107 2486 sjacqu01
        expected = *ptr;
108 2486 sjacqu01
        return false;
109 2486 sjacqu01
    }
110 2486 sjacqu01
}
111 2486 sjacqu01
112 2486 sjacqu01
}
113 2486 sjacqu01
}
114 2486 sjacqu01
115 2486 sjacqu01
#define BOOST_ATOMIC_THREAD_FENCE 2
116 2486 sjacqu01
inline void
117 2486 sjacqu01
atomic_thread_fence(memory_order order)
118 2486 sjacqu01
{
119 2486 sjacqu01
    switch(order) {
120 2486 sjacqu01
        case memory_order_acquire:
121 2486 sjacqu01
        case memory_order_release:
122 2486 sjacqu01
        case memory_order_acq_rel:
123 2486 sjacqu01
        case memory_order_seq_cst:
124 2486 sjacqu01
            atomics::detail::arm_barrier();
125 2486 sjacqu01
        default:;
126 2486 sjacqu01
    }
127 2486 sjacqu01
}
128 2486 sjacqu01
129 2486 sjacqu01
#define BOOST_ATOMIC_SIGNAL_FENCE 2
130 2486 sjacqu01
inline void
131 2486 sjacqu01
atomic_signal_fence(memory_order)
132 2486 sjacqu01
{
133 2486 sjacqu01
    __asm__ __volatile__ ("" ::: "memory");
134 2486 sjacqu01
}
135 2486 sjacqu01
136 2486 sjacqu01
class atomic_flag
137 2486 sjacqu01
{
138 2486 sjacqu01
private:
139 2486 sjacqu01
    atomic_flag(const atomic_flag &) /* = delete */ ;
140 2486 sjacqu01
    atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
141 2486 sjacqu01
    uint32_t v_;
142 2486 sjacqu01
public:
143 2486 sjacqu01
    BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
144 2486 sjacqu01
145 2486 sjacqu01
    void
146 2486 sjacqu01
    clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
147 2486 sjacqu01
    {
148 2486 sjacqu01
        atomics::detail::platform_fence_before_store(order);
149 2486 sjacqu01
        const_cast<volatile uint32_t &>(v_) = 0;
150 2486 sjacqu01
        atomics::detail::platform_fence_after_store(order);
151 2486 sjacqu01
    }
152 2486 sjacqu01
153 2486 sjacqu01
    bool
154 2486 sjacqu01
    test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
155 2486 sjacqu01
    {
156 2486 sjacqu01
        atomics::detail::platform_fence_before(order);
157 2486 sjacqu01
        uint32_t expected = v_;
158 2486 sjacqu01
        do {
159 2486 sjacqu01
            if (expected == 1)
160 2486 sjacqu01
                break;
161 2486 sjacqu01
        } while (!atomics::detail::platform_cmpxchg32(expected, (uint32_t)1, &v_));
162 2486 sjacqu01
        atomics::detail::platform_fence_after(order);
163 2486 sjacqu01
        return expected;
164 2486 sjacqu01
    }
165 2486 sjacqu01
};
166 2486 sjacqu01
167 2486 sjacqu01
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2
168 2486 sjacqu01
169 2486 sjacqu01
}
170 2486 sjacqu01
171 2486 sjacqu01
#include <boost/atomic/detail/base.hpp>
172 2486 sjacqu01
173 2486 sjacqu01
#if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
174 2486 sjacqu01
175 2486 sjacqu01
#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
176 2486 sjacqu01
#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2
177 2486 sjacqu01
#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2
178 2486 sjacqu01
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
179 2486 sjacqu01
#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
180 2486 sjacqu01
#define BOOST_ATOMIC_INT_LOCK_FREE 2
181 2486 sjacqu01
#define BOOST_ATOMIC_LONG_LOCK_FREE 2
182 2486 sjacqu01
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
183 2486 sjacqu01
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
184 2486 sjacqu01
#define BOOST_ATOMIC_BOOL_LOCK_FREE 2
185 2486 sjacqu01
186 2486 sjacqu01
#include <boost/atomic/detail/cas32weak.hpp>
187 2486 sjacqu01
188 2486 sjacqu01
#endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
189 2486 sjacqu01
190 2486 sjacqu01
#endif