13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/condition_variable.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <errno.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/time.h> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/lock.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace base { 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottConditionVariable::ConditionVariable(Lock* user_lock) 173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen : user_mutex_(user_lock->lock_.os_lock()) 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(NDEBUG) 193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen , user_lock_(user_lock) 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{ 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pthread_cond_init(&condition_, NULL); 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(0, rv); 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottConditionVariable::~ConditionVariable() { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pthread_cond_destroy(&condition_); 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(0, rv); 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ConditionVariable::Wait() { 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(NDEBUG) 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch user_lock_->CheckHeldAndUnmark(); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pthread_cond_wait(&condition_, user_mutex_); 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(0, rv); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(NDEBUG) 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch user_lock_->CheckUnheldAndMark(); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ConditionVariable::TimedWait(const TimeDelta& max_time) { 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 usecs = max_time.InMicroseconds(); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The timeout argument to pthread_cond_timedwait is in absolute time. 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timeval now; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott gettimeofday(&now, NULL); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct timespec abstime; 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott abstime.tv_sec = now.tv_sec + (usecs / Time::kMicrosecondsPerSecond); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott abstime.tv_nsec = (now.tv_usec + (usecs % Time::kMicrosecondsPerSecond)) * 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Time::kNanosecondsPerMicrosecond; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott abstime.tv_sec += abstime.tv_nsec / Time::kNanosecondsPerSecond; 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott abstime.tv_nsec %= Time::kNanosecondsPerSecond; 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_GE(abstime.tv_sec, now.tv_sec); // Overflow paranoia 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(NDEBUG) 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch user_lock_->CheckHeldAndUnmark(); 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pthread_cond_timedwait(&condition_, user_mutex_, &abstime); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(rv == 0 || rv == ETIMEDOUT); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(NDEBUG) 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch user_lock_->CheckUnheldAndMark(); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ConditionVariable::Broadcast() { 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pthread_cond_broadcast(&condition_); 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(0, rv); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ConditionVariable::Signal() { 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int rv = pthread_cond_signal(&condition_); 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(0, rv); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} // namespace base 78