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