proxygen
folly::atomic_shared_ptr< T, Atom, CountedDetail > Class Template Reference

#include <AtomicSharedPtr.h>

Public Member Functions

 atomic_shared_ptr () noexcept
 
 atomic_shared_ptr (SharedPtr foo)
 
 atomic_shared_ptr (const atomic_shared_ptr< T > &)=delete
 
 ~atomic_shared_ptr ()
 
void operator= (SharedPtr desired)
 
void operator= (const atomic_shared_ptr< T > &)=delete
 
bool is_lock_free () const noexcept
 
SharedPtr load (std::memory_order order=std::memory_order_seq_cst) const noexcept
 
 operator SharedPtr () const
 
void store (SharedPtr n, std::memory_order order=std::memory_order_seq_cst)
 
SharedPtr exchange (SharedPtr n, std::memory_order order=std::memory_order_seq_cst)
 
bool compare_exchange_weak (SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
 
bool compare_exchange_weak (SharedPtr &expected, const SharedPtr &n, std::memory_order success, std::memory_order failure)
 
bool compare_exchange_weak (SharedPtr &expected, SharedPtr &&desired, std::memory_order mo=std::memory_order_seq_cst) noexcept
 
bool compare_exchange_weak (SharedPtr &expected, SharedPtr &&desired, std::memory_order success, std::memory_order failure)
 
bool compare_exchange_strong (SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
 
bool compare_exchange_strong (SharedPtr &expected, const SharedPtr &n, std::memory_order success, std::memory_order failure)
 
bool compare_exchange_strong (SharedPtr &expected, SharedPtr &&desired, std::memory_order mo=std::memory_order_seq_cst) noexcept
 
bool compare_exchange_strong (SharedPtr &expected, SharedPtr &&desired, std::memory_order success, std::memory_order failure)
 

Private Types

using SharedPtr = typename CountedDetail::template CountedPtr< T >
 
using BasePtr = typename CountedDetail::counted_base
 
using PackedPtr = folly::PackedSyncPtr< BasePtr >
 

Private Member Functions

void add_external (BasePtr *res, int64_t c=0) const
 
void release_external (PackedPtr &res, int64_t c=0) const
 
PackedPtr get_newptr (const SharedPtr &n) const
 
PackedPtr get_newptr (SharedPtr &&n) const
 
void init ()
 
unsigned int get_local_count (const PackedPtr &p) const
 
bool owners_eq (PackedPtr &p1, BasePtr *p2)
 
SharedPtr get_shared_ptr (const PackedPtr &p, bool inc=true) const
 
PackedPtr takeOwnedBase (std::memory_order order) const noexcept
 
void putOwnedBase (BasePtr *p, unsigned int count, std::memory_order mo) const noexcept
 

Private Attributes

AtomicStruct< PackedPtr, Atomptr_
 

Static Private Attributes

static constexpr unsigned EXTERNAL_OFFSET {0x2000}
 
static constexpr unsigned ALIASED_PTR {0x4000}
 

Detailed Description

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
class folly::atomic_shared_ptr< T, Atom, CountedDetail >

Definition at line 73 of file AtomicSharedPtr.h.

Member Typedef Documentation

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
using folly::atomic_shared_ptr< T, Atom, CountedDetail >::BasePtr = typename CountedDetail::counted_base
private

Definition at line 75 of file AtomicSharedPtr.h.

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
using folly::atomic_shared_ptr< T, Atom, CountedDetail >::PackedPtr = folly::PackedSyncPtr<BasePtr>
private

Definition at line 76 of file AtomicSharedPtr.h.

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
using folly::atomic_shared_ptr< T, Atom, CountedDetail >::SharedPtr = typename CountedDetail::template CountedPtr<T>
private

Definition at line 74 of file AtomicSharedPtr.h.

Constructor & Destructor Documentation

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
folly::atomic_shared_ptr< T, Atom, CountedDetail >::atomic_shared_ptr ( )
inlinenoexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
folly::atomic_shared_ptr< T, Atom, CountedDetail >::atomic_shared_ptr ( SharedPtr  foo)
inlineexplicit

Definition at line 82 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::atomic_shared_ptr(), folly::gen::move, and folly::atomic_shared_ptr< T, Atom, CountedDetail >::store().

83  : atomic_shared_ptr() {
85  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void store(SharedPtr n, std::memory_order order=std::memory_order_seq_cst)
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
folly::atomic_shared_ptr< T, Atom, CountedDetail >::atomic_shared_ptr ( const atomic_shared_ptr< T > &  )
delete
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
folly::atomic_shared_ptr< T, Atom, CountedDetail >::~atomic_shared_ptr ( )
inline

Definition at line 88 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::store().

88  {
89  store(SharedPtr(nullptr));
90  }
typename CountedDetail::template CountedPtr< T > SharedPtr
void store(SharedPtr n, std::memory_order order=std::memory_order_seq_cst)

Member Function Documentation

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::add_external ( BasePtr res,
int64_t  c = 0 
) const
inlineprivate

Definition at line 237 of file AtomicSharedPtr.h.

References c, and folly::atomic_shared_ptr< T, Atom, CountedDetail >::EXTERNAL_OFFSET.

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_newptr().

237  {
238  assert(res);
239  CountedDetail::inc_shared_count(res, EXTERNAL_OFFSET + c);
240  }
static constexpr unsigned EXTERNAL_OFFSET
char c
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong ( SharedPtr expected,
const SharedPtr n,
std::memory_order  mo = std::memory_order_seq_cst 
)
inlinenoexcept

Definition at line 191 of file AtomicSharedPtr.h.

References folly::detail::default_failure_memory_order().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong().

194  {
196  expected, n, mo, detail::default_failure_memory_order(mo));
197  }
std::memory_order default_failure_memory_order(std::memory_order successMode)
Definition: AtomicUtils.h:24
bool compare_exchange_strong(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong ( SharedPtr expected,
const SharedPtr n,
std::memory_order  success,
std::memory_order  failure 
)
inline

Definition at line 198 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak().

202  {
203  auto local_expected = expected;
204  do {
205  if (compare_exchange_weak(expected, n, success, failure)) {
206  return true;
207  }
208  } while (local_expected == expected);
209 
210  return false;
211  }
bool compare_exchange_weak(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong ( SharedPtr expected,
SharedPtr &&  desired,
std::memory_order  mo = std::memory_order_seq_cst 
)
inlinenoexcept

Definition at line 212 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong(), and folly::detail::default_failure_memory_order().

215  {
217  expected, desired, mo, detail::default_failure_memory_order(mo));
218  }
std::memory_order default_failure_memory_order(std::memory_order successMode)
Definition: AtomicUtils.h:24
bool compare_exchange_strong(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong ( SharedPtr expected,
SharedPtr &&  desired,
std::memory_order  success,
std::memory_order  failure 
)
inline

Definition at line 219 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong().

223  {
224  return compare_exchange_strong(expected, desired, success, failure);
225  }
bool compare_exchange_strong(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak ( SharedPtr expected,
const SharedPtr n,
std::memory_order  mo = std::memory_order_seq_cst 
)
inlinenoexcept

Definition at line 140 of file AtomicSharedPtr.h.

References folly::detail::default_failure_memory_order().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_strong(), and folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak().

143  {
144  return compare_exchange_weak(
145  expected, n, mo, detail::default_failure_memory_order(mo));
146  }
std::memory_order default_failure_memory_order(std::memory_order successMode)
Definition: AtomicUtils.h:24
bool compare_exchange_weak(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak ( SharedPtr expected,
const SharedPtr n,
std::memory_order  success,
std::memory_order  failure 
)
inline

Definition at line 147 of file AtomicSharedPtr.h.

References folly::PackedSyncPtr< T >::get(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_newptr(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_shared_ptr(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::owners_eq(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::ptr_, folly::atomic_shared_ptr< T, Atom, CountedDetail >::release_external(), and folly::atomic_shared_ptr< T, Atom, CountedDetail >::takeOwnedBase().

151  {
152  auto newptr = get_newptr(n);
153  PackedPtr oldptr, expectedptr;
154 
155  oldptr = takeOwnedBase(success);
156  if (!owners_eq(oldptr, CountedDetail::get_counted_base(expected))) {
157  expected = get_shared_ptr(oldptr, false);
158  release_external(newptr);
159  return false;
160  }
161  expectedptr = oldptr; // Need oldptr to release if failed
162  if (ptr_.compare_exchange_weak(expectedptr, newptr, success, failure)) {
163  if (oldptr.get()) {
164  release_external(oldptr, -1);
165  }
166  return true;
167  } else {
168  if (oldptr.get()) {
169  expected = get_shared_ptr(oldptr, false);
170  } else {
171  expected = SharedPtr(nullptr);
172  }
173  release_external(newptr);
174  return false;
175  }
176  }
PackedPtr takeOwnedBase(std::memory_order order) const noexcept
AtomicStruct< PackedPtr, Atom > ptr_
typename CountedDetail::template CountedPtr< T > SharedPtr
SharedPtr get_shared_ptr(const PackedPtr &p, bool inc=true) const
bool owners_eq(PackedPtr &p1, BasePtr *p2)
folly::PackedSyncPtr< BasePtr > PackedPtr
void release_external(PackedPtr &res, int64_t c=0) const
PackedPtr get_newptr(const SharedPtr &n) const
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak ( SharedPtr expected,
SharedPtr &&  desired,
std::memory_order  mo = std::memory_order_seq_cst 
)
inlinenoexcept

Definition at line 177 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak(), and folly::detail::default_failure_memory_order().

180  {
181  return compare_exchange_weak(
182  expected, desired, mo, detail::default_failure_memory_order(mo));
183  }
std::memory_order default_failure_memory_order(std::memory_order successMode)
Definition: AtomicUtils.h:24
bool compare_exchange_weak(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak ( SharedPtr expected,
SharedPtr &&  desired,
std::memory_order  success,
std::memory_order  failure 
)
inline

Definition at line 184 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak().

188  {
189  return compare_exchange_weak(expected, desired, success, failure);
190  }
bool compare_exchange_weak(SharedPtr &expected, const SharedPtr &n, std::memory_order mo=std::memory_order_seq_cst) noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
SharedPtr folly::atomic_shared_ptr< T, Atom, CountedDetail >::exchange ( SharedPtr  n,
std::memory_order  order = std::memory_order_seq_cst 
)
inline

Definition at line 124 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_newptr(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_shared_ptr(), folly::gen::move, order, folly::atomic_shared_ptr< T, Atom, CountedDetail >::ptr_, and folly::atomic_shared_ptr< T, Atom, CountedDetail >::release_external().

126  {
127  auto newptr = get_newptr(std::move(n));
128  auto old = ptr_.exchange(newptr, order);
129 
130  SharedPtr old_ptr;
131 
132  if (old.get()) {
133  old_ptr = get_shared_ptr(old);
134  release_external(old);
135  }
136 
137  return old_ptr;
138  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
AtomicStruct< PackedPtr, Atom > ptr_
typename CountedDetail::template CountedPtr< T > SharedPtr
SharedPtr get_shared_ptr(const PackedPtr &p, bool inc=true) const
void release_external(PackedPtr &res, int64_t c=0) const
int order
PackedPtr get_newptr(const SharedPtr &n) const
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
unsigned int folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_local_count ( const PackedPtr p) const
inlineprivate
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
PackedPtr folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_newptr ( const SharedPtr n) const
inlineprivate

Definition at line 250 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::add_external(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::ALIASED_PTR, count, folly::data(), and folly::PackedSyncPtr< T >::init().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::exchange(), and folly::atomic_shared_ptr< T, Atom, CountedDetail >::store().

250  {
251  BasePtr* newval;
252  unsigned count = 0;
253  if (!n) {
254  newval = nullptr;
255  } else {
256  newval = CountedDetail::get_counted_base(n);
257  if (n.get() != CountedDetail::template get_shared_ptr<T>(newval)) {
258  // This is an aliased sharedptr. Make an un-aliased one
259  // by wrapping in *another* shared_ptr.
260  auto data = CountedDetail::template make_ptr<SharedPtr>(n);
261  newval = CountedDetail::get_counted_base(data);
262  count = ALIASED_PTR;
263  // (add external must happen before data goes out of scope)
264  add_external(newval);
265  } else {
266  add_external(newval);
267  }
268  }
269 
270  PackedPtr newptr;
271  newptr.init(newval, count);
272 
273  return newptr;
274  }
void add_external(BasePtr *res, int64_t c=0) const
typename CountedDetail::counted_base BasePtr
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
static constexpr unsigned ALIASED_PTR
int * count
folly::PackedSyncPtr< BasePtr > PackedPtr
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
PackedPtr folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_newptr ( SharedPtr &&  n) const
inlineprivate

Definition at line 275 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::add_external(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::ALIASED_PTR, count, folly::data(), folly::PackedSyncPtr< T >::init(), and folly::gen::move.

275  {
276  BasePtr* newval;
277  unsigned count = 0;
278  if (!n) {
279  newval = nullptr;
280  } else {
281  newval = CountedDetail::get_counted_base(n);
282  if (n.get() != CountedDetail::template get_shared_ptr<T>(newval)) {
283  // This is an aliased sharedptr. Make an un-aliased one
284  // by wrapping in *another* shared_ptr.
285  auto data = CountedDetail::template make_ptr<SharedPtr>(std::move(n));
286  newval = CountedDetail::get_counted_base(data);
287  count = ALIASED_PTR;
288  CountedDetail::release_ptr(data);
289  add_external(newval, -1);
290  } else {
291  CountedDetail::release_ptr(n);
292  add_external(newval, -1);
293  }
294  }
295 
296  PackedPtr newptr;
297  newptr.init(newval, count);
298 
299  return newptr;
300  }
void add_external(BasePtr *res, int64_t c=0) const
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
typename CountedDetail::counted_base BasePtr
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
static constexpr unsigned ALIASED_PTR
int * count
folly::PackedSyncPtr< BasePtr > PackedPtr
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
SharedPtr folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_shared_ptr ( const PackedPtr p,
bool  inc = true 
) const
inlineprivate

Definition at line 322 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::ALIASED_PTR, folly::PackedSyncPtr< T >::extra(), and folly::PackedSyncPtr< T >::get().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::exchange(), and folly::atomic_shared_ptr< T, Atom, CountedDetail >::load().

322  {
323  bool aliased = p.extra() & ALIASED_PTR;
324 
325  auto res = CountedDetail::template get_shared_ptr_from_counted_base<T>(
326  p.get(), inc);
327  if (aliased) {
328  auto aliasedp =
329  CountedDetail::template get_shared_ptr_from_counted_base<SharedPtr>(
330  p.get());
331  res = *aliasedp;
332  }
333  return res;
334  }
static constexpr unsigned ALIASED_PTR
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::init ( )
inlineprivate

Definition at line 301 of file AtomicSharedPtr.h.

References folly::data(), folly::PackedSyncPtr< T >::init(), and folly::AtomicStruct< T, Atom >::store().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::atomic_shared_ptr().

301  {
302  PackedPtr data;
303  data.init();
304  ptr_.store(data);
305  }
AtomicStruct< PackedPtr, Atom > ptr_
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
folly::PackedSyncPtr< BasePtr > PackedPtr
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::is_lock_free ( ) const
inlinenoexcept

Definition at line 96 of file AtomicSharedPtr.h.

96  {
97  // lock free unless more than EXTERNAL_OFFSET threads are
98  // contending and they all get unlucky and scheduled out during
99  // load().
100  //
101  // TODO: Could use a lock-free external map to fix this
102  // corner case.
103  return true;
104  }
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
SharedPtr folly::atomic_shared_ptr< T, Atom, CountedDetail >::load ( std::memory_order  order = std::memory_order_seq_cst) const
inlinenoexcept

Definition at line 106 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_shared_ptr(), folly::fibers::local(), order, and folly::atomic_shared_ptr< T, Atom, CountedDetail >::takeOwnedBase().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::operator SharedPtr().

107  {
108  auto local = takeOwnedBase(order);
109  return get_shared_ptr(local, false);
110  }
PackedPtr takeOwnedBase(std::memory_order order) const noexcept
SharedPtr get_shared_ptr(const PackedPtr &p, bool inc=true) const
int order
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
folly::atomic_shared_ptr< T, Atom, CountedDetail >::operator SharedPtr ( ) const
inline

Definition at line 112 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::load().

112  {
113  return load();
114  }
SharedPtr load(std::memory_order order=std::memory_order_seq_cst) const noexcept
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::operator= ( SharedPtr  desired)
inline

Definition at line 91 of file AtomicSharedPtr.h.

References folly::gen::move, and folly::atomic_shared_ptr< T, Atom, CountedDetail >::store().

91  {
92  store(std::move(desired));
93  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void store(SharedPtr n, std::memory_order order=std::memory_order_seq_cst)
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::operator= ( const atomic_shared_ptr< T > &  )
delete
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
bool folly::atomic_shared_ptr< T, Atom, CountedDetail >::owners_eq ( PackedPtr p1,
BasePtr p2 
)
inlineprivate

Definition at line 312 of file AtomicSharedPtr.h.

References folly::atomic_shared_ptr< T, Atom, CountedDetail >::ALIASED_PTR, folly::PackedSyncPtr< T >::extra(), and folly::PackedSyncPtr< T >::get().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak().

312  {
313  bool aliased1 = p1.extra() & ALIASED_PTR;
314  if (aliased1) {
315  auto p1a = CountedDetail::template get_shared_ptr_from_counted_base<T>(
316  p1.get(), false);
317  return CountedDetail::get_counted_base(p1a) == p2;
318  }
319  return p1.get() == p2;
320  }
static constexpr unsigned ALIASED_PTR
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::putOwnedBase ( BasePtr p,
unsigned int  count,
std::memory_order  mo 
) const
inlineprivatenoexcept

Definition at line 375 of file AtomicSharedPtr.h.

References folly::AtomicStruct< T, Atom >::compare_exchange_weak(), count, folly::PackedSyncPtr< T >::extra(), folly::PackedSyncPtr< T >::get(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_local_count(), folly::AtomicStruct< T, Atom >::load(), and folly::fibers::local().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::takeOwnedBase().

376  {
377  PackedPtr local = ptr_.load(std::memory_order_acquire);
378  while (true) {
379  if (local.get() != p) {
380  break;
381  }
382  auto newlocal = local;
383  if (get_local_count(local) > count) {
384  newlocal.setExtra(local.extra() - count);
385  } else {
386  // Otherwise it may be the same pointer, but someone else won
387  // the compare_exchange below, local count was already made
388  // global. We decrement the global count directly instead of
389  // the local one.
390  break;
391  }
392  if (ptr_.compare_exchange_weak(local, newlocal, mo)) {
393  return;
394  }
395  }
396 
397  CountedDetail::template release_shared<T>(p, count);
398  }
unsigned int get_local_count(const PackedPtr &p) const
AtomicStruct< PackedPtr, Atom > ptr_
int * count
folly::PackedSyncPtr< BasePtr > PackedPtr
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::release_external ( PackedPtr res,
int64_t  c = 0 
) const
inlineprivate

Definition at line 241 of file AtomicSharedPtr.h.

References c, count, diff(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::EXTERNAL_OFFSET, folly::PackedSyncPtr< T >::get(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_local_count(), and int64_t.

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::exchange(), and folly::atomic_shared_ptr< T, Atom, CountedDetail >::store().

241  {
242  if (!res.get()) {
243  return;
244  }
245  int64_t count = get_local_count(res) + c;
247  assert(diff >= 0);
248  CountedDetail::template release_shared<T>(res.get(), diff);
249  }
unsigned int get_local_count(const PackedPtr &p) const
static constexpr unsigned EXTERNAL_OFFSET
int * count
uint64_t diff(uint64_t a, uint64_t b)
Definition: FutexTest.cpp:135
char c
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
void folly::atomic_shared_ptr< T, Atom, CountedDetail >::store ( SharedPtr  n,
std::memory_order  order = std::memory_order_seq_cst 
)
inline
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
PackedPtr folly::atomic_shared_ptr< T, Atom, CountedDetail >::takeOwnedBase ( std::memory_order  order) const
inlineprivatenoexcept

Definition at line 342 of file AtomicSharedPtr.h.

References folly::AtomicStruct< T, Atom >::compare_exchange_weak(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::EXTERNAL_OFFSET, folly::PackedSyncPtr< T >::extra(), folly::PackedSyncPtr< T >::get(), folly::atomic_shared_ptr< T, Atom, CountedDetail >::get_local_count(), folly::AtomicStruct< T, Atom >::load(), folly::fibers::local(), order, folly::atomic_shared_ptr< T, Atom, CountedDetail >::putOwnedBase(), folly::PackedSyncPtr< T >::setExtra(), and folly::fibers::yield().

Referenced by folly::atomic_shared_ptr< T, Atom, CountedDetail >::compare_exchange_weak(), and folly::atomic_shared_ptr< T, Atom, CountedDetail >::load().

342  {
343  PackedPtr local, newlocal;
344  local = ptr_.load(std::memory_order_acquire);
345  while (true) {
346  if (!local.get()) {
347  return local;
348  }
349  newlocal = local;
350  if (get_local_count(newlocal) + 1 > EXTERNAL_OFFSET) {
351  // spinlock in the rare case we have more than
352  // EXTERNAL_OFFSET threads trying to access at once.
354  // Force DeterministicSchedule to choose a different thread
355  local = ptr_.load(std::memory_order_acquire);
356  } else {
357  newlocal.setExtra(newlocal.extra() + 1);
358  assert(get_local_count(newlocal) > 0);
359  if (ptr_.compare_exchange_weak(local, newlocal, order)) {
360  break;
361  }
362  }
363  }
364 
365  // Check if we need to push a batch from local -> global
366  auto batchcount = EXTERNAL_OFFSET / 2;
367  if (get_local_count(newlocal) > batchcount) {
368  CountedDetail::inc_shared_count(newlocal.get(), batchcount);
369  putOwnedBase(newlocal.get(), batchcount, order);
370  }
371 
372  return newlocal;
373  }
unsigned int get_local_count(const PackedPtr &p) const
AtomicStruct< PackedPtr, Atom > ptr_
void putOwnedBase(BasePtr *p, unsigned int count, std::memory_order mo) const noexcept
static constexpr unsigned EXTERNAL_OFFSET
folly::PackedSyncPtr< BasePtr > PackedPtr
int order

Member Data Documentation

template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
constexpr unsigned folly::atomic_shared_ptr< T, Atom, CountedDetail >::ALIASED_PTR {0x4000}
staticprivate
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
constexpr unsigned folly::atomic_shared_ptr< T, Atom, CountedDetail >::EXTERNAL_OFFSET {0x2000}
staticprivate
template<typename T, template< typename > class Atom = std::atomic, typename CountedDetail = detail::shared_ptr_internals>
AtomicStruct<PackedPtr, Atom> folly::atomic_shared_ptr< T, Atom, CountedDetail >::ptr_
mutableprivate

The documentation for this class was generated from the following file: