File: interlocked.hpp

package info (click to toggle)
supercollider 1%3A3.11.2%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 71,152 kB
  • sloc: cpp: 387,846; lisp: 80,328; ansic: 76,515; sh: 22,779; python: 7,932; makefile: 2,333; perl: 1,123; javascript: 915; java: 677; xml: 582; yacc: 314; lex: 175; objc: 152; ruby: 136
file content (212 lines) | stat: -rwxr-xr-x 5,174 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 *
 * (C) Copyright 2005-8 Anthony Williams
 * (C) Copyright 2012-2013 Vicente J. Botet Escriba
 * (C) Copyright 2013 Andrey Semashev
 */
/*!
 * \file   interlocked.hpp
 *
 * \brief  This header is the Boost.Sync library implementation, see the library documentation
 *         at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
 */

#ifndef BOOST_SYNC_DETAIL_INTERLOCKED_HPP_INCLUDED_
#define BOOST_SYNC_DETAIL_INTERLOCKED_HPP_INCLUDED_

#include <boost/atomic/detail/interlocked.hpp>
#include <boost/sync/detail/config.hpp>
#include <boost/sync/detail/header.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

namespace sync {

namespace detail {

namespace windows {

#if defined(BOOST_MSVC) && (_MSC_VER >= 1400) && !defined(UNDER_CE)

#if _MSC_VER == 1400
extern "C" unsigned char _interlockedbittestandset(long *a, long b);
extern "C" unsigned char _interlockedbittestandreset(long *a, long b);
#else
extern "C" unsigned char _interlockedbittestandset(volatile long *a, long b);
extern "C" unsigned char _interlockedbittestandreset(volatile long *a, long b);
#endif

#pragma intrinsic(_interlockedbittestandset)
#pragma intrinsic(_interlockedbittestandreset)

BOOST_FORCEINLINE bool interlocked_bit_test_and_set(long* x, long bit) BOOST_NOEXCEPT
{
    return _interlockedbittestandset(x, bit) != 0;
}

BOOST_FORCEINLINE bool interlocked_bit_test_and_reset(long* x, long bit) BOOST_NOEXCEPT
{
    return _interlockedbittestandreset(x, bit) != 0;
}

#define BOOST_SYNC_DETAIL_BTS_DEFINED

#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)

BOOST_FORCEINLINE bool interlocked_bit_test_and_set(long* x, long bit) BOOST_NOEXCEPT
{
#ifndef BOOST_INTEL_CXX_VERSION
    __asm
    {
        mov eax,bit;
        mov edx,x;
        lock bts [edx], eax;
        setc al;
    };
#else
    bool ret;
    __asm
    {
        mov eax,bit
        mov edx,x
        lock bts [edx], eax
        setc ret
    };
    return ret;
#endif
}

BOOST_FORCEINLINE bool interlocked_bit_test_and_reset(long* x, long bit) BOOST_NOEXCEPT
{
#ifndef BOOST_INTEL_CXX_VERSION
    __asm
    {
        mov eax,bit;
        mov edx,x;
        lock btr [edx],eax;
        setc al;
    };
#else
    bool ret;
    __asm
    {
        mov eax,bit
        mov edx,x
        lock btr [edx],eax
        setc ret
    };
    return ret;
#endif
}

#define BOOST_SYNC_DETAIL_BTS_DEFINED
#endif

#ifndef BOOST_SYNC_DETAIL_BTS_DEFINED

BOOST_FORCEINLINE bool interlocked_bit_test_and_set(long* x, long bit) BOOST_NOEXCEPT
{
    long const value = 1 << bit;
    long old = *x;
    while (true)
    {
        long const current = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(x, old | value, old);
        if (current == old)
            break;
        old = current;
    }
    return (old & value) != 0;
}

BOOST_FORCEINLINE bool interlocked_bit_test_and_reset(long* x, long bit) BOOST_NOEXCEPT
{
    long const value = 1 << bit;
    long old = *x;
    while (true)
    {
        long const current = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(x, old & ~value, old);
        if (current == old)
            break;
        old = current;
    }
    return (old & value) != 0;
}

#endif

#undef BOOST_SYNC_DETAIL_BTS_DEFINED

#if defined(__INTEL_COMPILER)
#define BOOST_SYNC_COMPILER_BARRIER() __memory_barrier()
#elif defined(_MSC_VER) && _MSC_VER >= 1310 && !defined(_WIN32_WCE)
extern "C" void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
#define BOOST_SYNC_COMPILER_BARRIER() _ReadWriteBarrier()
#endif

#ifdef BOOST_SYNC_COMPILER_BARRIER

BOOST_FORCEINLINE long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
{
    long const res = *x;
    BOOST_SYNC_COMPILER_BARRIER();
    return res;
}
BOOST_FORCEINLINE void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
{
    void* const res = *x;
    BOOST_SYNC_COMPILER_BARRIER();
    return res;
}

BOOST_FORCEINLINE void interlocked_write_release(long volatile* x, long value) BOOST_NOEXCEPT
{
    BOOST_SYNC_COMPILER_BARRIER();
    *x = value;
}
BOOST_FORCEINLINE void interlocked_write_release(void* volatile* x, void* value) BOOST_NOEXCEPT
{
    BOOST_SYNC_COMPILER_BARRIER();
    *x = value;
}

#else

BOOST_FORCEINLINE long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
{
    return BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(x, 0);
}
BOOST_FORCEINLINE void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
{
    return BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(x, 0);
}

BOOST_FORCEINLINE void interlocked_write_release(long volatile* x, long value) BOOST_NOEXCEPT
{
    BOOST_ATOMIC_INTERLOCKED_EXCHANGE(x, value);
}
BOOST_FORCEINLINE void interlocked_write_release(void* volatile* x, void* value) BOOST_NOEXCEPT
{
    BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(x, value);
}

#endif

} // namespace windows

} // namespace detail

} // namespace sync

} // namespace boost

#include <boost/sync/detail/footer.hpp>

#endif // BOOST_SYNC_DETAIL_INTERLOCKED_HPP_INCLUDED_