The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / platform / mutex.h @ f230a1cf

History | View | Annotate | Download (8.23 KB)

1
// Copyright 2013 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_PLATFORM_MUTEX_H_
29
#define V8_PLATFORM_MUTEX_H_
30

    
31
#include "../lazy-instance.h"
32
#if V8_OS_WIN
33
#include "../win32-headers.h"
34
#endif
35

    
36
#if V8_OS_POSIX
37
#include <pthread.h>  // NOLINT
38
#endif
39

    
40
namespace v8 {
41
namespace internal {
42

    
43
// ----------------------------------------------------------------------------
44
// Mutex
45
//
46
// This class is a synchronization primitive that can be used to protect shared
47
// data from being simultaneously accessed by multiple threads. A mutex offers
48
// exclusive, non-recursive ownership semantics:
49
// - A calling thread owns a mutex from the time that it successfully calls
50
//   either |Lock()| or |TryLock()| until it calls |Unlock()|.
51
// - When a thread owns a mutex, all other threads will block (for calls to
52
//   |Lock()|) or receive a |false| return value (for |TryLock()|) if they
53
//   attempt to claim ownership of the mutex.
54
// A calling thread must not own the mutex prior to calling |Lock()| or
55
// |TryLock()|. The behavior of a program is undefined if a mutex is destroyed
56
// while still owned by some thread. The Mutex class is non-copyable.
57

    
58
class Mutex V8_FINAL {
59
 public:
60
  Mutex();
61
  ~Mutex();
62

    
63
  // Locks the given mutex. If the mutex is currently unlocked, it becomes
64
  // locked and owned by the calling thread, and immediately. If the mutex
65
  // is already locked by another thread, suspends the calling thread until
66
  // the mutex is unlocked.
67
  void Lock();
68

    
69
  // Unlocks the given mutex. The mutex is assumed to be locked and owned by
70
  // the calling thread on entrance.
71
  void Unlock();
72

    
73
  // Tries to lock the given mutex. Returns whether the mutex was
74
  // successfully locked.
75
  bool TryLock() V8_WARN_UNUSED_RESULT;
76

    
77
  // The implementation-defined native handle type.
78
#if V8_OS_POSIX
79
  typedef pthread_mutex_t NativeHandle;
80
#elif V8_OS_WIN
81
  typedef CRITICAL_SECTION NativeHandle;
82
#endif
83

    
84
  NativeHandle& native_handle() {
85
    return native_handle_;
86
  }
87
  const NativeHandle& native_handle() const {
88
    return native_handle_;
89
  }
90

    
91
 private:
92
  NativeHandle native_handle_;
93
#ifdef DEBUG
94
  int level_;
95
#endif
96

    
97
  V8_INLINE void AssertHeldAndUnmark() {
98
#ifdef DEBUG
99
    ASSERT_EQ(1, level_);
100
    level_--;
101
#endif
102
  }
103

    
104
  V8_INLINE void AssertUnheldAndMark() {
105
#ifdef DEBUG
106
    ASSERT_EQ(0, level_);
107
    level_++;
108
#endif
109
  }
110

    
111
  friend class ConditionVariable;
112

    
113
  DISALLOW_COPY_AND_ASSIGN(Mutex);
114
};
115

    
116

    
117
// POD Mutex initialized lazily (i.e. the first time Pointer() is called).
118
// Usage:
119
//   static LazyMutex my_mutex = LAZY_MUTEX_INITIALIZER;
120
//
121
//   void my_function() {
122
//     LockGuard<Mutex> guard(my_mutex.Pointer());
123
//     // Do something.
124
//   }
125
//
126
typedef LazyStaticInstance<Mutex,
127
                           DefaultConstructTrait<Mutex>,
128
                           ThreadSafeInitOnceTrait>::type LazyMutex;
129

    
130
#define LAZY_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
131

    
132

    
133
// -----------------------------------------------------------------------------
134
// RecursiveMutex
135
//
136
// This class is a synchronization primitive that can be used to protect shared
137
// data from being simultaneously accessed by multiple threads. A recursive
138
// mutex offers exclusive, recursive ownership semantics:
139
// - A calling thread owns a recursive mutex for a period of time that starts
140
//   when it successfully calls either |Lock()| or |TryLock()|. During this
141
//   period, the thread may make additional calls to |Lock()| or |TryLock()|.
142
//   The period of ownership ends when the thread makes a matching number of
143
//   calls to |Unlock()|.
144
// - When a thread owns a recursive mutex, all other threads will block (for
145
//   calls to |Lock()|) or receive a |false| return value (for |TryLock()|) if
146
//   they attempt to claim ownership of the recursive mutex.
147
// - The maximum number of times that a recursive mutex may be locked is
148
//   unspecified, but after that number is reached, calls to |Lock()| will
149
//   probably abort the process and calls to |TryLock()| return false.
150
// The behavior of a program is undefined if a recursive mutex is destroyed
151
// while still owned by some thread. The RecursiveMutex class is non-copyable.
152

    
153
class RecursiveMutex V8_FINAL {
154
 public:
155
  RecursiveMutex();
156
  ~RecursiveMutex();
157

    
158
  // Locks the mutex. If another thread has already locked the mutex, a call to
159
  // |Lock()| will block execution until the lock is acquired. A thread may call
160
  // |Lock()| on a recursive mutex repeatedly. Ownership will only be released
161
  // after the thread makes a matching number of calls to |Unlock()|.
162
  // The behavior is undefined if the mutex is not unlocked before being
163
  // destroyed, i.e. some thread still owns it.
164
  void Lock();
165

    
166
  // Unlocks the mutex if its level of ownership is 1 (there was exactly one
167
  // more call to |Lock()| than there were calls to unlock() made by this
168
  // thread), reduces the level of ownership by 1 otherwise. The mutex must be
169
  // locked by the current thread of execution, otherwise, the behavior is
170
  // undefined.
171
  void Unlock();
172

    
173
  // Tries to lock the given mutex. Returns whether the mutex was
174
  // successfully locked.
175
  bool TryLock() V8_WARN_UNUSED_RESULT;
176

    
177
  // The implementation-defined native handle type.
178
  typedef Mutex::NativeHandle NativeHandle;
179

    
180
  NativeHandle& native_handle() {
181
    return native_handle_;
182
  }
183
  const NativeHandle& native_handle() const {
184
    return native_handle_;
185
  }
186

    
187
 private:
188
  NativeHandle native_handle_;
189
#ifdef DEBUG
190
  int level_;
191
#endif
192

    
193
  DISALLOW_COPY_AND_ASSIGN(RecursiveMutex);
194
};
195

    
196

    
197
// POD RecursiveMutex initialized lazily (i.e. the first time Pointer() is
198
// called).
199
// Usage:
200
//   static LazyRecursiveMutex my_mutex = LAZY_RECURSIVE_MUTEX_INITIALIZER;
201
//
202
//   void my_function() {
203
//     LockGuard<RecursiveMutex> guard(my_mutex.Pointer());
204
//     // Do something.
205
//   }
206
//
207
typedef LazyStaticInstance<RecursiveMutex,
208
                           DefaultConstructTrait<RecursiveMutex>,
209
                           ThreadSafeInitOnceTrait>::type LazyRecursiveMutex;
210

    
211
#define LAZY_RECURSIVE_MUTEX_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER
212

    
213

    
214
// -----------------------------------------------------------------------------
215
// LockGuard
216
//
217
// This class is a mutex wrapper that provides a convenient RAII-style mechanism
218
// for owning a mutex for the duration of a scoped block.
219
// When a LockGuard object is created, it attempts to take ownership of the
220
// mutex it is given. When control leaves the scope in which the LockGuard
221
// object was created, the LockGuard is destructed and the mutex is released.
222
// The LockGuard class is non-copyable.
223

    
224
template <typename Mutex>
225
class LockGuard V8_FINAL {
226
 public:
227
  explicit LockGuard(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
228
  ~LockGuard() { mutex_->Unlock(); }
229

    
230
 private:
231
  Mutex* mutex_;
232

    
233
  DISALLOW_COPY_AND_ASSIGN(LockGuard);
234
};
235

    
236
} }  // namespace v8::internal
237

    
238
#endif  // V8_PLATFORM_MUTEX_H_