mutex.cc 3.76 KB
Newer Older
1
// Copyright 2013 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5
#include "src/base/platform/mutex.h"
6

7
#include <errno.h>
8 9

namespace v8 {
10
namespace base {
11 12 13

#if V8_OS_POSIX

14
static V8_INLINE void InitializeNativeHandle(pthread_mutex_t* mutex) {
15 16 17 18 19
  int result;
#if defined(DEBUG)
  // Use an error checking mutex in debug mode.
  pthread_mutexattr_t attr;
  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 26 27 28 29
  result = pthread_mutexattr_destroy(&attr);
#else
  // Use a fast mutex (default attributes).
  result = pthread_mutex_init(mutex, NULL);
#endif  // defined(DEBUG)
30
  DCHECK_EQ(0, result);
31 32 33 34
  USE(result);
}


35
static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36 37
  pthread_mutexattr_t attr;
  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 46 47 48
  USE(result);
}


49
static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50
  int result = pthread_mutex_destroy(mutex);
51
  DCHECK_EQ(0, result);
52 53 54 55
  USE(result);
}


56
static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57
  int result = pthread_mutex_lock(mutex);
58
  DCHECK_EQ(0, result);
59 60 61 62
  USE(result);
}


63
static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64
  int result = pthread_mutex_unlock(mutex);
65
  DCHECK_EQ(0, result);
66 67 68 69
  USE(result);
}


70
static V8_INLINE bool TryLockNativeHandle(pthread_mutex_t* mutex) {
71 72 73 74
  int result = pthread_mutex_trylock(mutex);
  if (result == EBUSY) {
    return false;
  }
75
  DCHECK_EQ(0, result);
76 77 78 79 80
  return true;
}

#elif V8_OS_WIN

81
static V8_INLINE void InitializeNativeHandle(PCRITICAL_SECTION cs) {
82 83 84 85
  InitializeCriticalSection(cs);
}


86
static V8_INLINE void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs) {
87 88 89 90
  InitializeCriticalSection(cs);
}


91
static V8_INLINE void DestroyNativeHandle(PCRITICAL_SECTION cs) {
92 93 94 95
  DeleteCriticalSection(cs);
}


96
static V8_INLINE void LockNativeHandle(PCRITICAL_SECTION cs) {
97 98 99 100
  EnterCriticalSection(cs);
}


101
static V8_INLINE void UnlockNativeHandle(PCRITICAL_SECTION cs) {
102 103 104 105
  LeaveCriticalSection(cs);
}


106
static V8_INLINE bool TryLockNativeHandle(PCRITICAL_SECTION cs) {
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
  return TryEnterCriticalSection(cs);
}

#endif  // V8_OS_POSIX


Mutex::Mutex() {
  InitializeNativeHandle(&native_handle_);
#ifdef DEBUG
  level_ = 0;
#endif
}


Mutex::~Mutex() {
  DestroyNativeHandle(&native_handle_);
123
  DCHECK_EQ(0, level_);
124 125 126 127 128
}


void Mutex::Lock() {
  LockNativeHandle(&native_handle_);
129
  AssertUnheldAndMark();
130 131 132 133
}


void Mutex::Unlock() {
134
  AssertHeldAndUnmark();
135 136 137 138 139 140 141 142
  UnlockNativeHandle(&native_handle_);
}


bool Mutex::TryLock() {
  if (!TryLockNativeHandle(&native_handle_)) {
    return false;
  }
143
  AssertUnheldAndMark();
144 145 146 147 148 149 150 151 152 153 154 155 156 157
  return true;
}


RecursiveMutex::RecursiveMutex() {
  InitializeRecursiveNativeHandle(&native_handle_);
#ifdef DEBUG
  level_ = 0;
#endif
}


RecursiveMutex::~RecursiveMutex() {
  DestroyNativeHandle(&native_handle_);
158
  DCHECK_EQ(0, level_);
159 160 161 162 163 164
}


void RecursiveMutex::Lock() {
  LockNativeHandle(&native_handle_);
#ifdef DEBUG
165
  DCHECK_LE(0, level_);
166 167 168 169 170 171 172
  level_++;
#endif
}


void RecursiveMutex::Unlock() {
#ifdef DEBUG
173
  DCHECK_LT(0, level_);
174 175 176 177 178 179 180 181 182 183 184
  level_--;
#endif
  UnlockNativeHandle(&native_handle_);
}


bool RecursiveMutex::TryLock() {
  if (!TryLockNativeHandle(&native_handle_)) {
    return false;
  }
#ifdef DEBUG
185
  DCHECK_LE(0, level_);
186 187 188 189 190
  level_++;
#endif
  return true;
}

191 192
}  // namespace base
}  // namespace v8