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" | 5 #include "platform/globals.h" |
6 #if defined(TARGET_OS_LINUX) | 6 #if defined(TARGET_OS_LINUX) |
7 | 7 |
8 #include "platform/thread.h" | 8 #include "platform/thread.h" |
9 | 9 |
10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| 11 #include <sys/resource.h> // NOLINT |
11 #include <sys/time.h> // NOLINT | 12 #include <sys/time.h> // NOLINT |
12 | 13 |
13 #include "platform/assert.h" | 14 #include "platform/assert.h" |
14 | 15 |
15 namespace dart { | 16 namespace dart { |
16 | 17 |
17 #define VALIDATE_PTHREAD_RESULT(result) \ | 18 #define VALIDATE_PTHREAD_RESULT(result) \ |
18 if (result != 0) { \ | 19 if (result != 0) { \ |
19 const int kBufferSize = 1024; \ | 20 const int kBufferSize = 1024; \ |
20 char error_buf[kBufferSize]; \ | 21 char error_buf[kBufferSize]; \ |
(...skipping 11 matching lines...) Expand all Loading... |
32 __FILE__, __LINE__, result, \ | 33 __FILE__, __LINE__, result, \ |
33 strerror_r(result, error_buf, kBufferSize)); \ | 34 strerror_r(result, error_buf, kBufferSize)); \ |
34 return result; \ | 35 return result; \ |
35 } | 36 } |
36 #else | 37 #else |
37 #define RETURN_ON_PTHREAD_FAILURE(result) \ | 38 #define RETURN_ON_PTHREAD_FAILURE(result) \ |
38 if (result != 0) return result; | 39 if (result != 0) return result; |
39 #endif | 40 #endif |
40 | 41 |
41 | 42 |
42 static void ComputeTimeSpec(struct timespec* ts, int64_t millis) { | 43 static void ComputeTimeSpecMicros(struct timespec* ts, int64_t micros) { |
43 int64_t secs = millis / kMillisecondsPerSecond; | 44 int64_t secs = micros / kMicrosecondsPerSecond; |
44 int64_t nanos = | 45 int64_t nanos = |
45 (millis - (secs * kMillisecondsPerSecond)) * kNanosecondsPerMillisecond; | 46 (micros - (secs * kMicrosecondsPerSecond)) * kNanosecondsPerMicrosecond; |
46 int result = clock_gettime(CLOCK_MONOTONIC, ts); | 47 int result = clock_gettime(CLOCK_MONOTONIC, ts); |
47 ASSERT(result == 0); | 48 ASSERT(result == 0); |
48 ts->tv_sec += secs; | 49 ts->tv_sec += secs; |
49 ts->tv_nsec += nanos; | 50 ts->tv_nsec += nanos; |
50 if (ts->tv_nsec >= kNanosecondsPerSecond) { | 51 if (ts->tv_nsec >= kNanosecondsPerSecond) { |
51 ts->tv_sec += 1; | 52 ts->tv_sec += 1; |
52 ts->tv_nsec -= kNanosecondsPerSecond; | 53 ts->tv_nsec -= kNanosecondsPerSecond; |
53 } | 54 } |
54 } | 55 } |
55 | 56 |
56 | 57 |
| 58 static void ComputeTimeSpec(struct timespec* ts, int64_t millis) { |
| 59 ComputeTimeSpec(ts, millis * kMicrosecondsPerMillisecond); |
| 60 } |
| 61 |
| 62 |
57 class ThreadStartData { | 63 class ThreadStartData { |
58 public: | 64 public: |
59 ThreadStartData(Thread::ThreadStartFunction function, | 65 ThreadStartData(Thread::ThreadStartFunction function, |
60 uword parameter) | 66 uword parameter) |
61 : function_(function), parameter_(parameter) {} | 67 : function_(function), parameter_(parameter) {} |
62 | 68 |
63 Thread::ThreadStartFunction function() const { return function_; } | 69 Thread::ThreadStartFunction function() const { return function_; } |
64 uword parameter() const { return parameter_; } | 70 uword parameter() const { return parameter_; } |
65 | 71 |
66 private: | 72 private: |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 VALIDATE_PTHREAD_RESULT(result); | 143 VALIDATE_PTHREAD_RESULT(result); |
138 } | 144 } |
139 | 145 |
140 | 146 |
141 intptr_t Thread::GetMaxStackSize() { | 147 intptr_t Thread::GetMaxStackSize() { |
142 const int kStackSize = (128 * kWordSize * KB); | 148 const int kStackSize = (128 * kWordSize * KB); |
143 return kStackSize; | 149 return kStackSize; |
144 } | 150 } |
145 | 151 |
146 | 152 |
| 153 ThreadId Thread::GetCurrentThreadId() { |
| 154 return pthread_self(); |
| 155 } |
| 156 |
| 157 |
| 158 void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) { |
| 159 ASSERT(thread_id == GetCurrentThreadId()); |
| 160 ASSERT(cpu_usage != NULL); |
| 161 struct timespec ts; |
| 162 int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); |
| 163 ASSERT(r == 0); |
| 164 *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) / |
| 165 kNanosecondsPerMicrosecond; |
| 166 } |
| 167 |
| 168 |
147 Mutex::Mutex() { | 169 Mutex::Mutex() { |
148 pthread_mutexattr_t attr; | 170 pthread_mutexattr_t attr; |
149 int result = pthread_mutexattr_init(&attr); | 171 int result = pthread_mutexattr_init(&attr); |
150 VALIDATE_PTHREAD_RESULT(result); | 172 VALIDATE_PTHREAD_RESULT(result); |
151 | 173 |
152 #if defined(DEBUG) | 174 #if defined(DEBUG) |
153 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | 175 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); |
154 VALIDATE_PTHREAD_RESULT(result); | 176 VALIDATE_PTHREAD_RESULT(result); |
155 #endif // defined(DEBUG) | 177 #endif // defined(DEBUG) |
156 | 178 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 270 |
249 | 271 |
250 void Monitor::Exit() { | 272 void Monitor::Exit() { |
251 // TODO(iposva): Do we need to track lock owners? | 273 // TODO(iposva): Do we need to track lock owners? |
252 int result = pthread_mutex_unlock(data_.mutex()); | 274 int result = pthread_mutex_unlock(data_.mutex()); |
253 VALIDATE_PTHREAD_RESULT(result); | 275 VALIDATE_PTHREAD_RESULT(result); |
254 } | 276 } |
255 | 277 |
256 | 278 |
257 Monitor::WaitResult Monitor::Wait(int64_t millis) { | 279 Monitor::WaitResult Monitor::Wait(int64_t millis) { |
| 280 return WaitMicros(millis * kMicrosecondsPerMillisecond); |
| 281 } |
| 282 |
| 283 |
| 284 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
258 // TODO(iposva): Do we need to track lock owners? | 285 // TODO(iposva): Do we need to track lock owners? |
259 Monitor::WaitResult retval = kNotified; | 286 Monitor::WaitResult retval = kNotified; |
260 if (millis == 0) { | 287 if (micros == kNoTimeout) { |
261 // Wait forever. | 288 // Wait forever. |
262 int result = pthread_cond_wait(data_.cond(), data_.mutex()); | 289 int result = pthread_cond_wait(data_.cond(), data_.mutex()); |
263 VALIDATE_PTHREAD_RESULT(result); | 290 VALIDATE_PTHREAD_RESULT(result); |
264 } else { | 291 } else { |
265 struct timespec ts; | 292 struct timespec ts; |
266 ComputeTimeSpec(&ts, millis); | 293 ComputeTimeSpecMicros(&ts, micros); |
267 int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts); | 294 int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts); |
268 ASSERT((result == 0) || (result == ETIMEDOUT)); | 295 ASSERT((result == 0) || (result == ETIMEDOUT)); |
269 if (result == ETIMEDOUT) { | 296 if (result == ETIMEDOUT) { |
270 retval = kTimedOut; | 297 retval = kTimedOut; |
271 } | 298 } |
272 } | 299 } |
273 return retval; | 300 return retval; |
274 } | 301 } |
275 | 302 |
276 | 303 |
277 void Monitor::Notify() { | 304 void Monitor::Notify() { |
278 // TODO(iposva): Do we need to track lock owners? | 305 // TODO(iposva): Do we need to track lock owners? |
279 int result = pthread_cond_signal(data_.cond()); | 306 int result = pthread_cond_signal(data_.cond()); |
280 VALIDATE_PTHREAD_RESULT(result); | 307 VALIDATE_PTHREAD_RESULT(result); |
281 } | 308 } |
282 | 309 |
283 | 310 |
284 void Monitor::NotifyAll() { | 311 void Monitor::NotifyAll() { |
285 // TODO(iposva): Do we need to track lock owners? | 312 // TODO(iposva): Do we need to track lock owners? |
286 int result = pthread_cond_broadcast(data_.cond()); | 313 int result = pthread_cond_broadcast(data_.cond()); |
287 VALIDATE_PTHREAD_RESULT(result); | 314 VALIDATE_PTHREAD_RESULT(result); |
288 } | 315 } |
289 | 316 |
290 } // namespace dart | 317 } // namespace dart |
291 | 318 |
292 #endif // defined(TARGET_OS_LINUX) | 319 #endif // defined(TARGET_OS_LINUX) |
OLD | NEW |