X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FIntrusiveRefCntPtr.h;h=8057ec10be00953e5ffcb3a1d6d857a85e9eefd0;hb=2b762697564ca1e12e0e974e93ceeb4c3420505c;hp=947ccc46a5236b75d701f0b2ccd5e5ec0697c0bf;hpb=e3f75f8797b9752bfe7923bff9a87a15a6fe3552;p=oota-llvm.git diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 947ccc46a52..8057ec10be0 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -18,11 +18,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR -#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR +#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H +#define LLVM_ADT_INTRUSIVEREFCNTPTR_H -#include "llvm/Support/Casting.h" -#include "llvm/Support/Compiler.h" +#include +#include +#include namespace llvm { @@ -33,7 +34,7 @@ namespace llvm { /// RefCountedBase - A generic base class for objects that wish to /// have their lifetimes managed using reference counts. Classes /// subclass RefCountedBase to obtain such functionality, and are -/// typically handled with IntrusivePtr "smart pointers" (see below) +/// typically handled with IntrusiveRefCntPtr "smart pointers" (see below) /// which automatically handle the management of reference counts. /// Objects that subclass RefCountedBase should not be allocated on /// the stack, as invoking "delete" (which is called when the @@ -82,12 +83,37 @@ namespace llvm { friend struct IntrusiveRefCntPtrInfo; }; - + template struct IntrusiveRefCntPtrInfo { static void retain(T *obj) { obj->Retain(); } static void release(T *obj) { obj->Release(); } }; - + +/// \brief A thread-safe version of \c llvm::RefCountedBase. +/// +/// A generic base class for objects that wish to have their lifetimes managed +/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to +/// obtain such functionality, and are typically handled with +/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the +/// management of reference counts. +template +class ThreadSafeRefCountedBase { + mutable std::atomic RefCount; + +protected: + ThreadSafeRefCountedBase() : RefCount(0) {} + +public: + void Retain() const { ++RefCount; } + + void Release() const { + int NewRefCount = --RefCount; + assert(NewRefCount >= 0 && "Reference count was already zero."); + if (NewRefCount == 0) + delete static_cast(this); + } +}; + //===----------------------------------------------------------------------===// /// IntrusiveRefCntPtr - A template class that implements a "smart pointer" /// that assumes the wrapped object has a reference count associated @@ -108,11 +134,11 @@ namespace llvm { template class IntrusiveRefCntPtr { T* Obj; - typedef IntrusiveRefCntPtr this_type; + public: typedef T element_type; - explicit IntrusiveRefCntPtr() : Obj(0) {} + explicit IntrusiveRefCntPtr() : Obj(nullptr) {} IntrusiveRefCntPtr(T* obj) : Obj(obj) { retain(); @@ -122,51 +148,23 @@ namespace llvm { retain(); } -#if LLVM_USE_RVALUE_REFERENCES IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) { - S.Obj = 0; + S.Obj = nullptr; } template - IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.getPtr()) { - S.Obj = 0; + IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.get()) { + S.Obj = nullptr; } -#endif template IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) - : Obj(S.getPtr()) { + : Obj(S.get()) { retain(); } - IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) { - replace(S.getPtr()); - return *this; - } - -#if LLVM_USE_RVALUE_REFERENCES - IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr&& S) { - Obj = S.Obj; - S.Obj = 0; - return *this; - } - - template - IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr&& S) { - Obj = S.getPtr(); - S.Obj = 0; - return *this; - } -#endif - - template - IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) { - replace(S.getPtr()); - return *this; - } - - IntrusiveRefCntPtr& operator=(T * S) { - replace(S); + IntrusiveRefCntPtr& operator=(IntrusiveRefCntPtr S) { + swap(S); return *this; } @@ -176,12 +174,9 @@ namespace llvm { T* operator->() const { return Obj; } - T* getPtr() const { return Obj; } + T* get() const { return Obj; } - typedef T* (IntrusiveRefCntPtr::*unspecified_bool_type) () const; - operator unspecified_bool_type() const { - return Obj == 0 ? 0 : &IntrusiveRefCntPtr::getPtr; - } + explicit operator bool() const { return Obj; } void swap(IntrusiveRefCntPtr& other) { T* tmp = other.Obj; @@ -191,82 +186,103 @@ namespace llvm { void reset() { release(); - Obj = 0; + Obj = nullptr; } void resetWithoutRelease() { - Obj = 0; + Obj = nullptr; } private: void retain() { if (Obj) IntrusiveRefCntPtrInfo::retain(Obj); } void release() { if (Obj) IntrusiveRefCntPtrInfo::release(Obj); } - void replace(T* S) { - this_type(S).swap(*this); - } + template + friend class IntrusiveRefCntPtr; }; template inline bool operator==(const IntrusiveRefCntPtr& A, const IntrusiveRefCntPtr& B) { - return A.getPtr() == B.getPtr(); + return A.get() == B.get(); } template inline bool operator!=(const IntrusiveRefCntPtr& A, const IntrusiveRefCntPtr& B) { - return A.getPtr() != B.getPtr(); + return A.get() != B.get(); } template inline bool operator==(const IntrusiveRefCntPtr& A, U* B) { - return A.getPtr() == B; + return A.get() == B; } template inline bool operator!=(const IntrusiveRefCntPtr& A, U* B) { - return A.getPtr() != B; + return A.get() != B; } template inline bool operator==(T* A, const IntrusiveRefCntPtr& B) { - return A == B.getPtr(); + return A == B.get(); } template inline bool operator!=(T* A, const IntrusiveRefCntPtr& B) { - return A != B.getPtr(); + return A != B.get(); + } + + template + bool operator==(std::nullptr_t A, const IntrusiveRefCntPtr &B) { + return !B; + } + + template + bool operator==(const IntrusiveRefCntPtr &A, std::nullptr_t B) { + return B == A; + } + + template + bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr &B) { + return !(A == B); + } + + template + bool operator!=(const IntrusiveRefCntPtr &A, std::nullptr_t B) { + return !(A == B); } //===----------------------------------------------------------------------===// // LLVM-style downcasting support for IntrusiveRefCntPtr objects //===----------------------------------------------------------------------===// + template struct simplify_type; + template struct simplify_type > { typedef T* SimpleType; - static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr& Val) { - return Val.getPtr(); + static SimpleType getSimplifiedValue(IntrusiveRefCntPtr& Val) { + return Val.get(); } }; template struct simplify_type > { - typedef T* SimpleType; + typedef /*const*/ T* SimpleType; static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr& Val) { - return Val.getPtr(); + return Val.get(); } }; } // end namespace llvm -#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR +#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H