Add ARM big endian Target (armeb, thumbeb)
[oota-llvm.git] / include / llvm / ADT / IntrusiveRefCntPtr.h
index 0c02a8f318543b651ddb1076733245a9c5cdb015..aad139296b0059ad780c133eb0387f5fbe015316 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#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 <atomic>
 #include <memory>
 
 namespace llvm {
@@ -34,7 +35,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
@@ -88,6 +89,31 @@ namespace llvm {
     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 Derived>
+class ThreadSafeRefCountedBase {
+  mutable std::atomic<int> 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<const Derived*>(this);
+  }
+};
   
 //===----------------------------------------------------------------------===//
 /// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
@@ -123,7 +149,6 @@ namespace llvm {
       retain();
     }
 
-#if LLVM_USE_RVALUE_REFERENCES
     IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
       S.Obj = 0;
     }
@@ -132,7 +157,6 @@ namespace llvm {
     IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) {
       S.Obj = 0;
     }
-#endif
 
     template <class X>
     IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
@@ -226,13 +250,13 @@ namespace llvm {
 
   template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
     typedef T* SimpleType;
-    static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+    static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
       return Val.getPtr();
     }
   };
 
   template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
-    typedef T* SimpleType;
+    typedef /*const*/ T* SimpleType;
     static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
       return Val.getPtr();
     }
@@ -240,4 +264,4 @@ namespace llvm {
 
 } // end namespace llvm
 
-#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H