libstdc++
shared_ptr_atomic.h
Go to the documentation of this file.
1
// shared_ptr atomic access -*- C++ -*-
2
3
// Copyright (C) 2014-2016 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library. This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
15
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23
// <http://www.gnu.org/licenses/>.
24
25
/** @file bits/shared_ptr_atomic.h
26
* This is an internal header file, included by other library headers.
27
* Do not attempt to use it directly. @headername{memory}
28
*/
29
30
#ifndef _SHARED_PTR_ATOMIC_H
31
#define _SHARED_PTR_ATOMIC_H 1
32
33
#include <
bits/atomic_base.h
>
34
35
namespace
std
_GLIBCXX_VISIBILITY(default)
36
{
37
_GLIBCXX_BEGIN_NAMESPACE_VERSION
38
39
/**
40
* @addtogroup pointer_abstractions
41
* @{
42
*/
43
44
struct
_Sp_locker
45
{
46
_Sp_locker(
const
_Sp_locker&) =
delete
;
47
_Sp_locker& operator=(
const
_Sp_locker&) =
delete
;
48
49
#ifdef __GTHREADS
50
explicit
51
_Sp_locker(
const
void
*)
noexcept
;
52
_Sp_locker(
const
void
*,
const
void
*)
noexcept
;
53
~_Sp_locker();
54
55
private
:
56
unsigned
char
_M_key1;
57
unsigned
char
_M_key2;
58
#else
59
explicit
_Sp_locker(
const
void
*,
const
void
* =
nullptr
) { }
60
#endif
61
};
62
63
/**
64
* @brief Report whether shared_ptr atomic operations are lock-free.
65
* @param __p A non-null pointer to a shared_ptr object.
66
* @return True if atomic access to @c *__p is lock-free, false otherwise.
67
* @{
68
*/
69
template
<
typename
_Tp, _Lock_policy _Lp>
70
inline
bool
71
atomic_is_lock_free(
const
__shared_ptr<_Tp, _Lp>
* __p)
72
{
73
#ifdef __GTHREADS
74
return
__gthread_active_p() == 0;
75
#else
76
return
true
;
77
#endif
78
}
79
80
template
<
typename
_Tp>
81
inline
bool
82
atomic_is_lock_free(
const
shared_ptr<_Tp>
* __p)
83
{
return
std::atomic_is_lock_free<_Tp, __default_lock_policy>
(__p); }
84
85
// @}
86
87
/**
88
* @brief Atomic load for shared_ptr objects.
89
* @param __p A non-null pointer to a shared_ptr object.
90
* @return @c *__p
91
*
92
* The memory order shall not be @c memory_order_release or
93
* @c memory_order_acq_rel.
94
* @{
95
*/
96
template
<
typename
_Tp>
97
inline
shared_ptr<_Tp>
98
atomic_load_explicit(
const
shared_ptr<_Tp>
* __p,
memory_order
)
99
{
100
_Sp_locker
__lock
{__p};
101
return
*__p;
102
}
103
104
template
<
typename
_Tp>
105
inline
shared_ptr<_Tp>
106
atomic_load(
const
shared_ptr<_Tp>
* __p)
107
{
return
std::atomic_load_explicit(__p, memory_order_seq_cst); }
108
109
template
<
typename
_Tp, _Lock_policy _Lp>
110
inline
__shared_ptr<_Tp, _Lp>
111
atomic_load_explicit(
const
__shared_ptr<_Tp, _Lp>
* __p,
memory_order
)
112
{
113
_Sp_locker
__lock
{__p};
114
return
*__p;
115
}
116
117
template
<
typename
_Tp, _Lock_policy _Lp>
118
inline
__shared_ptr<_Tp, _Lp>
119
atomic_load(
const
__shared_ptr<_Tp, _Lp>
* __p)
120
{
return
std::atomic_load_explicit(__p, memory_order_seq_cst); }
121
// @}
122
123
/**
124
* @brief Atomic store for shared_ptr objects.
125
* @param __p A non-null pointer to a shared_ptr object.
126
* @param __r The value to store.
127
*
128
* The memory order shall not be @c memory_order_acquire or
129
* @c memory_order_acq_rel.
130
* @{
131
*/
132
template
<
typename
_Tp>
133
inline
void
134
atomic_store_explicit(
shared_ptr<_Tp>
* __p,
shared_ptr<_Tp>
__r,
135
memory_order
)
136
{
137
_Sp_locker
__lock
{__p};
138
__p->swap(__r);
// use swap so that **__p not destroyed while lock held
139
}
140
141
template
<
typename
_Tp>
142
inline
void
143
atomic_store(
shared_ptr<_Tp>
* __p,
shared_ptr<_Tp>
__r)
144
{ std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); }
145
146
template
<
typename
_Tp, _Lock_policy _Lp>
147
inline
void
148
atomic_store_explicit(
__shared_ptr<_Tp, _Lp>
* __p,
149
__shared_ptr<_Tp, _Lp>
__r,
150
memory_order
)
151
{
152
_Sp_locker
__lock
{__p};
153
__p->swap(__r);
// use swap so that **__p not destroyed while lock held
154
}
155
156
template
<
typename
_Tp, _Lock_policy _Lp>
157
inline
void
158
atomic_store(
__shared_ptr<_Tp, _Lp>
* __p,
__shared_ptr<_Tp, _Lp>
__r)
159
{ std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); }
160
// @}
161
162
/**
163
* @brief Atomic exchange for shared_ptr objects.
164
* @param __p A non-null pointer to a shared_ptr object.
165
* @param __r New value to store in @c *__p.
166
* @return The original value of @c *__p
167
* @{
168
*/
169
template
<
typename
_Tp>
170
inline
shared_ptr<_Tp>
171
atomic_exchange_explicit(
shared_ptr<_Tp>
* __p,
shared_ptr<_Tp>
__r,
172
memory_order
)
173
{
174
_Sp_locker
__lock
{__p};
175
__p->swap(__r);
176
return
__r;
177
}
178
179
template
<
typename
_Tp>
180
inline
shared_ptr<_Tp>
181
atomic_exchange(
shared_ptr<_Tp>
* __p,
shared_ptr<_Tp>
__r)
182
{
183
return
std::atomic_exchange_explicit(__p, std::move(__r),
184
memory_order_seq_cst);
185
}
186
187
template
<
typename
_Tp, _Lock_policy _Lp>
188
inline
__shared_ptr<_Tp, _Lp>
189
atomic_exchange_explicit(
__shared_ptr<_Tp, _Lp>
* __p,
190
__shared_ptr<_Tp, _Lp>
__r,
191
memory_order
)
192
{
193
_Sp_locker
__lock
{__p};
194
__p->swap(__r);
195
return
__r;
196
}
197
198
template
<
typename
_Tp, _Lock_policy _Lp>
199
inline
__shared_ptr<_Tp, _Lp>
200
atomic_exchange(
__shared_ptr<_Tp, _Lp>
* __p,
__shared_ptr<_Tp, _Lp>
__r)
201
{
202
return
std::atomic_exchange_explicit(__p, std::move(__r),
203
memory_order_seq_cst);
204
}
205
// @}
206
207
/**
208
* @brief Atomic compare-and-swap for shared_ptr objects.
209
* @param __p A non-null pointer to a shared_ptr object.
210
* @param __v A non-null pointer to a shared_ptr object.
211
* @param __w A non-null pointer to a shared_ptr object.
212
* @return True if @c *__p was equivalent to @c *__v, false otherwise.
213
*
214
* The memory order for failure shall not be @c memory_order_release or
215
* @c memory_order_acq_rel, or stronger than the memory order for success.
216
* @{
217
*/
218
template
<
typename
_Tp>
219
bool
220
atomic_compare_exchange_strong_explicit(
shared_ptr<_Tp>
* __p,
221
shared_ptr<_Tp>
*
__v
,
222
shared_ptr<_Tp>
__w
,
223
memory_order
,
224
memory_order
)
225
{
226
shared_ptr<_Tp>
__x;
// goes out of scope after __lock
227
_Sp_locker
__lock
{__p,
__v
};
228
owner_less<shared_ptr<_Tp>
> __less;
229
if
(*__p == *
__v
&& !__less(*__p, *
__v
) && !__less(*
__v
, *__p))
230
{
231
__x = std::move(*__p);
232
*__p = std::move(
__w
);
233
return
true
;
234
}
235
__x = std::move(*
__v
);
236
*
__v
= *__p;
237
return
false
;
238
}
239
240
template
<
typename
_Tp>
241
inline
bool
242
atomic_compare_exchange_strong(
shared_ptr<_Tp>
* __p,
shared_ptr<_Tp>
*
__v
,
243
shared_ptr<_Tp>
__w
)
244
{
245
return
std::atomic_compare_exchange_strong_explicit(__p,
__v
,
246
std::move(
__w
), memory_order_seq_cst, memory_order_seq_cst);
247
}
248
249
template
<
typename
_Tp>
250
inline
bool
251
atomic_compare_exchange_weak_explicit(
shared_ptr<_Tp>
* __p,
252
shared_ptr<_Tp>
*
__v
,
253
shared_ptr<_Tp>
__w
,
254
memory_order
__success
,
255
memory_order
__failure
)
256
{
257
return
std::atomic_compare_exchange_strong_explicit(__p,
__v
,
258
std::move(
__w
),
__success
,
__failure
);
259
}
260
261
template
<
typename
_Tp>
262
inline
bool
263
atomic_compare_exchange_weak(
shared_ptr<_Tp>
* __p,
shared_ptr<_Tp>
*
__v
,
264
shared_ptr<_Tp>
__w
)
265
{
266
return
std::atomic_compare_exchange_weak_explicit(__p,
__v
,
267
std::move(
__w
), memory_order_seq_cst, memory_order_seq_cst);
268
}
269
270
template
<
typename
_Tp, _Lock_policy _Lp>
271
bool
272
atomic_compare_exchange_strong_explicit(
__shared_ptr<_Tp, _Lp>
* __p,
273
__shared_ptr<_Tp, _Lp>
*
__v
,
274
__shared_ptr<_Tp, _Lp>
__w
,
275
memory_order
,
276
memory_order
)
277
{
278
__shared_ptr<_Tp, _Lp>
__x;
// goes out of scope after __lock
279
_Sp_locker
__lock
{__p,
__v
};
280
owner_less<__shared_ptr<_Tp, _Lp>
> __less;
281
if
(*__p == *
__v
&& !__less(*__p, *
__v
) && !__less(*
__v
, *__p))
282
{
283
__x = std::move(*__p);
284
*__p = std::move(
__w
);
285
return
true
;
286
}
287
__x = std::move(*
__v
);
288
*
__v
= *__p;
289
return
false
;
290
}
291
292
template
<
typename
_Tp, _Lock_policy _Lp>
293
inline
bool
294
atomic_compare_exchange_strong(
__shared_ptr<_Tp, _Lp>
* __p,
295
__shared_ptr<_Tp, _Lp>
*
__v
,
296
__shared_ptr<_Tp, _Lp>
__w
)
297
{
298
return
std::atomic_compare_exchange_strong_explicit(__p,
__v
,
299
std::move(
__w
), memory_order_seq_cst, memory_order_seq_cst);
300
}
301
302
template
<
typename
_Tp, _Lock_policy _Lp>
303
inline
bool
304
atomic_compare_exchange_weak_explicit(
__shared_ptr<_Tp, _Lp>
* __p,
305
__shared_ptr<_Tp, _Lp>
*
__v
,
306
__shared_ptr<_Tp, _Lp>
__w
,
307
memory_order
__success
,
308
memory_order
__failure
)
309
{
310
return
std::atomic_compare_exchange_strong_explicit(__p,
__v
,
311
std::move(
__w
),
__success
,
__failure
);
312
}
313
314
template
<
typename
_Tp, _Lock_policy _Lp>
315
inline
bool
316
atomic_compare_exchange_weak(
__shared_ptr<_Tp, _Lp>
* __p,
317
__shared_ptr<_Tp, _Lp>
*
__v
,
318
__shared_ptr<_Tp, _Lp>
__w
)
319
{
320
return
std::atomic_compare_exchange_weak_explicit(__p,
__v
,
321
std::move(
__w
), memory_order_seq_cst, memory_order_seq_cst);
322
}
323
// @}
324
325
// @} group pointer_abstractions
326
327
_GLIBCXX_END_NAMESPACE_VERSION
328
}
// namespace
329
330
#endif
// _SHARED_PTR_ATOMIC_H
atomic_base.h
std::memory_order
memory_order
Enumeration for memory_order.
Definition
atomic_base.h:56
std
ISO C++ entities toplevel namespace is std.
std::auto_ptr_ref
Definition
auto_ptr.h:49
include
bits
shared_ptr_atomic.h
Generated by
1.9.8