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

Side by Side Diff: src/base/platform/condition-variable.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 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 | « src/base/macros.h ('k') | src/base/platform/elapsed-timer.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project 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 "src/base/platform/condition-variable.h" 5 #include "src/base/platform/condition-variable.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <time.h> 8 #include <time.h>
9 9
10 #include "src/base/platform/time.h" 10 #include "src/base/platform/time.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace base { 13 namespace base {
14 14
15 #if V8_OS_POSIX 15 #if V8_OS_POSIX
16 16
17 ConditionVariable::ConditionVariable() { 17 ConditionVariable::ConditionVariable() {
18 // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary 18 // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary
19 // hack to support cross-compiling Chrome for Android in AOSP. Remove 19 // hack to support cross-compiling Chrome for Android in AOSP. Remove
20 // this once AOSP is fixed. 20 // this once AOSP is fixed.
21 #if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || \ 21 #if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || \
22 (V8_OS_LINUX && V8_LIBC_GLIBC)) && !V8_LIBRT_NOT_AVAILABLE 22 (V8_OS_LINUX && V8_LIBC_GLIBC)) && !V8_LIBRT_NOT_AVAILABLE
23 // On Free/Net/OpenBSD and Linux with glibc we can change the time 23 // On Free/Net/OpenBSD and Linux with glibc we can change the time
24 // source for pthread_cond_timedwait() to use the monotonic clock. 24 // source for pthread_cond_timedwait() to use the monotonic clock.
25 pthread_condattr_t attr; 25 pthread_condattr_t attr;
26 int result = pthread_condattr_init(&attr); 26 int result = pthread_condattr_init(&attr);
27 ASSERT_EQ(0, result); 27 DCHECK_EQ(0, result);
28 result = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 28 result = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
29 ASSERT_EQ(0, result); 29 DCHECK_EQ(0, result);
30 result = pthread_cond_init(&native_handle_, &attr); 30 result = pthread_cond_init(&native_handle_, &attr);
31 ASSERT_EQ(0, result); 31 DCHECK_EQ(0, result);
32 result = pthread_condattr_destroy(&attr); 32 result = pthread_condattr_destroy(&attr);
33 #else 33 #else
34 int result = pthread_cond_init(&native_handle_, NULL); 34 int result = pthread_cond_init(&native_handle_, NULL);
35 #endif 35 #endif
36 ASSERT_EQ(0, result); 36 DCHECK_EQ(0, result);
37 USE(result); 37 USE(result);
38 } 38 }
39 39
40 40
41 ConditionVariable::~ConditionVariable() { 41 ConditionVariable::~ConditionVariable() {
42 int result = pthread_cond_destroy(&native_handle_); 42 int result = pthread_cond_destroy(&native_handle_);
43 ASSERT_EQ(0, result); 43 DCHECK_EQ(0, result);
44 USE(result); 44 USE(result);
45 } 45 }
46 46
47 47
48 void ConditionVariable::NotifyOne() { 48 void ConditionVariable::NotifyOne() {
49 int result = pthread_cond_signal(&native_handle_); 49 int result = pthread_cond_signal(&native_handle_);
50 ASSERT_EQ(0, result); 50 DCHECK_EQ(0, result);
51 USE(result); 51 USE(result);
52 } 52 }
53 53
54 54
55 void ConditionVariable::NotifyAll() { 55 void ConditionVariable::NotifyAll() {
56 int result = pthread_cond_broadcast(&native_handle_); 56 int result = pthread_cond_broadcast(&native_handle_);
57 ASSERT_EQ(0, result); 57 DCHECK_EQ(0, result);
58 USE(result); 58 USE(result);
59 } 59 }
60 60
61 61
62 void ConditionVariable::Wait(Mutex* mutex) { 62 void ConditionVariable::Wait(Mutex* mutex) {
63 mutex->AssertHeldAndUnmark(); 63 mutex->AssertHeldAndUnmark();
64 int result = pthread_cond_wait(&native_handle_, &mutex->native_handle()); 64 int result = pthread_cond_wait(&native_handle_, &mutex->native_handle());
65 ASSERT_EQ(0, result); 65 DCHECK_EQ(0, result);
66 USE(result); 66 USE(result);
67 mutex->AssertUnheldAndMark(); 67 mutex->AssertUnheldAndMark();
68 } 68 }
69 69
70 70
71 bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) { 71 bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
72 struct timespec ts; 72 struct timespec ts;
73 int result; 73 int result;
74 mutex->AssertHeldAndUnmark(); 74 mutex->AssertHeldAndUnmark();
75 #if V8_OS_MACOSX 75 #if V8_OS_MACOSX
76 // Mac OS X provides pthread_cond_timedwait_relative_np(), which does 76 // Mac OS X provides pthread_cond_timedwait_relative_np(), which does
77 // not depend on the real time clock, which is what you really WANT here! 77 // not depend on the real time clock, which is what you really WANT here!
78 ts = rel_time.ToTimespec(); 78 ts = rel_time.ToTimespec();
79 ASSERT_GE(ts.tv_sec, 0); 79 DCHECK_GE(ts.tv_sec, 0);
80 ASSERT_GE(ts.tv_nsec, 0); 80 DCHECK_GE(ts.tv_nsec, 0);
81 result = pthread_cond_timedwait_relative_np( 81 result = pthread_cond_timedwait_relative_np(
82 &native_handle_, &mutex->native_handle(), &ts); 82 &native_handle_, &mutex->native_handle(), &ts);
83 #else 83 #else
84 // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary 84 // TODO(bmeurer): The test for V8_LIBRT_NOT_AVAILABLE is a temporary
85 // hack to support cross-compiling Chrome for Android in AOSP. Remove 85 // hack to support cross-compiling Chrome for Android in AOSP. Remove
86 // this once AOSP is fixed. 86 // this once AOSP is fixed.
87 #if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || \ 87 #if (V8_OS_FREEBSD || V8_OS_NETBSD || V8_OS_OPENBSD || \
88 (V8_OS_LINUX && V8_LIBC_GLIBC)) && !V8_LIBRT_NOT_AVAILABLE 88 (V8_OS_LINUX && V8_LIBC_GLIBC)) && !V8_LIBRT_NOT_AVAILABLE
89 // On Free/Net/OpenBSD and Linux with glibc we can change the time 89 // On Free/Net/OpenBSD and Linux with glibc we can change the time
90 // source for pthread_cond_timedwait() to use the monotonic clock. 90 // source for pthread_cond_timedwait() to use the monotonic clock.
91 result = clock_gettime(CLOCK_MONOTONIC, &ts); 91 result = clock_gettime(CLOCK_MONOTONIC, &ts);
92 ASSERT_EQ(0, result); 92 DCHECK_EQ(0, result);
93 Time now = Time::FromTimespec(ts); 93 Time now = Time::FromTimespec(ts);
94 #else 94 #else
95 // The timeout argument to pthread_cond_timedwait() is in absolute time. 95 // The timeout argument to pthread_cond_timedwait() is in absolute time.
96 Time now = Time::NowFromSystemTime(); 96 Time now = Time::NowFromSystemTime();
97 #endif 97 #endif
98 Time end_time = now + rel_time; 98 Time end_time = now + rel_time;
99 ASSERT_GE(end_time, now); 99 DCHECK_GE(end_time, now);
100 ts = end_time.ToTimespec(); 100 ts = end_time.ToTimespec();
101 result = pthread_cond_timedwait( 101 result = pthread_cond_timedwait(
102 &native_handle_, &mutex->native_handle(), &ts); 102 &native_handle_, &mutex->native_handle(), &ts);
103 #endif // V8_OS_MACOSX 103 #endif // V8_OS_MACOSX
104 mutex->AssertUnheldAndMark(); 104 mutex->AssertUnheldAndMark();
105 if (result == ETIMEDOUT) { 105 if (result == ETIMEDOUT) {
106 return false; 106 return false;
107 } 107 }
108 ASSERT_EQ(0, result); 108 DCHECK_EQ(0, result);
109 return true; 109 return true;
110 } 110 }
111 111
112 #elif V8_OS_WIN 112 #elif V8_OS_WIN
113 113
114 struct ConditionVariable::Event { 114 struct ConditionVariable::Event {
115 Event() : handle_(::CreateEventA(NULL, true, false, NULL)) { 115 Event() : handle_(::CreateEventA(NULL, true, false, NULL)) {
116 ASSERT(handle_ != NULL); 116 DCHECK(handle_ != NULL);
117 } 117 }
118 118
119 ~Event() { 119 ~Event() {
120 BOOL ok = ::CloseHandle(handle_); 120 BOOL ok = ::CloseHandle(handle_);
121 ASSERT(ok); 121 DCHECK(ok);
122 USE(ok); 122 USE(ok);
123 } 123 }
124 124
125 bool WaitFor(DWORD timeout_ms) { 125 bool WaitFor(DWORD timeout_ms) {
126 DWORD result = ::WaitForSingleObject(handle_, timeout_ms); 126 DWORD result = ::WaitForSingleObject(handle_, timeout_ms);
127 if (result == WAIT_OBJECT_0) { 127 if (result == WAIT_OBJECT_0) {
128 return true; 128 return true;
129 } 129 }
130 ASSERT(result == WAIT_TIMEOUT); 130 DCHECK(result == WAIT_TIMEOUT);
131 return false; 131 return false;
132 } 132 }
133 133
134 HANDLE handle_; 134 HANDLE handle_;
135 Event* next_; 135 Event* next_;
136 HANDLE thread_; 136 HANDLE thread_;
137 volatile bool notified_; 137 volatile bool notified_;
138 }; 138 };
139 139
140 140
141 ConditionVariable::NativeHandle::~NativeHandle() { 141 ConditionVariable::NativeHandle::~NativeHandle() {
142 ASSERT(waitlist_ == NULL); 142 DCHECK(waitlist_ == NULL);
143 143
144 while (freelist_ != NULL) { 144 while (freelist_ != NULL) {
145 Event* event = freelist_; 145 Event* event = freelist_;
146 freelist_ = event->next_; 146 freelist_ = event->next_;
147 delete event; 147 delete event;
148 } 148 }
149 } 149 }
150 150
151 151
152 ConditionVariable::Event* ConditionVariable::NativeHandle::Pre() { 152 ConditionVariable::Event* ConditionVariable::NativeHandle::Pre() {
153 LockGuard<Mutex> lock_guard(&mutex_); 153 LockGuard<Mutex> lock_guard(&mutex_);
154 154
155 // Grab an event from the free list or create a new one. 155 // Grab an event from the free list or create a new one.
156 Event* event = freelist_; 156 Event* event = freelist_;
157 if (event != NULL) { 157 if (event != NULL) {
158 freelist_ = event->next_; 158 freelist_ = event->next_;
159 } else { 159 } else {
160 event = new Event; 160 event = new Event;
161 } 161 }
162 event->thread_ = GetCurrentThread(); 162 event->thread_ = GetCurrentThread();
163 event->notified_ = false; 163 event->notified_ = false;
164 164
165 #ifdef DEBUG 165 #ifdef DEBUG
166 // The event must not be on the wait list. 166 // The event must not be on the wait list.
167 for (Event* we = waitlist_; we != NULL; we = we->next_) { 167 for (Event* we = waitlist_; we != NULL; we = we->next_) {
168 ASSERT_NE(event, we); 168 DCHECK_NE(event, we);
169 } 169 }
170 #endif 170 #endif
171 171
172 // Prepend the event to the wait list. 172 // Prepend the event to the wait list.
173 event->next_ = waitlist_; 173 event->next_ = waitlist_;
174 waitlist_ = event; 174 waitlist_ = event;
175 175
176 return event; 176 return event;
177 } 177 }
178 178
179 179
180 void ConditionVariable::NativeHandle::Post(Event* event, bool result) { 180 void ConditionVariable::NativeHandle::Post(Event* event, bool result) {
181 LockGuard<Mutex> lock_guard(&mutex_); 181 LockGuard<Mutex> lock_guard(&mutex_);
182 182
183 // Remove the event from the wait list. 183 // Remove the event from the wait list.
184 for (Event** wep = &waitlist_;; wep = &(*wep)->next_) { 184 for (Event** wep = &waitlist_;; wep = &(*wep)->next_) {
185 ASSERT_NE(NULL, *wep); 185 DCHECK_NE(NULL, *wep);
186 if (*wep == event) { 186 if (*wep == event) {
187 *wep = event->next_; 187 *wep = event->next_;
188 break; 188 break;
189 } 189 }
190 } 190 }
191 191
192 #ifdef DEBUG 192 #ifdef DEBUG
193 // The event must not be on the free list. 193 // The event must not be on the free list.
194 for (Event* fe = freelist_; fe != NULL; fe = fe->next_) { 194 for (Event* fe = freelist_; fe != NULL; fe = fe->next_) {
195 ASSERT_NE(event, fe); 195 DCHECK_NE(event, fe);
196 } 196 }
197 #endif 197 #endif
198 198
199 // Reset the event. 199 // Reset the event.
200 BOOL ok = ::ResetEvent(event->handle_); 200 BOOL ok = ::ResetEvent(event->handle_);
201 ASSERT(ok); 201 DCHECK(ok);
202 USE(ok); 202 USE(ok);
203 203
204 // Insert the event into the free list. 204 // Insert the event into the free list.
205 event->next_ = freelist_; 205 event->next_ = freelist_;
206 freelist_ = event; 206 freelist_ = event;
207 207
208 // Forward signals delivered after the timeout to the next waiting event. 208 // Forward signals delivered after the timeout to the next waiting event.
209 if (!result && event->notified_ && waitlist_ != NULL) { 209 if (!result && event->notified_ && waitlist_ != NULL) {
210 ok = ::SetEvent(waitlist_->handle_); 210 ok = ::SetEvent(waitlist_->handle_);
211 ASSERT(ok); 211 DCHECK(ok);
212 USE(ok); 212 USE(ok);
213 waitlist_->notified_ = true; 213 waitlist_->notified_ = true;
214 } 214 }
215 } 215 }
216 216
217 217
218 ConditionVariable::ConditionVariable() {} 218 ConditionVariable::ConditionVariable() {}
219 219
220 220
221 ConditionVariable::~ConditionVariable() {} 221 ConditionVariable::~ConditionVariable() {}
222 222
223 223
224 void ConditionVariable::NotifyOne() { 224 void ConditionVariable::NotifyOne() {
225 // Notify the thread with the highest priority in the waitlist 225 // Notify the thread with the highest priority in the waitlist
226 // that was not already signalled. 226 // that was not already signalled.
227 LockGuard<Mutex> lock_guard(native_handle_.mutex()); 227 LockGuard<Mutex> lock_guard(native_handle_.mutex());
228 Event* highest_event = NULL; 228 Event* highest_event = NULL;
229 int highest_priority = std::numeric_limits<int>::min(); 229 int highest_priority = std::numeric_limits<int>::min();
230 for (Event* event = native_handle().waitlist(); 230 for (Event* event = native_handle().waitlist();
231 event != NULL; 231 event != NULL;
232 event = event->next_) { 232 event = event->next_) {
233 if (event->notified_) { 233 if (event->notified_) {
234 continue; 234 continue;
235 } 235 }
236 int priority = GetThreadPriority(event->thread_); 236 int priority = GetThreadPriority(event->thread_);
237 ASSERT_NE(THREAD_PRIORITY_ERROR_RETURN, priority); 237 DCHECK_NE(THREAD_PRIORITY_ERROR_RETURN, priority);
238 if (priority >= highest_priority) { 238 if (priority >= highest_priority) {
239 highest_priority = priority; 239 highest_priority = priority;
240 highest_event = event; 240 highest_event = event;
241 } 241 }
242 } 242 }
243 if (highest_event != NULL) { 243 if (highest_event != NULL) {
244 ASSERT(!highest_event->notified_); 244 DCHECK(!highest_event->notified_);
245 ::SetEvent(highest_event->handle_); 245 ::SetEvent(highest_event->handle_);
246 highest_event->notified_ = true; 246 highest_event->notified_ = true;
247 } 247 }
248 } 248 }
249 249
250 250
251 void ConditionVariable::NotifyAll() { 251 void ConditionVariable::NotifyAll() {
252 // Notify all threads on the waitlist. 252 // Notify all threads on the waitlist.
253 LockGuard<Mutex> lock_guard(native_handle_.mutex()); 253 LockGuard<Mutex> lock_guard(native_handle_.mutex());
254 for (Event* event = native_handle().waitlist(); 254 for (Event* event = native_handle().waitlist();
(...skipping 15 matching lines...) Expand all
270 mutex->Unlock(); 270 mutex->Unlock();
271 271
272 // Wait on the wait event. 272 // Wait on the wait event.
273 while (!event->WaitFor(INFINITE)) 273 while (!event->WaitFor(INFINITE))
274 ; 274 ;
275 275
276 // Reaquire the user mutex. 276 // Reaquire the user mutex.
277 mutex->Lock(); 277 mutex->Lock();
278 278
279 // Release the wait event (we must have been notified). 279 // Release the wait event (we must have been notified).
280 ASSERT(event->notified_); 280 DCHECK(event->notified_);
281 native_handle_.Post(event, true); 281 native_handle_.Post(event, true);
282 } 282 }
283 283
284 284
285 bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) { 285 bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
286 // Create and setup the wait event. 286 // Create and setup the wait event.
287 Event* event = native_handle_.Pre(); 287 Event* event = native_handle_.Pre();
288 288
289 // Release the user mutex. 289 // Release the user mutex.
290 mutex->Unlock(); 290 mutex->Unlock();
(...skipping 13 matching lines...) Expand all
304 } else { 304 } else {
305 result = event->WaitFor((msec < 0) ? 0 : static_cast<DWORD>(msec)); 305 result = event->WaitFor((msec < 0) ? 0 : static_cast<DWORD>(msec));
306 break; 306 break;
307 } 307 }
308 } 308 }
309 309
310 // Reaquire the user mutex. 310 // Reaquire the user mutex.
311 mutex->Lock(); 311 mutex->Lock();
312 312
313 // Release the wait event. 313 // Release the wait event.
314 ASSERT(!result || event->notified_); 314 DCHECK(!result || event->notified_);
315 native_handle_.Post(event, result); 315 native_handle_.Post(event, result);
316 316
317 return result; 317 return result;
318 } 318 }
319 319
320 #endif // V8_OS_POSIX 320 #endif // V8_OS_POSIX
321 321
322 } } // namespace v8::base 322 } } // namespace v8::base
OLDNEW
« no previous file with comments | « src/base/macros.h ('k') | src/base/platform/elapsed-timer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698