CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros 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  #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
31 #include <atomic>
32 #include <memory>
33 #endif
34 // user include files
35 
36 // forward declarations
37 
38 namespace edm {
39  template <typename T>
41  {
42 
43  public:
45 
47  explicit AtomicPtrCache(T*);
48 
52 
54 
55  // ---------- const member functions ---------------------
56  T const* operator->() const { return load();}
57  T const& operator*() const {return *load(); }
58  T const* load() const;
59 
60  bool isSet() const;
61 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
62  bool set(std::unique_ptr<T> iNewValue) const;
65 #endif
66  // ---------- static member functions --------------------
67 
68  // ---------- member functions ---------------------------
69  T* operator->() { return load();}
70  T& operator*() {return *load();}
71 
72  T* load();
73 
75  void reset();
76 
77  private:
78 
79  // ---------- member data --------------------------------
80 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
81  mutable std::atomic<T*> m_data;
82 #else
83  mutable T* m_data;
84 #endif
85  };
86 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
87  template<typename T>
88  inline AtomicPtrCache<T>::AtomicPtrCache():m_data{nullptr} {}
89 
90  template<typename T>
91  inline AtomicPtrCache<T>::AtomicPtrCache(T* iValue): m_data{iValue} {}
92 
93  template<typename T>
95  m_data{nullptr}
96  {
97  auto ptr = iOther.m_data.load(std::memory_order_acquire);
98  if(ptr != nullptr) {
99  m_data.store( new T{*ptr}, std::memory_order_release);
100  }
101  }
102  template<typename T>
104  auto ptr = iOther.m_data.load(std::memory_order_acquire);
105  if(ptr != nullptr) {
106  auto ourPtr =m_data.load(std::memory_order_acquire);
107  if( ourPtr !=nullptr) {
108  *ourPtr = *ptr;
109  } else {
110  m_data.store( new T{*ptr}, std::memory_order_release);
111  }
112  } else {
113  delete m_data.exchange(nullptr, std::memory_order_acq_rel);
114  }
115  return *this;
116  }
117 
118 
119  template<typename T>
121  delete m_data.load(std::memory_order_acquire);
122  }
123 
124  template<typename T>
125  inline T* AtomicPtrCache<T>::load(){ return m_data.load(std::memory_order_acquire);}
126 
127  template<typename T>
128  inline T const* AtomicPtrCache<T>::load() const{ return m_data.load(std::memory_order_acquire);}
129 
130  template<typename T>
131  inline bool AtomicPtrCache<T>::isSet() const { return nullptr!=m_data.load(std::memory_order_acquire);}
132 
133  template<typename T>
134  inline bool AtomicPtrCache<T>::set(std::unique_ptr<T> iNewValue) const {
135  bool retValue;
136  T* expected = nullptr;
137  if( (retValue = m_data.compare_exchange_strong(expected,iNewValue.get(), std::memory_order_acq_rel)) ) {
138  iNewValue.release();
139  }
140  return retValue;
141  }
142 
143  template<typename T>
144  inline void AtomicPtrCache<T>::reset() { delete m_data.exchange(nullptr,std::memory_order_acq_rel);}
145 
146 #endif
147 }
148 
149 
150 #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
long double T
T const * load() const