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