| 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 |