Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(421)

Side by Side Diff: runtime/vm/os_thread_macos.cc

Issue 1426743002: Add lock owner information for class Monitor and add assertions for wait/notify/notifyall. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code-review-comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/os_thread_linux.cc ('k') | runtime/vm/os_thread_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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(TARGET_OS_MACOS) 6 #if defined(TARGET_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 <sys/errno.h> // NOLINT
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 VALIDATE_PTHREAD_RESULT(result); 216 VALIDATE_PTHREAD_RESULT(result);
217 #endif // defined(DEBUG) 217 #endif // defined(DEBUG)
218 218
219 result = pthread_mutex_init(data_.mutex(), &attr); 219 result = pthread_mutex_init(data_.mutex(), &attr);
220 // Verify that creating a pthread_mutex succeeded. 220 // Verify that creating a pthread_mutex succeeded.
221 VALIDATE_PTHREAD_RESULT(result); 221 VALIDATE_PTHREAD_RESULT(result);
222 222
223 result = pthread_mutexattr_destroy(&attr); 223 result = pthread_mutexattr_destroy(&attr);
224 VALIDATE_PTHREAD_RESULT(result); 224 VALIDATE_PTHREAD_RESULT(result);
225 225
226 #if defined(DEBUG)
226 // When running with assertions enabled we do track the owner. 227 // When running with assertions enabled we do track the owner.
227 #if defined(DEBUG)
228 owner_ = OSThread::kInvalidThreadId; 228 owner_ = OSThread::kInvalidThreadId;
229 #endif // defined(DEBUG) 229 #endif // defined(DEBUG)
230 } 230 }
231 231
232 232
233 Mutex::~Mutex() { 233 Mutex::~Mutex() {
234 int result = pthread_mutex_destroy(data_.mutex()); 234 int result = pthread_mutex_destroy(data_.mutex());
235 // Verify that the pthread_mutex was destroyed. 235 // Verify that the pthread_mutex was destroyed.
236 VALIDATE_PTHREAD_RESULT(result); 236 VALIDATE_PTHREAD_RESULT(result);
237 237
238 #if defined(DEBUG)
238 // When running with assertions enabled we do track the owner. 239 // When running with assertions enabled we do track the owner.
239 #if defined(DEBUG)
240 ASSERT(owner_ == OSThread::kInvalidThreadId); 240 ASSERT(owner_ == OSThread::kInvalidThreadId);
241 #endif // defined(DEBUG) 241 #endif // defined(DEBUG)
242 } 242 }
243 243
244 244
245 void Mutex::Lock() { 245 void Mutex::Lock() {
246 int result = pthread_mutex_lock(data_.mutex()); 246 int result = pthread_mutex_lock(data_.mutex());
247 // Specifically check for dead lock to help debugging. 247 // Specifically check for dead lock to help debugging.
248 ASSERT(result != EDEADLK); 248 ASSERT(result != EDEADLK);
249 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. 249 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
250 #if defined(DEBUG)
250 // When running with assertions enabled we do track the owner. 251 // When running with assertions enabled we do track the owner.
251 #if defined(DEBUG)
252 owner_ = OSThread::GetCurrentThreadId(); 252 owner_ = OSThread::GetCurrentThreadId();
253 #endif // defined(DEBUG) 253 #endif // defined(DEBUG)
254 } 254 }
255 255
256 256
257 bool Mutex::TryLock() { 257 bool Mutex::TryLock() {
258 int result = pthread_mutex_trylock(data_.mutex()); 258 int result = pthread_mutex_trylock(data_.mutex());
259 // Return false if the lock is busy and locking failed. 259 // Return false if the lock is busy and locking failed.
260 if ((result == EBUSY) || (result == EDEADLK)) { 260 if ((result == EBUSY) || (result == EDEADLK)) {
261 return false; 261 return false;
262 } 262 }
263 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. 263 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
264 #if defined(DEBUG)
264 // When running with assertions enabled we do track the owner. 265 // When running with assertions enabled we do track the owner.
265 #if defined(DEBUG)
266 owner_ = OSThread::GetCurrentThreadId(); 266 owner_ = OSThread::GetCurrentThreadId();
267 #endif // defined(DEBUG) 267 #endif // defined(DEBUG)
268 return true; 268 return true;
269 } 269 }
270 270
271 271
272 void Mutex::Unlock() { 272 void Mutex::Unlock() {
273 #if defined(DEBUG)
273 // When running with assertions enabled we do track the owner. 274 // When running with assertions enabled we do track the owner.
274 #if defined(DEBUG)
275 ASSERT(IsOwnedByCurrentThread()); 275 ASSERT(IsOwnedByCurrentThread());
276 owner_ = OSThread::kInvalidThreadId; 276 owner_ = OSThread::kInvalidThreadId;
277 #endif // defined(DEBUG) 277 #endif // defined(DEBUG)
278 int result = pthread_mutex_unlock(data_.mutex()); 278 int result = pthread_mutex_unlock(data_.mutex());
279 // Specifically check for wrong thread unlocking to aid debugging. 279 // Specifically check for wrong thread unlocking to aid debugging.
280 ASSERT(result != EPERM); 280 ASSERT(result != EPERM);
281 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. 281 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
282 } 282 }
283 283
284 284
285 Monitor::Monitor() { 285 Monitor::Monitor() {
286 pthread_mutexattr_t attr; 286 pthread_mutexattr_t attr;
287 int result = pthread_mutexattr_init(&attr); 287 int result = pthread_mutexattr_init(&attr);
288 VALIDATE_PTHREAD_RESULT(result); 288 VALIDATE_PTHREAD_RESULT(result);
289 289
290 #if defined(DEBUG) 290 #if defined(DEBUG)
291 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); 291 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
292 VALIDATE_PTHREAD_RESULT(result); 292 VALIDATE_PTHREAD_RESULT(result);
293 #endif // defined(DEBUG) 293 #endif // defined(DEBUG)
294 294
295 result = pthread_mutex_init(data_.mutex(), &attr); 295 result = pthread_mutex_init(data_.mutex(), &attr);
296 VALIDATE_PTHREAD_RESULT(result); 296 VALIDATE_PTHREAD_RESULT(result);
297 297
298 result = pthread_mutexattr_destroy(&attr); 298 result = pthread_mutexattr_destroy(&attr);
299 VALIDATE_PTHREAD_RESULT(result); 299 VALIDATE_PTHREAD_RESULT(result);
300 300
301 result = pthread_cond_init(data_.cond(), NULL); 301 result = pthread_cond_init(data_.cond(), NULL);
302 VALIDATE_PTHREAD_RESULT(result); 302 VALIDATE_PTHREAD_RESULT(result);
303
304 #if defined(DEBUG)
305 // When running with assertions enabled we track the owner.
306 owner_ = OSThread::kInvalidThreadId;
307 #endif // defined(DEBUG)
303 } 308 }
304 309
305 310
306 Monitor::~Monitor() { 311 Monitor::~Monitor() {
312 #if defined(DEBUG)
313 // When running with assertions enabled we track the owner.
314 ASSERT(owner_ == OSThread::kInvalidThreadId);
315 #endif // defined(DEBUG)
316
307 int result = pthread_mutex_destroy(data_.mutex()); 317 int result = pthread_mutex_destroy(data_.mutex());
308 VALIDATE_PTHREAD_RESULT(result); 318 VALIDATE_PTHREAD_RESULT(result);
309 319
310 result = pthread_cond_destroy(data_.cond()); 320 result = pthread_cond_destroy(data_.cond());
311 VALIDATE_PTHREAD_RESULT(result); 321 VALIDATE_PTHREAD_RESULT(result);
312 } 322 }
313 323
314 324
315 void Monitor::Enter() { 325 void Monitor::Enter() {
316 int result = pthread_mutex_lock(data_.mutex()); 326 int result = pthread_mutex_lock(data_.mutex());
317 VALIDATE_PTHREAD_RESULT(result); 327 VALIDATE_PTHREAD_RESULT(result);
318 // TODO(iposva): Do we need to track lock owners? 328
329 #if defined(DEBUG)
330 // When running with assertions enabled we track the owner.
331 ASSERT(owner_ == OSThread::kInvalidThreadId);
332 owner_ = OSThread::GetCurrentThreadId();
333 #endif // defined(DEBUG)
319 } 334 }
320 335
321 336
322 void Monitor::Exit() { 337 void Monitor::Exit() {
323 // TODO(iposva): Do we need to track lock owners? 338 #if defined(DEBUG)
339 // When running with assertions enabled we track the owner.
340 ASSERT(IsOwnedByCurrentThread());
341 owner_ = OSThread::kInvalidThreadId;
342 #endif // defined(DEBUG)
343
324 int result = pthread_mutex_unlock(data_.mutex()); 344 int result = pthread_mutex_unlock(data_.mutex());
325 VALIDATE_PTHREAD_RESULT(result); 345 VALIDATE_PTHREAD_RESULT(result);
326 } 346 }
327 347
328 348
329 Monitor::WaitResult Monitor::Wait(int64_t millis) { 349 Monitor::WaitResult Monitor::Wait(int64_t millis) {
330 return WaitMicros(millis * kMicrosecondsPerMillisecond); 350 return WaitMicros(millis * kMicrosecondsPerMillisecond);
331 } 351 }
332 352
333 353
334 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { 354 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
335 // TODO(iposva): Do we need to track lock owners? 355 #if defined(DEBUG)
356 // When running with assertions enabled we track the owner.
357 ASSERT(IsOwnedByCurrentThread());
358 ThreadId saved_owner = owner_;
359 owner_ = OSThread::kInvalidThreadId;
360 #endif // defined(DEBUG)
361
336 Monitor::WaitResult retval = kNotified; 362 Monitor::WaitResult retval = kNotified;
337 if (micros == kNoTimeout) { 363 if (micros == kNoTimeout) {
338 // Wait forever. 364 // Wait forever.
339 int result = pthread_cond_wait(data_.cond(), data_.mutex()); 365 int result = pthread_cond_wait(data_.cond(), data_.mutex());
340 VALIDATE_PTHREAD_RESULT(result); 366 VALIDATE_PTHREAD_RESULT(result);
341 } else { 367 } else {
342 struct timespec ts; 368 struct timespec ts;
343 int64_t secs = micros / kMicrosecondsPerSecond; 369 int64_t secs = micros / kMicrosecondsPerSecond;
344 if (secs > kMaxInt32) { 370 if (secs > kMaxInt32) {
345 // Avoid truncation of overly large timeout values. 371 // Avoid truncation of overly large timeout values.
346 secs = kMaxInt32; 372 secs = kMaxInt32;
347 } 373 }
348 int64_t nanos = 374 int64_t nanos =
349 (micros - (secs * kMicrosecondsPerSecond)) * kNanosecondsPerMicrosecond; 375 (micros - (secs * kMicrosecondsPerSecond)) * kNanosecondsPerMicrosecond;
350 ts.tv_sec = static_cast<int32_t>(secs); 376 ts.tv_sec = static_cast<int32_t>(secs);
351 ts.tv_nsec = static_cast<long>(nanos); // NOLINT (long used in timespec). 377 ts.tv_nsec = static_cast<long>(nanos); // NOLINT (long used in timespec).
352 int result = pthread_cond_timedwait_relative_np(data_.cond(), 378 int result = pthread_cond_timedwait_relative_np(data_.cond(),
353 data_.mutex(), 379 data_.mutex(),
354 &ts); 380 &ts);
355 ASSERT((result == 0) || (result == ETIMEDOUT)); 381 ASSERT((result == 0) || (result == ETIMEDOUT));
356 if (result == ETIMEDOUT) { 382 if (result == ETIMEDOUT) {
357 retval = kTimedOut; 383 retval = kTimedOut;
358 } 384 }
359 } 385 }
386
387 #if defined(DEBUG)
388 // When running with assertions enabled we track the owner.
389 ASSERT(owner_ == OSThread::kInvalidThreadId);
390 owner_ = OSThread::GetCurrentThreadId();
391 ASSERT(owner_ == saved_owner);
392 #endif // defined(DEBUG)
360 return retval; 393 return retval;
361 } 394 }
362 395
363 396
364 void Monitor::Notify() { 397 void Monitor::Notify() {
365 // TODO(iposva): Do we need to track lock owners? 398 // When running with assertions enabled we track the owner.
399 ASSERT(IsOwnedByCurrentThread());
366 int result = pthread_cond_signal(data_.cond()); 400 int result = pthread_cond_signal(data_.cond());
367 VALIDATE_PTHREAD_RESULT(result); 401 VALIDATE_PTHREAD_RESULT(result);
368 } 402 }
369 403
370 404
371 void Monitor::NotifyAll() { 405 void Monitor::NotifyAll() {
372 // TODO(iposva): Do we need to track lock owners? 406 // When running with assertions enabled we track the owner.
407 ASSERT(IsOwnedByCurrentThread());
373 int result = pthread_cond_broadcast(data_.cond()); 408 int result = pthread_cond_broadcast(data_.cond());
374 VALIDATE_PTHREAD_RESULT(result); 409 VALIDATE_PTHREAD_RESULT(result);
375 } 410 }
376 411
377 } // namespace dart 412 } // namespace dart
378 413
379 #endif // defined(TARGET_OS_MACOS) 414 #endif // defined(TARGET_OS_MACOS)
OLDNEW
« no previous file with comments | « runtime/vm/os_thread_linux.cc ('k') | runtime/vm/os_thread_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698