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