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  T* release();
78 
79  private:
80 
81  // ---------- member data --------------------------------
82 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
83  mutable std::atomic<T*> m_data;
84 #else
85  mutable T* m_data;
86 #endif
87  };
88 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
89  template<typename T>
90  inline AtomicPtrCache<T>::AtomicPtrCache():m_data{nullptr} {}
91 
92  template<typename T>
93  inline AtomicPtrCache<T>::AtomicPtrCache(T* iValue): m_data{iValue} {}
94 
95  template<typename T>
97  m_data{nullptr}
98  {
99  auto ptr = iOther.m_data.load(std::memory_order_acquire);
100  if(ptr != nullptr) {
101  m_data.store( new T{*ptr}, std::memory_order_release);
102  }
103  }
104  template<typename T>
106  auto ptr = iOther.m_data.load(std::memory_order_acquire);
107  if(ptr != nullptr) {
108  auto ourPtr =m_data.load(std::memory_order_acquire);
109  if( ourPtr !=nullptr) {
110  *ourPtr = *ptr;
111  } else {
112  m_data.store( new T{*ptr}, std::memory_order_release);
113  }
114  } else {
115  delete m_data.exchange(nullptr, std::memory_order_acq_rel);
116  }
117  return *this;
118  }
119 
120 
121  template<typename T>
123  delete m_data.load(std::memory_order_acquire);
124  }
125 
126  template<typename T>
127  inline T* AtomicPtrCache<T>::load(){ return m_data.load(std::memory_order_acquire);}
128 
129  template<typename T>
130  inline T const* AtomicPtrCache<T>::load() const{ return m_data.load(std::memory_order_acquire);}
131 
132  template<typename T>
133  inline bool AtomicPtrCache<T>::isSet() const { return nullptr!=m_data.load(std::memory_order_acquire);}
134 
135  template<typename T>
136  inline bool AtomicPtrCache<T>::set(std::unique_ptr<T> iNewValue) const {
137  bool retValue;
138  T* expected = nullptr;
139  if( (retValue = m_data.compare_exchange_strong(expected,iNewValue.get(), std::memory_order_acq_rel)) ) {
140  iNewValue.release();
141  }
142  return retValue;
143  }
144 
145  template<typename T>
146  inline void AtomicPtrCache<T>::reset() { delete m_data.exchange(nullptr,std::memory_order_acq_rel);}
147 
148  template<typename T>
150  T* tmp = m_data.exchange(nullptr);
151  return tmp;
152  }
153 #endif
154 }
155 #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::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
std::atomic< T * > m_data
long double T
T const * load() const