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