| 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" // NOLINT |
| 6 #if defined(TARGET_OS_LINUX) | 6 #if defined(TARGET_OS_LINUX) |
| 7 | 7 |
| 8 #include "vm/thread.h" | 8 #include "vm/os_thread.h" |
| 9 | 9 |
| 10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| 11 #include <sys/resource.h> // NOLINT | 11 #include <sys/resource.h> // NOLINT |
| 12 #include <sys/time.h> // NOLINT | 12 #include <sys/time.h> // NOLINT |
| 13 | 13 |
| 14 #include "platform/assert.h" | 14 #include "platform/assert.h" |
| 15 #include "vm/isolate.h" | 15 #include "vm/isolate.h" |
| 16 | 16 |
| 17 namespace dart { | 17 namespace dart { |
| 18 | 18 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 ts->tv_nsec += nanos; | 51 ts->tv_nsec += nanos; |
| 52 if (ts->tv_nsec >= kNanosecondsPerSecond) { | 52 if (ts->tv_nsec >= kNanosecondsPerSecond) { |
| 53 ts->tv_sec += 1; | 53 ts->tv_sec += 1; |
| 54 ts->tv_nsec -= kNanosecondsPerSecond; | 54 ts->tv_nsec -= kNanosecondsPerSecond; |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 class ThreadStartData { | 59 class ThreadStartData { |
| 60 public: | 60 public: |
| 61 ThreadStartData(Thread::ThreadStartFunction function, | 61 ThreadStartData(OSThread::ThreadStartFunction function, |
| 62 uword parameter) | 62 uword parameter) |
| 63 : function_(function), parameter_(parameter) {} | 63 : function_(function), parameter_(parameter) {} |
| 64 | 64 |
| 65 Thread::ThreadStartFunction function() const { return function_; } | 65 OSThread::ThreadStartFunction function() const { return function_; } |
| 66 uword parameter() const { return parameter_; } | 66 uword parameter() const { return parameter_; } |
| 67 | 67 |
| 68 private: | 68 private: |
| 69 Thread::ThreadStartFunction function_; | 69 OSThread::ThreadStartFunction function_; |
| 70 uword parameter_; | 70 uword parameter_; |
| 71 | 71 |
| 72 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); | 72 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 | 75 |
| 76 // Dispatch to the thread start function provided by the caller. This trampoline | 76 // Dispatch to the thread start function provided by the caller. This trampoline |
| 77 // is used to ensure that the thread is properly destroyed if the thread just | 77 // is used to ensure that the thread is properly destroyed if the thread just |
| 78 // exits. | 78 // exits. |
| 79 static void* ThreadStart(void* data_ptr) { | 79 static void* ThreadStart(void* data_ptr) { |
| 80 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); | 80 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); |
| 81 | 81 |
| 82 Thread::ThreadStartFunction function = data->function(); | 82 OSThread::ThreadStartFunction function = data->function(); |
| 83 uword parameter = data->parameter(); | 83 uword parameter = data->parameter(); |
| 84 delete data; | 84 delete data; |
| 85 | 85 |
| 86 // Call the supplied thread start function handing it its parameters. | 86 // Call the supplied thread start function handing it its parameters. |
| 87 function(parameter); | 87 function(parameter); |
| 88 | 88 |
| 89 return NULL; | 89 return NULL; |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 int Thread::Start(ThreadStartFunction function, uword parameter) { | 93 int OSThread::Start(ThreadStartFunction function, uword parameter) { |
| 94 pthread_attr_t attr; | 94 pthread_attr_t attr; |
| 95 int result = pthread_attr_init(&attr); | 95 int result = pthread_attr_init(&attr); |
| 96 RETURN_ON_PTHREAD_FAILURE(result); | 96 RETURN_ON_PTHREAD_FAILURE(result); |
| 97 | 97 |
| 98 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 98 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| 99 RETURN_ON_PTHREAD_FAILURE(result); | 99 RETURN_ON_PTHREAD_FAILURE(result); |
| 100 | 100 |
| 101 result = pthread_attr_setstacksize(&attr, Thread::GetMaxStackSize()); | 101 result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize()); |
| 102 RETURN_ON_PTHREAD_FAILURE(result); | 102 RETURN_ON_PTHREAD_FAILURE(result); |
| 103 | 103 |
| 104 ThreadStartData* data = new ThreadStartData(function, parameter); | 104 ThreadStartData* data = new ThreadStartData(function, parameter); |
| 105 | 105 |
| 106 pthread_t tid; | 106 pthread_t tid; |
| 107 result = pthread_create(&tid, &attr, ThreadStart, data); | 107 result = pthread_create(&tid, &attr, ThreadStart, data); |
| 108 RETURN_ON_PTHREAD_FAILURE(result); | 108 RETURN_ON_PTHREAD_FAILURE(result); |
| 109 | 109 |
| 110 result = pthread_attr_destroy(&attr); | 110 result = pthread_attr_destroy(&attr); |
| 111 RETURN_ON_PTHREAD_FAILURE(result); | 111 RETURN_ON_PTHREAD_FAILURE(result); |
| 112 | 112 |
| 113 return 0; | 113 return 0; |
| 114 } | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 ThreadLocalKey Thread::kUnsetThreadLocalKey = static_cast<pthread_key_t>(-1); | 117 ThreadLocalKey OSThread::kUnsetThreadLocalKey = |
| 118 ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0); | 118 static_cast<pthread_key_t>(-1); |
| 119 ThreadId OSThread::kInvalidThreadId = static_cast<ThreadId>(0); |
| 119 | 120 |
| 120 ThreadLocalKey Thread::CreateThreadLocal() { | 121 ThreadLocalKey OSThread::CreateThreadLocal() { |
| 121 pthread_key_t key = kUnsetThreadLocalKey; | 122 pthread_key_t key = kUnsetThreadLocalKey; |
| 122 int result = pthread_key_create(&key, NULL); | 123 int result = pthread_key_create(&key, NULL); |
| 123 VALIDATE_PTHREAD_RESULT(result); | 124 VALIDATE_PTHREAD_RESULT(result); |
| 124 ASSERT(key != kUnsetThreadLocalKey); | 125 ASSERT(key != kUnsetThreadLocalKey); |
| 125 return key; | 126 return key; |
| 126 } | 127 } |
| 127 | 128 |
| 128 | 129 |
| 129 void Thread::DeleteThreadLocal(ThreadLocalKey key) { | 130 void OSThread::DeleteThreadLocal(ThreadLocalKey key) { |
| 130 ASSERT(key != kUnsetThreadLocalKey); | 131 ASSERT(key != kUnsetThreadLocalKey); |
| 131 int result = pthread_key_delete(key); | 132 int result = pthread_key_delete(key); |
| 132 VALIDATE_PTHREAD_RESULT(result); | 133 VALIDATE_PTHREAD_RESULT(result); |
| 133 } | 134 } |
| 134 | 135 |
| 135 | 136 |
| 136 void Thread::SetThreadLocal(ThreadLocalKey key, uword value) { | 137 void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) { |
| 137 ASSERT(key != kUnsetThreadLocalKey); | 138 ASSERT(key != kUnsetThreadLocalKey); |
| 138 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); | 139 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); |
| 139 VALIDATE_PTHREAD_RESULT(result); | 140 VALIDATE_PTHREAD_RESULT(result); |
| 140 } | 141 } |
| 141 | 142 |
| 142 | 143 |
| 143 intptr_t Thread::GetMaxStackSize() { | 144 intptr_t OSThread::GetMaxStackSize() { |
| 144 const int kStackSize = (128 * kWordSize * KB); | 145 const int kStackSize = (128 * kWordSize * KB); |
| 145 return kStackSize; | 146 return kStackSize; |
| 146 } | 147 } |
| 147 | 148 |
| 148 | 149 |
| 149 ThreadId Thread::GetCurrentThreadId() { | 150 ThreadId OSThread::GetCurrentThreadId() { |
| 150 return pthread_self(); | 151 return pthread_self(); |
| 151 } | 152 } |
| 152 | 153 |
| 153 | 154 |
| 154 bool Thread::Join(ThreadId id) { | 155 bool OSThread::Join(ThreadId id) { |
| 155 return false; | 156 return false; |
| 156 } | 157 } |
| 157 | 158 |
| 158 | 159 |
| 159 intptr_t Thread::ThreadIdToIntPtr(ThreadId id) { | 160 intptr_t OSThread::ThreadIdToIntPtr(ThreadId id) { |
| 160 ASSERT(sizeof(id) == sizeof(intptr_t)); | 161 ASSERT(sizeof(id) == sizeof(intptr_t)); |
| 161 return static_cast<intptr_t>(id); | 162 return static_cast<intptr_t>(id); |
| 162 } | 163 } |
| 163 | 164 |
| 164 | 165 |
| 165 bool Thread::Compare(ThreadId a, ThreadId b) { | 166 bool OSThread::Compare(ThreadId a, ThreadId b) { |
| 166 return pthread_equal(a, b) != 0; | 167 return pthread_equal(a, b) != 0; |
| 167 } | 168 } |
| 168 | 169 |
| 169 | 170 |
| 170 void Thread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) { | 171 void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) { |
| 171 ASSERT(thread_id == GetCurrentThreadId()); | 172 ASSERT(thread_id == GetCurrentThreadId()); |
| 172 ASSERT(cpu_usage != NULL); | 173 ASSERT(cpu_usage != NULL); |
| 173 struct timespec ts; | 174 struct timespec ts; |
| 174 int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); | 175 int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); |
| 175 ASSERT(r == 0); | 176 ASSERT(r == 0); |
| 176 *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) / | 177 *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) / |
| 177 kNanosecondsPerMicrosecond; | 178 kNanosecondsPerMicrosecond; |
| 178 } | 179 } |
| 179 | 180 |
| 180 | 181 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 | 343 |
| 343 void Monitor::NotifyAll() { | 344 void Monitor::NotifyAll() { |
| 344 // TODO(iposva): Do we need to track lock owners? | 345 // TODO(iposva): Do we need to track lock owners? |
| 345 int result = pthread_cond_broadcast(data_.cond()); | 346 int result = pthread_cond_broadcast(data_.cond()); |
| 346 VALIDATE_PTHREAD_RESULT(result); | 347 VALIDATE_PTHREAD_RESULT(result); |
| 347 } | 348 } |
| 348 | 349 |
| 349 } // namespace dart | 350 } // namespace dart |
| 350 | 351 |
| 351 #endif // defined(TARGET_OS_LINUX) | 352 #endif // defined(TARGET_OS_LINUX) |
| OLD | NEW |