gem5  v22.1.0.0
refcnt.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2018 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2002-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #ifndef __BASE_REFCNT_HH__
42 #define __BASE_REFCNT_HH__
43 
44 #include <type_traits>
45 
52 namespace gem5
53 {
54 
61 {
62  private:
63  // The reference count is mutable because one may want to
64  // reference count a const pointer. This really is OK because
65  // const is about logical constness of the object not really about
66  // strictly disallowing an object to change.
67  mutable int count;
68 
69  private:
70  // Don't allow a default copy constructor or copy operator on
71  // these objects because the default operation will copy the
72  // reference count as well and we certainly don't want that.
75 
76  public:
84  RefCounted() : count(0) {}
85 
95  virtual ~RefCounted() {}
96 
98  void incref() const { ++count; }
99 
102  void
103  decref() const
104  {
105  if (--count <= 0)
106  delete this;
107  }
108 };
109 
125 template <class T>
127 {
128  public:
129  using PtrType = T*;
130 
131  protected:
134  static constexpr auto TisConst = std::is_const_v<T>;
135  using ConstT = typename std::conditional_t<TisConst,
138  friend ConstT;
139  using NonConstT = typename std::conditional_t<TisConst,
142  friend NonConstT;
146  T *data;
147 
154  void
155  copy(T *d)
156  {
157  data = d;
158  if (data)
159  data->incref();
160  }
161 
167  void
168  del()
169  {
170  if (data)
171  data->decref();
172  }
173 
177  void
178  set(T *d)
179  {
180  // Need to check if we're actually changing because otherwise
181  // we could delete the last reference before adding the new
182  // reference.
183  if (data != d) {
184  del();
185  copy(d);
186  }
187  }
188 
189  public:
192 
196 
199  RefCountingPtr(const RefCountingPtr &r) { copy(r.data); }
200 
205  {
206  data = r.data;
207  r.data = nullptr;
208  }
209 
210  template <bool B = TisConst>
211  RefCountingPtr(const NonConstT &r) { copy(r.data); }
212 
215 
216  // The following pointer access functions are const because they
217  // don't actually change the pointer, though the user could change
218  // what is pointed to. This is analagous to a "Foo * const".
219 
221  T *operator->() const { return data; }
222 
224  T &operator*() const { return *data; }
225 
227  T *get() const { return data; }
228 
229  template <bool B = TisConst>
231  {
232  return RefCountingPtr<const T>(*this);
233  }
234 
236  const RefCountingPtr &operator=(T *p) { set(p); return *this; }
237 
239  const RefCountingPtr &
241  {
242  return operator=(r.data);
243  }
244 
246  const RefCountingPtr &
248  {
249  /* This happens regardless of whether the pointer is the same or not,
250  * because of the move semantics, the rvalue needs to be 'destroyed'.
251  */
252  del();
253  data = r.data;
254  r.data = nullptr;
255  return *this;
256  }
257 
259  bool operator!() const { return data == 0; }
260 
262  operator bool() const { return data != 0; }
263 };
264 
266 template<class T>
267 inline bool
269 {
270  return l.get() == r.get();
271 }
272 
275 template<class T>
276 inline bool
277 operator==(const RefCountingPtr<T> &l, const T *r)
278 {
279  return l.get() == r;
280 }
281 
284 template<class T>
285 inline bool
286 operator==(const T *l, const RefCountingPtr<T> &r)
287 {
288  return l == r.get();
289 }
290 
292 template<class T>
293 inline bool
295 {
296  return l.get() != r.get();
297 }
298 
301 template<class T>
302 inline bool
303 operator!=(const RefCountingPtr<T> &l, const T *r)
304 {
305  return l.get() != r;
306 }
307 
310 template<class T>
311 inline bool
312 operator!=(const T *l, const RefCountingPtr<T> &r)
313 {
314  return l != r.get();
315 }
316 
317 } // namespace gem5
318 
319 #endif // __BASE_REFCNT_HH__
Derive from RefCounted if you want to enable reference counting of this class.
Definition: refcnt.hh:61
RefCounted(const RefCounted &)
virtual ~RefCounted()
We make the destructor virtual because we're likely to have virtual functions on reference counted ob...
Definition: refcnt.hh:95
RefCounted & operator=(const RefCounted &)
RefCounted()
We initialize the reference count to zero and the first object to take ownership of it must increment...
Definition: refcnt.hh:84
void decref() const
Decrement the reference count and destroy the object if all references are gone.
Definition: refcnt.hh:103
void incref() const
Increment the reference count.
Definition: refcnt.hh:98
If you want a reference counting pointer to a mutable object, create it like this:
Definition: refcnt.hh:127
RefCountingPtr()
Create an empty reference counting pointer.
Definition: refcnt.hh:191
T * data
The stored pointer.
Definition: refcnt.hh:146
typename std::conditional_t< TisConst, RefCountingPtr< T >, RefCountingPtr< typename std::add_const< T >::type > > ConstT
Definition: refcnt.hh:137
typename std::conditional_t< TisConst, RefCountingPtr< typename std::remove_const< T >::type >, RefCountingPtr< T > > NonConstT
Definition: refcnt.hh:141
const RefCountingPtr & operator=(const RefCountingPtr &r)
Copy the pointer from another RefCountingPtr.
Definition: refcnt.hh:240
bool operator!() const
Check if the pointer is empty.
Definition: refcnt.hh:259
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:227
void set(T *d)
Drop the old reference and change it to something new.
Definition: refcnt.hh:178
void del()
Delete the reference to any existing object if it is non NULL.
Definition: refcnt.hh:168
static constexpr auto TisConst
Convenience aliases for const/non-const versions of T w/ friendship.
Definition: refcnt.hh:134
~RefCountingPtr()
Destroy the pointer and any reference it may hold.
Definition: refcnt.hh:214
RefCountingPtr(T *data)
Create a new reference counting pointer to some object (probably something newly created).
Definition: refcnt.hh:195
const RefCountingPtr & operator=(T *p)
Assign a new value to the pointer.
Definition: refcnt.hh:236
RefCountingPtr(const RefCountingPtr &r)
Create a new reference counting pointer by copying another one.
Definition: refcnt.hh:199
T * operator->() const
Access a member variable.
Definition: refcnt.hh:221
RefCountingPtr(const NonConstT &r)
Definition: refcnt.hh:211
void copy(T *d)
Copy a new pointer value and increment the reference count if it is a valid pointer.
Definition: refcnt.hh:155
T & operator*() const
Dereference the pointer.
Definition: refcnt.hh:224
RefCountingPtr(RefCountingPtr &&r)
Move-constructor.
Definition: refcnt.hh:204
const RefCountingPtr & operator=(RefCountingPtr &&r)
Move-assign the pointer from another RefCountingPtr.
Definition: refcnt.hh:247
Bitfield< 9 > d
Definition: misc_types.hh:64
Bitfield< 5 > r
Definition: pagetable.hh:60
Bitfield< 55 > l
Definition: pagetable.hh:54
Bitfield< 54 > p
Definition: pagetable.hh:70
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
static bool operator==(const PCStateBase &a, const PCStateBase &b)
Definition: pcstate.hh:155
static bool operator!=(const PCStateBase &a, const PCStateBase &b)
Definition: pcstate.hh:161

Generated on Wed Dec 21 2022 10:22:29 for gem5 by doxygen 1.9.1