• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // Utility functions in support of the XRT API.
17 
18 #ifndef TENSORFLOW_COMPILER_XRT_XRT_REFPTR_H_
19 #define TENSORFLOW_COMPILER_XRT_XRT_REFPTR_H_
20 
21 #include <cstddef>
22 
23 namespace tensorflow {
24 
25 // Reference counted smart pointer for XRT objects providing the standard
26 // Ref()/Unref() APIs.
27 template <typename T>
28 class RefPtr {
29  public:
30   RefPtr() = default;
31   // Creates a RefPtr from a pointer. This is an ownership transfer operation,
32   // and the caller has to own a valid reference to ptr (unless ptr is nullptr).
RefPtr(T * ptr)33   RefPtr(T* ptr) : ptr_(ptr) {}  // NOLINT
RefPtr(const RefPtr & other)34   RefPtr(const RefPtr& other) : ptr_(other.ptr_) { Acquire(ptr_); }
RefPtr(RefPtr && other)35   RefPtr(RefPtr&& other) : ptr_(other.ptr_) { other.ptr_ = nullptr; }
36 
~RefPtr()37   ~RefPtr() { Release(ptr_); }
38 
39   RefPtr& operator=(const RefPtr& other) {
40     if (this != &other) {
41       Acquire(other.ptr_);
42       Release(ptr_);
43       ptr_ = other.ptr_;
44     }
45     return *this;
46   }
47 
48   RefPtr& operator=(RefPtr&& other) {
49     if (this != &other) {
50       Release(ptr_);
51       ptr_ = other.ptr_;
52       other.ptr_ = nullptr;
53     }
54     return *this;
55   }
56 
57   operator bool() const { return ptr_ != nullptr; }  // NOLINT
58   bool operator==(const RefPtr& rhs) const { return ptr_ == rhs.ptr_; }
59   bool operator!=(const RefPtr& rhs) const { return ptr_ != rhs.ptr_; }
60   bool operator==(const T* ptr) const { return ptr_ == ptr; }
61   bool operator!=(const T* ptr) const { return ptr_ != ptr; }
62   bool operator==(std::nullptr_t ptr) const { return ptr_ == ptr; }
63   bool operator!=(std::nullptr_t ptr) const { return ptr_ != ptr; }
64 
get()65   T* get() const { return ptr_; }
66 
67   T* operator->() const {
68     CHECK(ptr_ != nullptr);  // Crash OK
69     return ptr_;
70   }
71 
72   T& operator*() const {
73     CHECK(ptr_ != nullptr);  // Crash OK
74     return *ptr_;
75   }
76 
release()77   T* release() {
78     T* ptr = ptr_;
79     ptr_ = nullptr;
80     return ptr;
81   }
82 
83   // Resets the RefPtr from a pointer. This is an ownership transfer operation,
84   // and the caller has to own a valid reference to ptr (unless ptr is nullptr).
85   void reset(T* ptr = nullptr) {
86     Release(ptr_);
87     ptr_ = ptr;
88   }
89 
90  private:
Release(T * ptr)91   static void Release(T* ptr) {
92     if (ptr != nullptr) {
93       ptr->Unref();
94     }
95   }
96 
Acquire(T * ptr)97   static void Acquire(T* ptr) {
98     if (ptr != nullptr) {
99       ptr->Ref();
100     }
101   }
102 
103   T* ptr_ = nullptr;
104 };
105 
106 }  // namespace tensorflow
107 
108 #endif  // TENSORFLOW_COMPILER_XRT_XRT_REFPTR_H_
109