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

Side by Side Diff: base/synchronization/condition_variable_posix.cc

Issue 24158005: Fix WaitableEvent and ConditionVariable::TimedWait to use monotonic time on non-mac posix (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix mac Created 7 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | base/synchronization/condition_variable_unittest.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/synchronization/condition_variable.h" 5 #include "base/synchronization/condition_variable.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/time.h> 8 #include <sys/time.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/synchronization/lock.h" 11 #include "base/synchronization/lock.h"
12 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 14
15 namespace base { 15 namespace base {
16 16
17 ConditionVariable::ConditionVariable(Lock* user_lock) 17 ConditionVariable::ConditionVariable(Lock* user_lock)
18 : user_mutex_(user_lock->lock_.native_handle()) 18 : user_mutex_(user_lock->lock_.native_handle())
19 #if !defined(NDEBUG) 19 #if !defined(NDEBUG)
20 , user_lock_(user_lock) 20 , user_lock_(user_lock)
21 #endif 21 #endif
22 { 22 {
23 int rv = pthread_cond_init(&condition_, NULL); 23 int rv = 0;
24 // http://crbug.com/293736
25 // NaCl doesn't support monotonic clock based absolute deadlines.
26 // Android supports it through the non-standard
27 // pthread_cond_timedwait_monotonic_np.
28 // Mac can use relative time deadlines.
29 #if !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID)
30 pthread_condattr_t attrs;
31 rv = pthread_condattr_init(&attrs);
32 DCHECK_EQ(0, rv);
33 pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC);
34 rv = pthread_cond_init(&condition_, &attrs);
35 pthread_condattr_destroy(&attrs);
36 #else
37 rv = pthread_cond_init(&condition_, NULL);
38 #endif
24 DCHECK_EQ(0, rv); 39 DCHECK_EQ(0, rv);
25 } 40 }
26 41
27 ConditionVariable::~ConditionVariable() { 42 ConditionVariable::~ConditionVariable() {
28 int rv = pthread_cond_destroy(&condition_); 43 int rv = pthread_cond_destroy(&condition_);
29 DCHECK_EQ(0, rv); 44 DCHECK_EQ(0, rv);
30 } 45 }
31 46
32 void ConditionVariable::Wait() { 47 void ConditionVariable::Wait() {
33 base::ThreadRestrictions::AssertWaitAllowed(); 48 base::ThreadRestrictions::AssertWaitAllowed();
34 #if !defined(NDEBUG) 49 #if !defined(NDEBUG)
35 user_lock_->CheckHeldAndUnmark(); 50 user_lock_->CheckHeldAndUnmark();
36 #endif 51 #endif
37 int rv = pthread_cond_wait(&condition_, user_mutex_); 52 int rv = pthread_cond_wait(&condition_, user_mutex_);
38 DCHECK_EQ(0, rv); 53 DCHECK_EQ(0, rv);
39 #if !defined(NDEBUG) 54 #if !defined(NDEBUG)
40 user_lock_->CheckUnheldAndMark(); 55 user_lock_->CheckUnheldAndMark();
41 #endif 56 #endif
42 } 57 }
43 58
44 void ConditionVariable::TimedWait(const TimeDelta& max_time) { 59 void ConditionVariable::TimedWait(const TimeDelta& max_time) {
45 base::ThreadRestrictions::AssertWaitAllowed(); 60 base::ThreadRestrictions::AssertWaitAllowed();
46 int64 usecs = max_time.InMicroseconds(); 61 int64 usecs = max_time.InMicroseconds();
47 62 struct timespec relative_time;
48 // The timeout argument to pthread_cond_timedwait is in absolute time. 63 relative_time.tv_sec = usecs / Time::kMicrosecondsPerSecond;
49 struct timeval now; 64 relative_time.tv_nsec =
50 gettimeofday(&now, NULL); 65 (usecs % Time::kMicrosecondsPerSecond) * Time::kNanosecondsPerMicrosecond;
51
52 struct timespec abstime;
53 abstime.tv_sec = now.tv_sec + (usecs / Time::kMicrosecondsPerSecond);
54 abstime.tv_nsec = (now.tv_usec + (usecs % Time::kMicrosecondsPerSecond)) *
55 Time::kNanosecondsPerMicrosecond;
56 abstime.tv_sec += abstime.tv_nsec / Time::kNanosecondsPerSecond;
57 abstime.tv_nsec %= Time::kNanosecondsPerSecond;
58 DCHECK_GE(abstime.tv_sec, now.tv_sec); // Overflow paranoia
59 66
60 #if !defined(NDEBUG) 67 #if !defined(NDEBUG)
61 user_lock_->CheckHeldAndUnmark(); 68 user_lock_->CheckHeldAndUnmark();
62 #endif 69 #endif
63 int rv = pthread_cond_timedwait(&condition_, user_mutex_, &abstime); 70
71 #if defined(OS_MACOSX)
72 int rv = pthread_cond_timedwait_relative_np(
73 &condition_, user_mutex_, &relative_time);
74 #else
75 // The timeout argument to pthread_cond_timedwait is in absolute time.
76 struct timespec absolute_time;
77 #if defined(OS_NACL)
Nico 2013/10/01 23:01:53 Maybe add a "// See comment in constructor for why
piman 2013/10/01 23:16:33 Done.
78 struct timeval now;
79 gettimeofday(&now, NULL);
80 absolute_time.tv_sec = now.tv_sec;
81 absolute_time.tv_nsec = now.tv_usec * Time::kNanosecondsPerMicrosecond;
82 #else
83 struct timespec now;
84 clock_gettime(CLOCK_MONOTONIC, &now);
85 absolute_time.tv_sec = now.tv_sec;
86 absolute_time.tv_nsec = now.tv_nsec;
87 #endif
88
89 absolute_time.tv_sec += relative_time.tv_sec;
90 absolute_time.tv_nsec += relative_time.tv_nsec;
91 absolute_time.tv_sec += absolute_time.tv_nsec / Time::kNanosecondsPerSecond;
92 absolute_time.tv_nsec %= Time::kNanosecondsPerSecond;
93 DCHECK_GE(absolute_time.tv_sec, now.tv_sec); // Overflow paranoia
94
95 #if defined(OS_ANDROID)
96 int rv = pthread_cond_timedwait_monotonic_np(
97 &condition_, user_mutex_, &absolute_time);
98 #else
99 int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time);
100 #endif // OS_ANDROID
101 #endif // OS_MACOSX
102
64 DCHECK(rv == 0 || rv == ETIMEDOUT); 103 DCHECK(rv == 0 || rv == ETIMEDOUT);
65 #if !defined(NDEBUG) 104 #if !defined(NDEBUG)
66 user_lock_->CheckUnheldAndMark(); 105 user_lock_->CheckUnheldAndMark();
67 #endif 106 #endif
68 } 107 }
69 108
70 void ConditionVariable::Broadcast() { 109 void ConditionVariable::Broadcast() {
71 int rv = pthread_cond_broadcast(&condition_); 110 int rv = pthread_cond_broadcast(&condition_);
72 DCHECK_EQ(0, rv); 111 DCHECK_EQ(0, rv);
73 } 112 }
74 113
75 void ConditionVariable::Signal() { 114 void ConditionVariable::Signal() {
76 int rv = pthread_cond_signal(&condition_); 115 int rv = pthread_cond_signal(&condition_);
77 DCHECK_EQ(0, rv); 116 DCHECK_EQ(0, rv);
78 } 117 }
79 118
80 } // namespace base 119 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/synchronization/condition_variable_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698