Copy ExpandInlineAsm to TargetLowering from TargetAsmInfo.
[oota-llvm.git] / include / llvm / System / RWMutex.h
index 2b466f20b49e81877e45fa05373b68c5b7734c6e..3a288180bf0756837bc73875eb5c7df3ad995bb0 100644 (file)
 #ifndef LLVM_SYSTEM_RWMUTEX_H
 #define LLVM_SYSTEM_RWMUTEX_H
 
+#include "llvm/System/Threading.h"
+#include <cassert>
+
 namespace llvm
 {
   namespace sys
   {
-    /// @brief Platform agnostic Mutex class.
-    class RWMutex
+    /// @brief Platform agnostic RWMutex class.
+    class RWMutexImpl
     {
     /// @name Constructors
     /// @{
@@ -27,11 +30,11 @@ namespace llvm
 
       /// Initializes the lock but doesn't acquire it.
       /// @brief Default Constructor.
-      explicit RWMutex();
+      explicit RWMutexImpl();
 
       /// Releases and removes the lock
       /// @brief Destructor
-      ~RWMutex();
+      ~RWMutexImpl();
 
     /// @}
     /// @name Methods
@@ -66,18 +69,104 @@ namespace llvm
     /// @name Platform Dependent Data
     /// @{
     private:
-#ifdef ENABLE_THREADS
       void* data_; ///< We don't know what the data will be
-#endif
 
     /// @}
     /// @name Do Not Implement
     /// @{
     private:
-      RWMutex(const RWMutex & original);
-      void operator=(const RWMutex &);
+      RWMutexImpl(const RWMutexImpl & original);
+      void operator=(const RWMutexImpl &);
     /// @}
     };
+    
+    /// SmartMutex - An R/W mutex with a compile time constant parameter that 
+    /// indicates whether this mutex should become a no-op when we're not
+    /// running in multithreaded mode.
+    template<bool mt_only>
+    class SmartRWMutex : public RWMutexImpl {
+      unsigned readers, writers;
+    public:
+      explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
+      
+      bool reader_acquire() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::reader_acquire();
+        
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        ++readers;
+        return true;
+      }
+      
+      bool reader_release() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::reader_release();
+        
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        assert(readers > 0 && "Reader lock not acquired before release!");
+        --readers;
+        return true;
+      }
+      
+      bool writer_acquire() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::writer_acquire();
+        
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        assert(writers == 0 && "Writer lock already acquired!");
+        ++writers;
+        return true;
+      }
+      
+      bool writer_release() {
+        if (!mt_only || llvm_is_multithreaded())
+          return RWMutexImpl::writer_release();
+        
+        // Single-threaded debugging code.  This would be racy in multithreaded
+        // mode, but provides not sanity checks in single threaded mode.
+        assert(writers == 1 && "Writer lock not acquired before release!");
+        --writers;
+        return true;
+      }
+      
+    private:
+      SmartRWMutex(const SmartRWMutex<mt_only> & original);
+      void operator=(const SmartRWMutex<mt_only> &);
+    };
+    typedef SmartRWMutex<false> RWMutex;
+    
+    /// ScopedReader - RAII acquisition of a reader lock
+    template<bool mt_only>
+    struct SmartScopedReader {
+      SmartRWMutex<mt_only>& mutex;
+      
+      explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
+        mutex.reader_acquire();
+      }
+      
+      ~SmartScopedReader() {
+        mutex.reader_release();
+      }
+    };
+    typedef SmartScopedReader<false> ScopedReader;
+    
+    /// ScopedWriter - RAII acquisition of a writer lock
+    template<bool mt_only>
+    struct SmartScopedWriter {
+      SmartRWMutex<mt_only>& mutex;
+      
+      explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
+        mutex.writer_acquire();
+      }
+      
+      ~SmartScopedWriter() {
+        mutex.writer_release();
+      }
+    };
+    typedef SmartScopedWriter<false> ScopedWriter;
   }
 }