| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" // NOLINT | 5 #include "platform/globals.h" // NOLINT |
| 6 #if defined(HOST_OS_MACOS) | 6 #if defined(HOST_OS_MACOS) |
| 7 | 7 |
| 8 #include "vm/os_thread.h" | 8 #include "vm/os_thread.h" |
| 9 | 9 |
| 10 #include <sys/errno.h> // NOLINT | 10 #include <mach/mach_host.h> // NOLINT |
| 11 #include <sys/types.h> // NOLINT | |
| 12 #include <sys/sysctl.h> // NOLINT | |
| 13 #include <mach/mach_init.h> // NOLINT | 11 #include <mach/mach_init.h> // NOLINT |
| 14 #include <mach/mach_host.h> // NOLINT | |
| 15 #include <mach/mach_port.h> // NOLINT | 12 #include <mach/mach_port.h> // NOLINT |
| 16 #include <mach/mach_traps.h> // NOLINT | 13 #include <mach/mach_traps.h> // NOLINT |
| 17 #include <mach/task_info.h> // NOLINT | 14 #include <mach/task_info.h> // NOLINT |
| 15 #include <mach/thread_act.h> // NOLINT |
| 18 #include <mach/thread_info.h> // NOLINT | 16 #include <mach/thread_info.h> // NOLINT |
| 19 #include <mach/thread_act.h> // NOLINT | 17 #include <sys/errno.h> // NOLINT |
| 18 #include <sys/sysctl.h> // NOLINT |
| 19 #include <sys/types.h> // NOLINT |
| 20 | 20 |
| 21 #include "platform/assert.h" | 21 #include "platform/assert.h" |
| 22 #include "platform/utils.h" | 22 #include "platform/utils.h" |
| 23 | 23 |
| 24 #include "vm/profiler.h" | 24 #include "vm/profiler.h" |
| 25 | 25 |
| 26 namespace dart { | 26 namespace dart { |
| 27 | 27 |
| 28 #define VALIDATE_PTHREAD_RESULT(result) \ | 28 #define VALIDATE_PTHREAD_RESULT(result) \ |
| 29 if (result != 0) { \ | 29 if (result != 0) { \ |
| 30 const int kBufferSize = 1024; \ | 30 const int kBufferSize = 1024; \ |
| 31 char error_message[kBufferSize]; \ | 31 char error_message[kBufferSize]; \ |
| 32 NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \ | 32 NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \ |
| 33 Utils::StrError(result, error_message, kBufferSize); \ | 33 Utils::StrError(result, error_message, kBufferSize); \ |
| 34 FATAL2("pthread error: %d (%s)", result, error_message); \ | 34 FATAL2("pthread error: %d (%s)", result, error_message); \ |
| 35 } | 35 } |
| 36 | 36 |
| 37 | |
| 38 #if defined(DEBUG) | 37 #if defined(DEBUG) |
| 39 #define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result) | 38 #define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result) |
| 40 #else | 39 #else |
| 41 // NOTE: This (currently) expands to a no-op. | 40 // NOTE: This (currently) expands to a no-op. |
| 42 #define ASSERT_PTHREAD_SUCCESS(result) ASSERT(result == 0) | 41 #define ASSERT_PTHREAD_SUCCESS(result) ASSERT(result == 0) |
| 43 #endif | 42 #endif |
| 44 | 43 |
| 45 | |
| 46 #ifdef DEBUG | 44 #ifdef DEBUG |
| 47 #define RETURN_ON_PTHREAD_FAILURE(result) \ | 45 #define RETURN_ON_PTHREAD_FAILURE(result) \ |
| 48 if (result != 0) { \ | 46 if (result != 0) { \ |
| 49 const int kBufferSize = 1024; \ | 47 const int kBufferSize = 1024; \ |
| 50 char error_message[kBufferSize]; \ | 48 char error_message[kBufferSize]; \ |
| 51 Utils::StrError(result, error_message, kBufferSize); \ | 49 Utils::StrError(result, error_message, kBufferSize); \ |
| 52 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \ | 50 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \ |
| 53 result, error_message); \ | 51 result, error_message); \ |
| 54 return result; \ | 52 return result; \ |
| 55 } | 53 } |
| 56 #else | 54 #else |
| 57 #define RETURN_ON_PTHREAD_FAILURE(result) \ | 55 #define RETURN_ON_PTHREAD_FAILURE(result) \ |
| 58 if (result != 0) return result; | 56 if (result != 0) return result; |
| 59 #endif | 57 #endif |
| 60 | 58 |
| 61 | |
| 62 class ThreadStartData { | 59 class ThreadStartData { |
| 63 public: | 60 public: |
| 64 ThreadStartData(const char* name, | 61 ThreadStartData(const char* name, |
| 65 OSThread::ThreadStartFunction function, | 62 OSThread::ThreadStartFunction function, |
| 66 uword parameter) | 63 uword parameter) |
| 67 : name_(name), function_(function), parameter_(parameter) {} | 64 : name_(name), function_(function), parameter_(parameter) {} |
| 68 | 65 |
| 69 const char* name() const { return name_; } | 66 const char* name() const { return name_; } |
| 70 OSThread::ThreadStartFunction function() const { return function_; } | 67 OSThread::ThreadStartFunction function() const { return function_; } |
| 71 uword parameter() const { return parameter_; } | 68 uword parameter() const { return parameter_; } |
| 72 | 69 |
| 73 private: | 70 private: |
| 74 const char* name_; | 71 const char* name_; |
| 75 OSThread::ThreadStartFunction function_; | 72 OSThread::ThreadStartFunction function_; |
| 76 uword parameter_; | 73 uword parameter_; |
| 77 | 74 |
| 78 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); | 75 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); |
| 79 }; | 76 }; |
| 80 | 77 |
| 81 | |
| 82 // Dispatch to the thread start function provided by the caller. This trampoline | 78 // Dispatch to the thread start function provided by the caller. This trampoline |
| 83 // is used to ensure that the thread is properly destroyed if the thread just | 79 // is used to ensure that the thread is properly destroyed if the thread just |
| 84 // exits. | 80 // exits. |
| 85 static void* ThreadStart(void* data_ptr) { | 81 static void* ThreadStart(void* data_ptr) { |
| 86 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); | 82 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); |
| 87 | 83 |
| 88 const char* name = data->name(); | 84 const char* name = data->name(); |
| 89 OSThread::ThreadStartFunction function = data->function(); | 85 OSThread::ThreadStartFunction function = data->function(); |
| 90 uword parameter = data->parameter(); | 86 uword parameter = data->parameter(); |
| 91 delete data; | 87 delete data; |
| 92 | 88 |
| 93 // Create new OSThread object and set as TLS for new thread. | 89 // Create new OSThread object and set as TLS for new thread. |
| 94 OSThread* thread = OSThread::CreateOSThread(); | 90 OSThread* thread = OSThread::CreateOSThread(); |
| 95 if (thread != NULL) { | 91 if (thread != NULL) { |
| 96 OSThread::SetCurrent(thread); | 92 OSThread::SetCurrent(thread); |
| 97 thread->set_name(name); | 93 thread->set_name(name); |
| 98 | 94 |
| 99 // Call the supplied thread start function handing it its parameters. | 95 // Call the supplied thread start function handing it its parameters. |
| 100 function(parameter); | 96 function(parameter); |
| 101 } | 97 } |
| 102 | 98 |
| 103 return NULL; | 99 return NULL; |
| 104 } | 100 } |
| 105 | 101 |
| 106 | |
| 107 int OSThread::Start(const char* name, | 102 int OSThread::Start(const char* name, |
| 108 ThreadStartFunction function, | 103 ThreadStartFunction function, |
| 109 uword parameter) { | 104 uword parameter) { |
| 110 pthread_attr_t attr; | 105 pthread_attr_t attr; |
| 111 int result = pthread_attr_init(&attr); | 106 int result = pthread_attr_init(&attr); |
| 112 RETURN_ON_PTHREAD_FAILURE(result); | 107 RETURN_ON_PTHREAD_FAILURE(result); |
| 113 | 108 |
| 114 result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize()); | 109 result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize()); |
| 115 RETURN_ON_PTHREAD_FAILURE(result); | 110 RETURN_ON_PTHREAD_FAILURE(result); |
| 116 | 111 |
| 117 ThreadStartData* data = new ThreadStartData(name, function, parameter); | 112 ThreadStartData* data = new ThreadStartData(name, function, parameter); |
| 118 | 113 |
| 119 pthread_t tid; | 114 pthread_t tid; |
| 120 result = pthread_create(&tid, &attr, ThreadStart, data); | 115 result = pthread_create(&tid, &attr, ThreadStart, data); |
| 121 RETURN_ON_PTHREAD_FAILURE(result); | 116 RETURN_ON_PTHREAD_FAILURE(result); |
| 122 | 117 |
| 123 result = pthread_attr_destroy(&attr); | 118 result = pthread_attr_destroy(&attr); |
| 124 RETURN_ON_PTHREAD_FAILURE(result); | 119 RETURN_ON_PTHREAD_FAILURE(result); |
| 125 | 120 |
| 126 return 0; | 121 return 0; |
| 127 } | 122 } |
| 128 | 123 |
| 129 | |
| 130 const ThreadId OSThread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL); | 124 const ThreadId OSThread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL); |
| 131 const ThreadJoinId OSThread::kInvalidThreadJoinId = | 125 const ThreadJoinId OSThread::kInvalidThreadJoinId = |
| 132 reinterpret_cast<ThreadJoinId>(NULL); | 126 reinterpret_cast<ThreadJoinId>(NULL); |
| 133 | 127 |
| 134 | |
| 135 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) { | 128 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) { |
| 136 pthread_key_t key = kUnsetThreadLocalKey; | 129 pthread_key_t key = kUnsetThreadLocalKey; |
| 137 int result = pthread_key_create(&key, destructor); | 130 int result = pthread_key_create(&key, destructor); |
| 138 VALIDATE_PTHREAD_RESULT(result); | 131 VALIDATE_PTHREAD_RESULT(result); |
| 139 ASSERT(key != kUnsetThreadLocalKey); | 132 ASSERT(key != kUnsetThreadLocalKey); |
| 140 return key; | 133 return key; |
| 141 } | 134 } |
| 142 | 135 |
| 143 | |
| 144 void OSThread::DeleteThreadLocal(ThreadLocalKey key) { | 136 void OSThread::DeleteThreadLocal(ThreadLocalKey key) { |
| 145 ASSERT(key != kUnsetThreadLocalKey); | 137 ASSERT(key != kUnsetThreadLocalKey); |
| 146 int result = pthread_key_delete(key); | 138 int result = pthread_key_delete(key); |
| 147 VALIDATE_PTHREAD_RESULT(result); | 139 VALIDATE_PTHREAD_RESULT(result); |
| 148 } | 140 } |
| 149 | 141 |
| 150 | |
| 151 void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) { | 142 void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) { |
| 152 ASSERT(key != kUnsetThreadLocalKey); | 143 ASSERT(key != kUnsetThreadLocalKey); |
| 153 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); | 144 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); |
| 154 VALIDATE_PTHREAD_RESULT(result); | 145 VALIDATE_PTHREAD_RESULT(result); |
| 155 } | 146 } |
| 156 | 147 |
| 157 | |
| 158 intptr_t OSThread::GetMaxStackSize() { | 148 intptr_t OSThread::GetMaxStackSize() { |
| 159 const int kStackSize = (128 * kWordSize * KB); | 149 const int kStackSize = (128 * kWordSize * KB); |
| 160 return kStackSize; | 150 return kStackSize; |
| 161 } | 151 } |
| 162 | 152 |
| 163 | |
| 164 ThreadId OSThread::GetCurrentThreadId() { | 153 ThreadId OSThread::GetCurrentThreadId() { |
| 165 return pthread_self(); | 154 return pthread_self(); |
| 166 } | 155 } |
| 167 | 156 |
| 168 | |
| 169 #ifndef PRODUCT | 157 #ifndef PRODUCT |
| 170 ThreadId OSThread::GetCurrentThreadTraceId() { | 158 ThreadId OSThread::GetCurrentThreadTraceId() { |
| 171 return ThreadIdFromIntPtr(pthread_mach_thread_np(pthread_self())); | 159 return ThreadIdFromIntPtr(pthread_mach_thread_np(pthread_self())); |
| 172 } | 160 } |
| 173 #endif // PRODUCT | 161 #endif // PRODUCT |
| 174 | 162 |
| 175 | |
| 176 ThreadJoinId OSThread::GetCurrentThreadJoinId(OSThread* thread) { | 163 ThreadJoinId OSThread::GetCurrentThreadJoinId(OSThread* thread) { |
| 177 ASSERT(thread != NULL); | 164 ASSERT(thread != NULL); |
| 178 // Make sure we're filling in the join id for the current thread. | 165 // Make sure we're filling in the join id for the current thread. |
| 179 ASSERT(thread->id() == GetCurrentThreadId()); | 166 ASSERT(thread->id() == GetCurrentThreadId()); |
| 180 // Make sure the join_id_ hasn't been set, yet. | 167 // Make sure the join_id_ hasn't been set, yet. |
| 181 DEBUG_ASSERT(thread->join_id_ == kInvalidThreadJoinId); | 168 DEBUG_ASSERT(thread->join_id_ == kInvalidThreadJoinId); |
| 182 pthread_t id = pthread_self(); | 169 pthread_t id = pthread_self(); |
| 183 #if defined(DEBUG) | 170 #if defined(DEBUG) |
| 184 thread->join_id_ = id; | 171 thread->join_id_ = id; |
| 185 #endif | 172 #endif |
| 186 return id; | 173 return id; |
| 187 } | 174 } |
| 188 | 175 |
| 189 | |
| 190 void OSThread::Join(ThreadJoinId id) { | 176 void OSThread::Join(ThreadJoinId id) { |
| 191 int result = pthread_join(id, NULL); | 177 int result = pthread_join(id, NULL); |
| 192 ASSERT(result == 0); | 178 ASSERT(result == 0); |
| 193 } | 179 } |
| 194 | 180 |
| 195 | |
| 196 intptr_t OSThread::ThreadIdToIntPtr(ThreadId id) { | 181 intptr_t OSThread::ThreadIdToIntPtr(ThreadId id) { |
| 197 ASSERT(sizeof(id) == sizeof(intptr_t)); | 182 ASSERT(sizeof(id) == sizeof(intptr_t)); |
| 198 return reinterpret_cast<intptr_t>(id); | 183 return reinterpret_cast<intptr_t>(id); |
| 199 } | 184 } |
| 200 | 185 |
| 201 | |
| 202 ThreadId OSThread::ThreadIdFromIntPtr(intptr_t id) { | 186 ThreadId OSThread::ThreadIdFromIntPtr(intptr_t id) { |
| 203 return reinterpret_cast<ThreadId>(id); | 187 return reinterpret_cast<ThreadId>(id); |
| 204 } | 188 } |
| 205 | 189 |
| 206 | |
| 207 bool OSThread::Compare(ThreadId a, ThreadId b) { | 190 bool OSThread::Compare(ThreadId a, ThreadId b) { |
| 208 return pthread_equal(a, b) != 0; | 191 return pthread_equal(a, b) != 0; |
| 209 } | 192 } |
| 210 | 193 |
| 211 | |
| 212 bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) { | 194 bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) { |
| 213 *upper = reinterpret_cast<uword>(pthread_get_stackaddr_np(pthread_self())); | 195 *upper = reinterpret_cast<uword>(pthread_get_stackaddr_np(pthread_self())); |
| 214 *lower = *upper - pthread_get_stacksize_np(pthread_self()); | 196 *lower = *upper - pthread_get_stacksize_np(pthread_self()); |
| 215 return true; | 197 return true; |
| 216 } | 198 } |
| 217 | 199 |
| 218 | |
| 219 Mutex::Mutex() { | 200 Mutex::Mutex() { |
| 220 pthread_mutexattr_t attr; | 201 pthread_mutexattr_t attr; |
| 221 int result = pthread_mutexattr_init(&attr); | 202 int result = pthread_mutexattr_init(&attr); |
| 222 VALIDATE_PTHREAD_RESULT(result); | 203 VALIDATE_PTHREAD_RESULT(result); |
| 223 | 204 |
| 224 #if defined(DEBUG) | 205 #if defined(DEBUG) |
| 225 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | 206 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); |
| 226 VALIDATE_PTHREAD_RESULT(result); | 207 VALIDATE_PTHREAD_RESULT(result); |
| 227 #endif // defined(DEBUG) | 208 #endif // defined(DEBUG) |
| 228 | 209 |
| 229 result = pthread_mutex_init(data_.mutex(), &attr); | 210 result = pthread_mutex_init(data_.mutex(), &attr); |
| 230 // Verify that creating a pthread_mutex succeeded. | 211 // Verify that creating a pthread_mutex succeeded. |
| 231 VALIDATE_PTHREAD_RESULT(result); | 212 VALIDATE_PTHREAD_RESULT(result); |
| 232 | 213 |
| 233 result = pthread_mutexattr_destroy(&attr); | 214 result = pthread_mutexattr_destroy(&attr); |
| 234 VALIDATE_PTHREAD_RESULT(result); | 215 VALIDATE_PTHREAD_RESULT(result); |
| 235 | 216 |
| 236 #if defined(DEBUG) | 217 #if defined(DEBUG) |
| 237 // When running with assertions enabled we do track the owner. | 218 // When running with assertions enabled we do track the owner. |
| 238 owner_ = OSThread::kInvalidThreadId; | 219 owner_ = OSThread::kInvalidThreadId; |
| 239 #endif // defined(DEBUG) | 220 #endif // defined(DEBUG) |
| 240 } | 221 } |
| 241 | 222 |
| 242 | |
| 243 Mutex::~Mutex() { | 223 Mutex::~Mutex() { |
| 244 int result = pthread_mutex_destroy(data_.mutex()); | 224 int result = pthread_mutex_destroy(data_.mutex()); |
| 245 // Verify that the pthread_mutex was destroyed. | 225 // Verify that the pthread_mutex was destroyed. |
| 246 VALIDATE_PTHREAD_RESULT(result); | 226 VALIDATE_PTHREAD_RESULT(result); |
| 247 | 227 |
| 248 #if defined(DEBUG) | 228 #if defined(DEBUG) |
| 249 // When running with assertions enabled we do track the owner. | 229 // When running with assertions enabled we do track the owner. |
| 250 ASSERT(owner_ == OSThread::kInvalidThreadId); | 230 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 251 #endif // defined(DEBUG) | 231 #endif // defined(DEBUG) |
| 252 } | 232 } |
| 253 | 233 |
| 254 | |
| 255 void Mutex::Lock() { | 234 void Mutex::Lock() { |
| 256 int result = pthread_mutex_lock(data_.mutex()); | 235 int result = pthread_mutex_lock(data_.mutex()); |
| 257 // Specifically check for dead lock to help debugging. | 236 // Specifically check for dead lock to help debugging. |
| 258 ASSERT(result != EDEADLK); | 237 ASSERT(result != EDEADLK); |
| 259 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 238 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
| 260 #if defined(DEBUG) | 239 #if defined(DEBUG) |
| 261 // When running with assertions enabled we do track the owner. | 240 // When running with assertions enabled we do track the owner. |
| 262 owner_ = OSThread::GetCurrentThreadId(); | 241 owner_ = OSThread::GetCurrentThreadId(); |
| 263 #endif // defined(DEBUG) | 242 #endif // defined(DEBUG) |
| 264 } | 243 } |
| 265 | 244 |
| 266 | |
| 267 bool Mutex::TryLock() { | 245 bool Mutex::TryLock() { |
| 268 int result = pthread_mutex_trylock(data_.mutex()); | 246 int result = pthread_mutex_trylock(data_.mutex()); |
| 269 // Return false if the lock is busy and locking failed. | 247 // Return false if the lock is busy and locking failed. |
| 270 if ((result == EBUSY) || (result == EDEADLK)) { | 248 if ((result == EBUSY) || (result == EDEADLK)) { |
| 271 return false; | 249 return false; |
| 272 } | 250 } |
| 273 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 251 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
| 274 #if defined(DEBUG) | 252 #if defined(DEBUG) |
| 275 // When running with assertions enabled we do track the owner. | 253 // When running with assertions enabled we do track the owner. |
| 276 owner_ = OSThread::GetCurrentThreadId(); | 254 owner_ = OSThread::GetCurrentThreadId(); |
| 277 #endif // defined(DEBUG) | 255 #endif // defined(DEBUG) |
| 278 return true; | 256 return true; |
| 279 } | 257 } |
| 280 | 258 |
| 281 | |
| 282 void Mutex::Unlock() { | 259 void Mutex::Unlock() { |
| 283 #if defined(DEBUG) | 260 #if defined(DEBUG) |
| 284 // When running with assertions enabled we do track the owner. | 261 // When running with assertions enabled we do track the owner. |
| 285 ASSERT(IsOwnedByCurrentThread()); | 262 ASSERT(IsOwnedByCurrentThread()); |
| 286 owner_ = OSThread::kInvalidThreadId; | 263 owner_ = OSThread::kInvalidThreadId; |
| 287 #endif // defined(DEBUG) | 264 #endif // defined(DEBUG) |
| 288 int result = pthread_mutex_unlock(data_.mutex()); | 265 int result = pthread_mutex_unlock(data_.mutex()); |
| 289 // Specifically check for wrong thread unlocking to aid debugging. | 266 // Specifically check for wrong thread unlocking to aid debugging. |
| 290 ASSERT(result != EPERM); | 267 ASSERT(result != EPERM); |
| 291 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 268 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
| 292 } | 269 } |
| 293 | 270 |
| 294 | |
| 295 Monitor::Monitor() { | 271 Monitor::Monitor() { |
| 296 pthread_mutexattr_t attr; | 272 pthread_mutexattr_t attr; |
| 297 int result = pthread_mutexattr_init(&attr); | 273 int result = pthread_mutexattr_init(&attr); |
| 298 VALIDATE_PTHREAD_RESULT(result); | 274 VALIDATE_PTHREAD_RESULT(result); |
| 299 | 275 |
| 300 #if defined(DEBUG) | 276 #if defined(DEBUG) |
| 301 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | 277 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); |
| 302 VALIDATE_PTHREAD_RESULT(result); | 278 VALIDATE_PTHREAD_RESULT(result); |
| 303 #endif // defined(DEBUG) | 279 #endif // defined(DEBUG) |
| 304 | 280 |
| 305 result = pthread_mutex_init(data_.mutex(), &attr); | 281 result = pthread_mutex_init(data_.mutex(), &attr); |
| 306 VALIDATE_PTHREAD_RESULT(result); | 282 VALIDATE_PTHREAD_RESULT(result); |
| 307 | 283 |
| 308 result = pthread_mutexattr_destroy(&attr); | 284 result = pthread_mutexattr_destroy(&attr); |
| 309 VALIDATE_PTHREAD_RESULT(result); | 285 VALIDATE_PTHREAD_RESULT(result); |
| 310 | 286 |
| 311 result = pthread_cond_init(data_.cond(), NULL); | 287 result = pthread_cond_init(data_.cond(), NULL); |
| 312 VALIDATE_PTHREAD_RESULT(result); | 288 VALIDATE_PTHREAD_RESULT(result); |
| 313 | 289 |
| 314 #if defined(DEBUG) | 290 #if defined(DEBUG) |
| 315 // When running with assertions enabled we track the owner. | 291 // When running with assertions enabled we track the owner. |
| 316 owner_ = OSThread::kInvalidThreadId; | 292 owner_ = OSThread::kInvalidThreadId; |
| 317 #endif // defined(DEBUG) | 293 #endif // defined(DEBUG) |
| 318 } | 294 } |
| 319 | 295 |
| 320 | |
| 321 Monitor::~Monitor() { | 296 Monitor::~Monitor() { |
| 322 #if defined(DEBUG) | 297 #if defined(DEBUG) |
| 323 // When running with assertions enabled we track the owner. | 298 // When running with assertions enabled we track the owner. |
| 324 ASSERT(owner_ == OSThread::kInvalidThreadId); | 299 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 325 #endif // defined(DEBUG) | 300 #endif // defined(DEBUG) |
| 326 | 301 |
| 327 int result = pthread_mutex_destroy(data_.mutex()); | 302 int result = pthread_mutex_destroy(data_.mutex()); |
| 328 VALIDATE_PTHREAD_RESULT(result); | 303 VALIDATE_PTHREAD_RESULT(result); |
| 329 | 304 |
| 330 result = pthread_cond_destroy(data_.cond()); | 305 result = pthread_cond_destroy(data_.cond()); |
| 331 VALIDATE_PTHREAD_RESULT(result); | 306 VALIDATE_PTHREAD_RESULT(result); |
| 332 } | 307 } |
| 333 | 308 |
| 334 | |
| 335 bool Monitor::TryEnter() { | 309 bool Monitor::TryEnter() { |
| 336 int result = pthread_mutex_trylock(data_.mutex()); | 310 int result = pthread_mutex_trylock(data_.mutex()); |
| 337 // Return false if the lock is busy and locking failed. | 311 // Return false if the lock is busy and locking failed. |
| 338 if ((result == EBUSY) || (result == EDEADLK)) { | 312 if ((result == EBUSY) || (result == EDEADLK)) { |
| 339 return false; | 313 return false; |
| 340 } | 314 } |
| 341 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 315 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
| 342 #if defined(DEBUG) | 316 #if defined(DEBUG) |
| 343 // When running with assertions enabled we track the owner. | 317 // When running with assertions enabled we track the owner. |
| 344 ASSERT(owner_ == OSThread::kInvalidThreadId); | 318 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 345 owner_ = OSThread::GetCurrentThreadId(); | 319 owner_ = OSThread::GetCurrentThreadId(); |
| 346 #endif // defined(DEBUG) | 320 #endif // defined(DEBUG) |
| 347 return true; | 321 return true; |
| 348 } | 322 } |
| 349 | 323 |
| 350 | |
| 351 void Monitor::Enter() { | 324 void Monitor::Enter() { |
| 352 int result = pthread_mutex_lock(data_.mutex()); | 325 int result = pthread_mutex_lock(data_.mutex()); |
| 353 VALIDATE_PTHREAD_RESULT(result); | 326 VALIDATE_PTHREAD_RESULT(result); |
| 354 | 327 |
| 355 #if defined(DEBUG) | 328 #if defined(DEBUG) |
| 356 // When running with assertions enabled we track the owner. | 329 // When running with assertions enabled we track the owner. |
| 357 ASSERT(owner_ == OSThread::kInvalidThreadId); | 330 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 358 owner_ = OSThread::GetCurrentThreadId(); | 331 owner_ = OSThread::GetCurrentThreadId(); |
| 359 #endif // defined(DEBUG) | 332 #endif // defined(DEBUG) |
| 360 } | 333 } |
| 361 | 334 |
| 362 | |
| 363 void Monitor::Exit() { | 335 void Monitor::Exit() { |
| 364 #if defined(DEBUG) | 336 #if defined(DEBUG) |
| 365 // When running with assertions enabled we track the owner. | 337 // When running with assertions enabled we track the owner. |
| 366 ASSERT(IsOwnedByCurrentThread()); | 338 ASSERT(IsOwnedByCurrentThread()); |
| 367 owner_ = OSThread::kInvalidThreadId; | 339 owner_ = OSThread::kInvalidThreadId; |
| 368 #endif // defined(DEBUG) | 340 #endif // defined(DEBUG) |
| 369 | 341 |
| 370 int result = pthread_mutex_unlock(data_.mutex()); | 342 int result = pthread_mutex_unlock(data_.mutex()); |
| 371 VALIDATE_PTHREAD_RESULT(result); | 343 VALIDATE_PTHREAD_RESULT(result); |
| 372 } | 344 } |
| 373 | 345 |
| 374 | |
| 375 Monitor::WaitResult Monitor::Wait(int64_t millis) { | 346 Monitor::WaitResult Monitor::Wait(int64_t millis) { |
| 376 return WaitMicros(millis * kMicrosecondsPerMillisecond); | 347 return WaitMicros(millis * kMicrosecondsPerMillisecond); |
| 377 } | 348 } |
| 378 | 349 |
| 379 | |
| 380 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { | 350 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
| 381 #if defined(DEBUG) | 351 #if defined(DEBUG) |
| 382 // When running with assertions enabled we track the owner. | 352 // When running with assertions enabled we track the owner. |
| 383 ASSERT(IsOwnedByCurrentThread()); | 353 ASSERT(IsOwnedByCurrentThread()); |
| 384 ThreadId saved_owner = owner_; | 354 ThreadId saved_owner = owner_; |
| 385 owner_ = OSThread::kInvalidThreadId; | 355 owner_ = OSThread::kInvalidThreadId; |
| 386 #endif // defined(DEBUG) | 356 #endif // defined(DEBUG) |
| 387 | 357 |
| 388 Monitor::WaitResult retval = kNotified; | 358 Monitor::WaitResult retval = kNotified; |
| 389 if (micros == kNoTimeout) { | 359 if (micros == kNoTimeout) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 411 | 381 |
| 412 #if defined(DEBUG) | 382 #if defined(DEBUG) |
| 413 // When running with assertions enabled we track the owner. | 383 // When running with assertions enabled we track the owner. |
| 414 ASSERT(owner_ == OSThread::kInvalidThreadId); | 384 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 415 owner_ = OSThread::GetCurrentThreadId(); | 385 owner_ = OSThread::GetCurrentThreadId(); |
| 416 ASSERT(owner_ == saved_owner); | 386 ASSERT(owner_ == saved_owner); |
| 417 #endif // defined(DEBUG) | 387 #endif // defined(DEBUG) |
| 418 return retval; | 388 return retval; |
| 419 } | 389 } |
| 420 | 390 |
| 421 | |
| 422 void Monitor::Notify() { | 391 void Monitor::Notify() { |
| 423 // When running with assertions enabled we track the owner. | 392 // When running with assertions enabled we track the owner. |
| 424 ASSERT(IsOwnedByCurrentThread()); | 393 ASSERT(IsOwnedByCurrentThread()); |
| 425 int result = pthread_cond_signal(data_.cond()); | 394 int result = pthread_cond_signal(data_.cond()); |
| 426 VALIDATE_PTHREAD_RESULT(result); | 395 VALIDATE_PTHREAD_RESULT(result); |
| 427 } | 396 } |
| 428 | 397 |
| 429 | |
| 430 void Monitor::NotifyAll() { | 398 void Monitor::NotifyAll() { |
| 431 // When running with assertions enabled we track the owner. | 399 // When running with assertions enabled we track the owner. |
| 432 ASSERT(IsOwnedByCurrentThread()); | 400 ASSERT(IsOwnedByCurrentThread()); |
| 433 int result = pthread_cond_broadcast(data_.cond()); | 401 int result = pthread_cond_broadcast(data_.cond()); |
| 434 VALIDATE_PTHREAD_RESULT(result); | 402 VALIDATE_PTHREAD_RESULT(result); |
| 435 } | 403 } |
| 436 | 404 |
| 437 } // namespace dart | 405 } // namespace dart |
| 438 | 406 |
| 439 #endif // defined(HOST_OS_MACOS) | 407 #endif // defined(HOST_OS_MACOS) |
| OLD | NEW |