blob: 14016058ae747920cb147b85cafe8a72c44bd556 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/base/platform/mutex.h"
6
7#include <errno.h>
8
9namespace v8 {
10namespace base {
11
12#if V8_OS_POSIX
13
14static V8_INLINE void InitializeNativeHandle(pthread_mutex_t* mutex) {
15 int result;
16#if defined(DEBUG)
17 // Use an error checking mutex in debug mode.
18 pthread_mutexattr_t attr;
19 result = pthread_mutexattr_init(&attr);
20 DCHECK_EQ(0, result);
21 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
22 DCHECK_EQ(0, result);
23 result = pthread_mutex_init(mutex, &attr);
24 DCHECK_EQ(0, result);
25 result = pthread_mutexattr_destroy(&attr);
26#else
27 // Use a fast mutex (default attributes).
28 result = pthread_mutex_init(mutex, NULL);
29#endif // defined(DEBUG)
30 DCHECK_EQ(0, result);
31 USE(result);
32}
33
34
35static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36 pthread_mutexattr_t attr;
37 int result = pthread_mutexattr_init(&attr);
38 DCHECK_EQ(0, result);
39 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
40 DCHECK_EQ(0, result);
41 result = pthread_mutex_init(mutex, &attr);
42 DCHECK_EQ(0, result);
43 result = pthread_mutexattr_destroy(&attr);
44 DCHECK_EQ(0, result);
45 USE(result);
46}
47
48
49static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50 int result = pthread_mutex_destroy(mutex);
51 DCHECK_EQ(0, result);
52 USE(result);
53}
54
55
56static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57 int result = pthread_mutex_lock(mutex);
58 DCHECK_EQ(0, result);
59 USE(result);
60}
61
62
63static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64 int result = pthread_mutex_unlock(mutex);
65 DCHECK_EQ(0, result);
66 USE(result);
67}
68
69
70static V8_INLINE bool TryLockNativeHandle(pthread_mutex_t* mutex) {
71 int result = pthread_mutex_trylock(mutex);
72 if (result == EBUSY) {
73 return false;
74 }
75 DCHECK_EQ(0, result);
76 return true;
77}
78
79#elif V8_OS_WIN
80
81static V8_INLINE void InitializeNativeHandle(PCRITICAL_SECTION cs) {
82 InitializeCriticalSection(cs);
83}
84
85
86static V8_INLINE void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs) {
87 InitializeCriticalSection(cs);
88}
89
90
91static V8_INLINE void DestroyNativeHandle(PCRITICAL_SECTION cs) {
92 DeleteCriticalSection(cs);
93}
94
95
96static V8_INLINE void LockNativeHandle(PCRITICAL_SECTION cs) {
97 EnterCriticalSection(cs);
98}
99
100
101static V8_INLINE void UnlockNativeHandle(PCRITICAL_SECTION cs) {
102 LeaveCriticalSection(cs);
103}
104
105
106static V8_INLINE bool TryLockNativeHandle(PCRITICAL_SECTION cs) {
107 return TryEnterCriticalSection(cs);
108}
109
110#endif // V8_OS_POSIX
111
112
113Mutex::Mutex() {
114 InitializeNativeHandle(&native_handle_);
115#ifdef DEBUG
116 level_ = 0;
117#endif
118}
119
120
121Mutex::~Mutex() {
122 DestroyNativeHandle(&native_handle_);
123 DCHECK_EQ(0, level_);
124}
125
126
127void Mutex::Lock() {
128 LockNativeHandle(&native_handle_);
129 AssertUnheldAndMark();
130}
131
132
133void Mutex::Unlock() {
134 AssertHeldAndUnmark();
135 UnlockNativeHandle(&native_handle_);
136}
137
138
139bool Mutex::TryLock() {
140 if (!TryLockNativeHandle(&native_handle_)) {
141 return false;
142 }
143 AssertUnheldAndMark();
144 return true;
145}
146
147
148RecursiveMutex::RecursiveMutex() {
149 InitializeRecursiveNativeHandle(&native_handle_);
150#ifdef DEBUG
151 level_ = 0;
152#endif
153}
154
155
156RecursiveMutex::~RecursiveMutex() {
157 DestroyNativeHandle(&native_handle_);
158 DCHECK_EQ(0, level_);
159}
160
161
162void RecursiveMutex::Lock() {
163 LockNativeHandle(&native_handle_);
164#ifdef DEBUG
165 DCHECK_LE(0, level_);
166 level_++;
167#endif
168}
169
170
171void RecursiveMutex::Unlock() {
172#ifdef DEBUG
173 DCHECK_LT(0, level_);
174 level_--;
175#endif
176 UnlockNativeHandle(&native_handle_);
177}
178
179
180bool RecursiveMutex::TryLock() {
181 if (!TryLockNativeHandle(&native_handle_)) {
182 return false;
183 }
184#ifdef DEBUG
185 DCHECK_LE(0, level_);
186 level_++;
187#endif
188 return true;
189}
190
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191} // namespace base
192} // namespace v8