Mutex.h revision 3c8031df6d555ab6dc6b629273fd8244b801e4d6
1b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
2b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//
3b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//                     The LLVM Compiler Infrastructure
4b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
7b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//
8b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//===----------------------------------------------------------------------===//
9b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//
10b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// This file declares the llvm::sys::Mutex class.
11b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//
12b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//===----------------------------------------------------------------------===//
13b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
14b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer#ifndef LLVM_SYSTEM_MUTEX_H
15b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer#define LLVM_SYSTEM_MUTEX_H
16b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
17b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson#include "llvm/System/Threading.h"
18b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
19b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencernamespace llvm
20b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer{
21b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer  namespace sys
22b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer  {
23b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @brief Platform agnostic Mutex class.
24b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    class MutexImpl
25b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    {
26b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @name Constructors
27b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @{
28b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    public:
29b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
30b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// Initializes the lock but doesn't acquire it. if \p recursive is set
31b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// to false, the lock will not be recursive which makes it cheaper but
32b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// also more likely to deadlock (same thread can't acquire more than
33b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// once).
34b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @brief Default Constructor.
35b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      explicit MutexImpl(bool recursive = true);
36b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
37b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// Releases and removes the lock
38b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @brief Destructor
39b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      ~MutexImpl();
40b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
41b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @}
42b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @name Methods
43b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @{
44b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    public:
45b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
46b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// Attempts to unconditionally acquire the lock. If the lock is held by
47b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// another thread, this method will wait until it can acquire the lock.
48b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @returns false if any kind of error occurs, true otherwise.
49b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @brief Unconditionally acquire the lock.
50b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      bool acquire();
51b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
52b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// Attempts to release the lock. If the lock is held by the current
53b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// thread, the lock is released allowing other threads to acquire the
549eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen      /// lock.
55b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @returns false if any kind of error occurs, true otherwise.
56b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @brief Unconditionally release the lock.
57e98fc32b0d80663aff215e328bcd297b3141b565Dan Gohman      bool release();
58b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
59b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// Attempts to acquire the lock without blocking. If the lock is not
60b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// available, this function returns false quickly (without blocking). If
61b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// the lock is available, it is acquired.
62b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @returns false if any kind of error occurs or the lock is not
63b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// available, true otherwise.
64b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      /// @brief Try to acquire the lock.
65b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer      bool tryacquire();
669eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen
67b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    //@}
68b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @name Platform Dependent Data
69b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @{
70b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    private:
710a262ba7c3250ef02833fae864459ccc905a2e9bReid Spencer#ifdef ENABLE_THREADS
726d2352249af8853c8307a7cf679017b32d27958cJeff Cohen      void* data_; ///< We don't know what the data will be
730a262ba7c3250ef02833fae864459ccc905a2e9bReid Spencer#endif
74b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
75b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @}
76b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @name Do Not Implement
77b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @{
789eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen    private:
79b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      MutexImpl(const MutexImpl & original);
80b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      void operator=(const MutexImpl &);
81b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    /// @}
82b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer    };
83b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
84b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
85b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    /// SmartMutex - A mutex with a compile time constant parameter that
86b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    /// indicates whether this mutex should become a no-op when we're not
87b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    /// running in multithreaded mode.
88b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    template<bool mt_only>
89f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson    class SmartMutex : public MutexImpl {
90b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    public:
91f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson      explicit SmartMutex(bool recursive = true) : MutexImpl(recursive) { }
92b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
93b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      bool acquire() {
94f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson        if (!mt_only && llvm_is_multithreaded())
95f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson          return MutexImpl::acquire();
96b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson        return true;
97b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      }
98b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
99b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      bool release() {
100f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson        if (!mt_only || llvm_is_multithreaded())
101f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson          return MutexImpl::release();
102b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson        return true;
103b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      }
104b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
105b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      bool tryacquire() {
106f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson        if (!mt_only || llvm_is_multithreaded())
107f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson          return MutexImpl::tryacquire();
108b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson        return true;
109b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      }
110b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
111b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson      private:
112f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson        SmartMutex(const SmartMutex<mt_only> & original);
113b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson        void operator=(const SmartMutex<mt_only> &);
114b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    };
115b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson
116b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    /// Mutex - A standard, always enforced mutex.
117b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson    typedef SmartMutex<false> Mutex;
1183c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson
1193c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson    template<bool mt_only>
1203c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson    class SmartScopedLock  {
1213c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson      SmartMutex<mt_only>* mtx;
1223c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson
1233c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson    public:
1243c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson      SmartScopedLock(SmartMutex<mt_only>* m) : mtx(m) {
1253c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson        mtx->acquire();
1263c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson      }
1273c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson
1283c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson      ~SmartScopedLock() {
1293c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson        mtx->release();
1303c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson      }
1313c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson    };
1323c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson
1333c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson    typedef SmartScopedLock<false> ScopedLock;
134b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer  }
135b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer}
136b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer
137b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer#endif
138