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