CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
AtomicPtrCache.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_AtomicPtrCache_h
2 #define DataFormats_Common_AtomicPtrCache_h
3 // -*- C++ -*-
4 //
5 // Package: DataFormats/Common
6 // Class : AtomicPtrCache
7 //
24 //
25 // Original Author: Chris Jones
26 // Created: Thu, 07 Nov 2013 00:50:40 GMT
27 //
28 
29 // system include files
30 #include <atomic>
31 #include <memory>
32 // user include files
33 
34 // forward declarations
35 
36 namespace edm {
37  template <typename T>
39  public:
41 
43  explicit AtomicPtrCache(T*);
44 
48 
50 
51  // ---------- const member functions ---------------------
52  T const* operator->() const { return load(); }
53  T const& operator*() const { return *load(); }
54  T const* load() const;
55 
56  bool isSet() const;
59  bool set(std::unique_ptr<T> iNewValue) const;
60  // ---------- static member functions --------------------
61 
62  // ---------- member functions ---------------------------
63  T* operator->() { return load(); }
64  T& operator*() { return *load(); }
65 
66  T* load();
67 
69  void reset();
70 
71  T* release();
72 
73  private:
74  // ---------- member data --------------------------------
75  mutable std::atomic<T*> m_data;
76  };
77  template <typename T>
78  inline AtomicPtrCache<T>::AtomicPtrCache() : m_data{nullptr} {}
79 
80  template <typename T>
81  inline AtomicPtrCache<T>::AtomicPtrCache(T* iValue) : m_data{iValue} {}
82 
83  template <typename T>
84  inline AtomicPtrCache<T>::AtomicPtrCache(const AtomicPtrCache<T>& iOther) : m_data{nullptr} {
85  auto ptr = iOther.m_data.load(std::memory_order_acquire);
86  if (ptr != nullptr) {
87  m_data.store(new T{*ptr}, std::memory_order_release);
88  }
89  }
90  template <typename T>
92  auto ptr = iOther.m_data.load(std::memory_order_acquire);
93  if (ptr != nullptr) {
94  auto ourPtr = m_data.load(std::memory_order_acquire);
95  if (ourPtr != nullptr) {
96  *ourPtr = *ptr;
97  } else {
98  m_data.store(new T{*ptr}, std::memory_order_release);
99  }
100  } else {
101  delete m_data.exchange(nullptr, std::memory_order_acq_rel);
102  }
103  return *this;
104  }
105 
106  template <typename T>
108  delete m_data.load(std::memory_order_acquire);
109  }
110 
111  template <typename T>
113  return m_data.load(std::memory_order_acquire);
114  }
115 
116  template <typename T>
117  inline T const* AtomicPtrCache<T>::load() const {
118  return m_data.load(std::memory_order_acquire);
119  }
120 
121  template <typename T>
122  inline bool AtomicPtrCache<T>::isSet() const {
123  return nullptr != m_data.load(std::memory_order_acquire);
124  }
125 
126  template <typename T>
127  inline bool AtomicPtrCache<T>::set(std::unique_ptr<T> iNewValue) const {
128  bool retValue;
129  T* expected = nullptr;
130  if ((retValue = m_data.compare_exchange_strong(expected, iNewValue.get(), std::memory_order_acq_rel))) {
131  iNewValue.release();
132  }
133  return retValue;
134  }
135 
136  template <typename T>
137  inline void AtomicPtrCache<T>::reset() {
138  delete m_data.exchange(nullptr, std::memory_order_acq_rel);
139  }
140 
141  template <typename T>
143  T* tmp = m_data.exchange(nullptr);
144  return tmp;
145  }
146 } // namespace edm
147 #endif
T const & operator*() const
void reset()
unsets the value and deletes the memory
bool isSet() const
AtomicPtrCache & operator=(const AtomicPtrCache< T > &)
bool set(std::unique_ptr< T > iNewValue) const
T const * operator->() const
std::atomic< T * > m_data
tmp
align.sh
Definition: createJobs.py:716
long double T
T const * load() const