Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: runtime/bin/thread_android.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/thread_android.h ('k') | runtime/bin/thread_fuchsia.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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(HOST_OS_ANDROID) 6 #if defined(HOST_OS_ANDROID)
7 7
8 #include "bin/thread.h" 8 #include "bin/thread.h"
9 #include "bin/thread_android.h" 9 #include "bin/thread_android.h"
10 10
11 #include <errno.h> // NOLINT 11 #include <errno.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 "platform/utils.h" 15 #include "platform/utils.h"
16 16
17 namespace dart { 17 namespace dart {
18 namespace bin { 18 namespace bin {
19 19
20 #define VALIDATE_PTHREAD_RESULT(result) \ 20 #define VALIDATE_PTHREAD_RESULT(result) \
21 if (result != 0) { \ 21 if (result != 0) { \
22 const int kBufferSize = 1024; \ 22 const int kBufferSize = 1024; \
23 char error_message[kBufferSize]; \ 23 char error_message[kBufferSize]; \
24 Utils::StrError(result, error_message, kBufferSize); \ 24 Utils::StrError(result, error_message, kBufferSize); \
25 FATAL2("pthread error: %d (%s)", result, error_message); \ 25 FATAL2("pthread error: %d (%s)", result, error_message); \
26 } 26 }
27 27
28
29 #ifdef DEBUG 28 #ifdef DEBUG
30 #define RETURN_ON_PTHREAD_FAILURE(result) \ 29 #define RETURN_ON_PTHREAD_FAILURE(result) \
31 if (result != 0) { \ 30 if (result != 0) { \
32 const int kBufferSize = 1024; \ 31 const int kBufferSize = 1024; \
33 char error_message[kBufferSize]; \ 32 char error_message[kBufferSize]; \
34 Utils::StrError(result, error_message, kBufferSize); \ 33 Utils::StrError(result, error_message, kBufferSize); \
35 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \ 34 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \
36 result, error_message); \ 35 result, error_message); \
37 return result; \ 36 return result; \
38 } 37 }
39 #else 38 #else
40 #define RETURN_ON_PTHREAD_FAILURE(result) \ 39 #define RETURN_ON_PTHREAD_FAILURE(result) \
41 if (result != 0) { \ 40 if (result != 0) { \
42 return result; \ 41 return result; \
43 } 42 }
44 #endif 43 #endif
45 44
46
47 static void ComputeTimeSpecMicros(struct timespec* ts, int64_t micros) { 45 static void ComputeTimeSpecMicros(struct timespec* ts, int64_t micros) {
48 struct timeval tv; 46 struct timeval tv;
49 int64_t secs = micros / kMicrosecondsPerSecond; 47 int64_t secs = micros / kMicrosecondsPerSecond;
50 int64_t remaining_micros = (micros - (secs * kMicrosecondsPerSecond)); 48 int64_t remaining_micros = (micros - (secs * kMicrosecondsPerSecond));
51 int result = gettimeofday(&tv, NULL); 49 int result = gettimeofday(&tv, NULL);
52 ASSERT(result == 0); 50 ASSERT(result == 0);
53 ts->tv_sec = tv.tv_sec + secs; 51 ts->tv_sec = tv.tv_sec + secs;
54 ts->tv_nsec = (tv.tv_usec + remaining_micros) * kNanosecondsPerMicrosecond; 52 ts->tv_nsec = (tv.tv_usec + remaining_micros) * kNanosecondsPerMicrosecond;
55 if (ts->tv_nsec >= kNanosecondsPerSecond) { 53 if (ts->tv_nsec >= kNanosecondsPerSecond) {
56 ts->tv_sec += 1; 54 ts->tv_sec += 1;
57 ts->tv_nsec -= kNanosecondsPerSecond; 55 ts->tv_nsec -= kNanosecondsPerSecond;
58 } 56 }
59 } 57 }
60 58
61
62 class ThreadStartData { 59 class ThreadStartData {
63 public: 60 public:
64 ThreadStartData(Thread::ThreadStartFunction function, uword parameter) 61 ThreadStartData(Thread::ThreadStartFunction function, uword parameter)
65 : function_(function), parameter_(parameter) {} 62 : function_(function), parameter_(parameter) {}
66 63
67 Thread::ThreadStartFunction function() const { return function_; } 64 Thread::ThreadStartFunction function() const { return function_; }
68 uword parameter() const { return parameter_; } 65 uword parameter() const { return parameter_; }
69 66
70 private: 67 private:
71 Thread::ThreadStartFunction function_; 68 Thread::ThreadStartFunction function_;
72 uword parameter_; 69 uword parameter_;
73 70
74 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); 71 DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
75 }; 72 };
76 73
77
78 // Dispatch to the thread start function provided by the caller. This trampoline 74 // Dispatch to the thread start function provided by the caller. This trampoline
79 // is used to ensure that the thread is properly destroyed if the thread just 75 // is used to ensure that the thread is properly destroyed if the thread just
80 // exits. 76 // exits.
81 static void* ThreadStart(void* data_ptr) { 77 static void* ThreadStart(void* data_ptr) {
82 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); 78 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
83 79
84 Thread::ThreadStartFunction function = data->function(); 80 Thread::ThreadStartFunction function = data->function();
85 uword parameter = data->parameter(); 81 uword parameter = data->parameter();
86 delete data; 82 delete data;
87 83
88 // Call the supplied thread start function handing it its parameters. 84 // Call the supplied thread start function handing it its parameters.
89 function(parameter); 85 function(parameter);
90 86
91 return NULL; 87 return NULL;
92 } 88 }
93 89
94
95 int Thread::Start(ThreadStartFunction function, uword parameter) { 90 int Thread::Start(ThreadStartFunction function, uword parameter) {
96 pthread_attr_t attr; 91 pthread_attr_t attr;
97 int result = pthread_attr_init(&attr); 92 int result = pthread_attr_init(&attr);
98 RETURN_ON_PTHREAD_FAILURE(result); 93 RETURN_ON_PTHREAD_FAILURE(result);
99 94
100 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 95 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
101 RETURN_ON_PTHREAD_FAILURE(result); 96 RETURN_ON_PTHREAD_FAILURE(result);
102 97
103 result = pthread_attr_setstacksize(&attr, Thread::GetMaxStackSize()); 98 result = pthread_attr_setstacksize(&attr, Thread::GetMaxStackSize());
104 RETURN_ON_PTHREAD_FAILURE(result); 99 RETURN_ON_PTHREAD_FAILURE(result);
105 100
106 ThreadStartData* data = new ThreadStartData(function, parameter); 101 ThreadStartData* data = new ThreadStartData(function, parameter);
107 102
108 pthread_t tid; 103 pthread_t tid;
109 result = pthread_create(&tid, &attr, ThreadStart, data); 104 result = pthread_create(&tid, &attr, ThreadStart, data);
110 RETURN_ON_PTHREAD_FAILURE(result); 105 RETURN_ON_PTHREAD_FAILURE(result);
111 106
112 result = pthread_attr_destroy(&attr); 107 result = pthread_attr_destroy(&attr);
113 RETURN_ON_PTHREAD_FAILURE(result); 108 RETURN_ON_PTHREAD_FAILURE(result);
114 109
115 return 0; 110 return 0;
116 } 111 }
117 112
118
119 const ThreadLocalKey Thread::kUnsetThreadLocalKey = 113 const ThreadLocalKey Thread::kUnsetThreadLocalKey =
120 static_cast<pthread_key_t>(-1); 114 static_cast<pthread_key_t>(-1);
121 const ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0); 115 const ThreadId Thread::kInvalidThreadId = static_cast<ThreadId>(0);
122 116
123 ThreadLocalKey Thread::CreateThreadLocal() { 117 ThreadLocalKey Thread::CreateThreadLocal() {
124 pthread_key_t key = kUnsetThreadLocalKey; 118 pthread_key_t key = kUnsetThreadLocalKey;
125 int result = pthread_key_create(&key, NULL); 119 int result = pthread_key_create(&key, NULL);
126 VALIDATE_PTHREAD_RESULT(result); 120 VALIDATE_PTHREAD_RESULT(result);
127 ASSERT(key != kUnsetThreadLocalKey); 121 ASSERT(key != kUnsetThreadLocalKey);
128 return key; 122 return key;
129 } 123 }
130 124
131
132 void Thread::DeleteThreadLocal(ThreadLocalKey key) { 125 void Thread::DeleteThreadLocal(ThreadLocalKey key) {
133 ASSERT(key != kUnsetThreadLocalKey); 126 ASSERT(key != kUnsetThreadLocalKey);
134 int result = pthread_key_delete(key); 127 int result = pthread_key_delete(key);
135 VALIDATE_PTHREAD_RESULT(result); 128 VALIDATE_PTHREAD_RESULT(result);
136 } 129 }
137 130
138
139 void Thread::SetThreadLocal(ThreadLocalKey key, uword value) { 131 void Thread::SetThreadLocal(ThreadLocalKey key, uword value) {
140 ASSERT(key != kUnsetThreadLocalKey); 132 ASSERT(key != kUnsetThreadLocalKey);
141 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); 133 int result = pthread_setspecific(key, reinterpret_cast<void*>(value));
142 VALIDATE_PTHREAD_RESULT(result); 134 VALIDATE_PTHREAD_RESULT(result);
143 } 135 }
144 136
145
146 intptr_t Thread::GetMaxStackSize() { 137 intptr_t Thread::GetMaxStackSize() {
147 const int kStackSize = (128 * kWordSize * KB); 138 const int kStackSize = (128 * kWordSize * KB);
148 return kStackSize; 139 return kStackSize;
149 } 140 }
150 141
151
152 ThreadId Thread::GetCurrentThreadId() { 142 ThreadId Thread::GetCurrentThreadId() {
153 return gettid(); 143 return gettid();
154 } 144 }
155 145
156
157 intptr_t Thread::ThreadIdToIntPtr(ThreadId id) { 146 intptr_t Thread::ThreadIdToIntPtr(ThreadId id) {
158 ASSERT(sizeof(id) == sizeof(intptr_t)); 147 ASSERT(sizeof(id) == sizeof(intptr_t));
159 return static_cast<intptr_t>(id); 148 return static_cast<intptr_t>(id);
160 } 149 }
161 150
162
163 bool Thread::Compare(ThreadId a, ThreadId b) { 151 bool Thread::Compare(ThreadId a, ThreadId b) {
164 return (a == b); 152 return (a == b);
165 } 153 }
166 154
167
168 void Thread::InitOnce() { 155 void Thread::InitOnce() {
169 // Nothing to be done. 156 // Nothing to be done.
170 } 157 }
171 158
172
173 Mutex::Mutex() { 159 Mutex::Mutex() {
174 pthread_mutexattr_t attr; 160 pthread_mutexattr_t attr;
175 int result = pthread_mutexattr_init(&attr); 161 int result = pthread_mutexattr_init(&attr);
176 VALIDATE_PTHREAD_RESULT(result); 162 VALIDATE_PTHREAD_RESULT(result);
177 163
178 #if defined(DEBUG) 164 #if defined(DEBUG)
179 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); 165 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
180 VALIDATE_PTHREAD_RESULT(result); 166 VALIDATE_PTHREAD_RESULT(result);
181 #endif // defined(DEBUG) 167 #endif // defined(DEBUG)
182 168
183 result = pthread_mutex_init(data_.mutex(), &attr); 169 result = pthread_mutex_init(data_.mutex(), &attr);
184 // Verify that creating a pthread_mutex succeeded. 170 // Verify that creating a pthread_mutex succeeded.
185 VALIDATE_PTHREAD_RESULT(result); 171 VALIDATE_PTHREAD_RESULT(result);
186 172
187 result = pthread_mutexattr_destroy(&attr); 173 result = pthread_mutexattr_destroy(&attr);
188 VALIDATE_PTHREAD_RESULT(result); 174 VALIDATE_PTHREAD_RESULT(result);
189 } 175 }
190 176
191
192 Mutex::~Mutex() { 177 Mutex::~Mutex() {
193 int result = pthread_mutex_destroy(data_.mutex()); 178 int result = pthread_mutex_destroy(data_.mutex());
194 // Verify that the pthread_mutex was destroyed. 179 // Verify that the pthread_mutex was destroyed.
195 VALIDATE_PTHREAD_RESULT(result); 180 VALIDATE_PTHREAD_RESULT(result);
196 } 181 }
197 182
198
199 void Mutex::Lock() { 183 void Mutex::Lock() {
200 int result = pthread_mutex_lock(data_.mutex()); 184 int result = pthread_mutex_lock(data_.mutex());
201 // Specifically check for dead lock to help debugging. 185 // Specifically check for dead lock to help debugging.
202 ASSERT(result != EDEADLK); 186 ASSERT(result != EDEADLK);
203 ASSERT(result == 0); // Verify no other errors. 187 ASSERT(result == 0); // Verify no other errors.
204 // TODO(iposva): Do we need to track lock owners? 188 // TODO(iposva): Do we need to track lock owners?
205 } 189 }
206 190
207
208 bool Mutex::TryLock() { 191 bool Mutex::TryLock() {
209 int result = pthread_mutex_trylock(data_.mutex()); 192 int result = pthread_mutex_trylock(data_.mutex());
210 // Return false if the lock is busy and locking failed. 193 // Return false if the lock is busy and locking failed.
211 if (result == EBUSY) { 194 if (result == EBUSY) {
212 return false; 195 return false;
213 } 196 }
214 ASSERT(result == 0); // Verify no other errors. 197 ASSERT(result == 0); // Verify no other errors.
215 // TODO(iposva): Do we need to track lock owners? 198 // TODO(iposva): Do we need to track lock owners?
216 return true; 199 return true;
217 } 200 }
218 201
219
220 void Mutex::Unlock() { 202 void Mutex::Unlock() {
221 // TODO(iposva): Do we need to track lock owners? 203 // TODO(iposva): Do we need to track lock owners?
222 int result = pthread_mutex_unlock(data_.mutex()); 204 int result = pthread_mutex_unlock(data_.mutex());
223 // Specifically check for wrong thread unlocking to aid debugging. 205 // Specifically check for wrong thread unlocking to aid debugging.
224 ASSERT(result != EPERM); 206 ASSERT(result != EPERM);
225 ASSERT(result == 0); // Verify no other errors. 207 ASSERT(result == 0); // Verify no other errors.
226 } 208 }
227 209
228
229 Monitor::Monitor() { 210 Monitor::Monitor() {
230 pthread_mutexattr_t mutex_attr; 211 pthread_mutexattr_t mutex_attr;
231 int result = pthread_mutexattr_init(&mutex_attr); 212 int result = pthread_mutexattr_init(&mutex_attr);
232 VALIDATE_PTHREAD_RESULT(result); 213 VALIDATE_PTHREAD_RESULT(result);
233 214
234 #if defined(DEBUG) 215 #if defined(DEBUG)
235 result = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK); 216 result = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
236 VALIDATE_PTHREAD_RESULT(result); 217 VALIDATE_PTHREAD_RESULT(result);
237 #endif // defined(DEBUG) 218 #endif // defined(DEBUG)
238 219
239 result = pthread_mutex_init(data_.mutex(), &mutex_attr); 220 result = pthread_mutex_init(data_.mutex(), &mutex_attr);
240 VALIDATE_PTHREAD_RESULT(result); 221 VALIDATE_PTHREAD_RESULT(result);
241 222
242 result = pthread_mutexattr_destroy(&mutex_attr); 223 result = pthread_mutexattr_destroy(&mutex_attr);
243 VALIDATE_PTHREAD_RESULT(result); 224 VALIDATE_PTHREAD_RESULT(result);
244 225
245 pthread_condattr_t cond_attr; 226 pthread_condattr_t cond_attr;
246 result = pthread_condattr_init(&cond_attr); 227 result = pthread_condattr_init(&cond_attr);
247 VALIDATE_PTHREAD_RESULT(result); 228 VALIDATE_PTHREAD_RESULT(result);
248 229
249 result = pthread_cond_init(data_.cond(), &cond_attr); 230 result = pthread_cond_init(data_.cond(), &cond_attr);
250 VALIDATE_PTHREAD_RESULT(result); 231 VALIDATE_PTHREAD_RESULT(result);
251 232
252 result = pthread_condattr_destroy(&cond_attr); 233 result = pthread_condattr_destroy(&cond_attr);
253 VALIDATE_PTHREAD_RESULT(result); 234 VALIDATE_PTHREAD_RESULT(result);
254 } 235 }
255 236
256
257 Monitor::~Monitor() { 237 Monitor::~Monitor() {
258 int result = pthread_mutex_destroy(data_.mutex()); 238 int result = pthread_mutex_destroy(data_.mutex());
259 VALIDATE_PTHREAD_RESULT(result); 239 VALIDATE_PTHREAD_RESULT(result);
260 240
261 result = pthread_cond_destroy(data_.cond()); 241 result = pthread_cond_destroy(data_.cond());
262 VALIDATE_PTHREAD_RESULT(result); 242 VALIDATE_PTHREAD_RESULT(result);
263 } 243 }
264 244
265
266 void Monitor::Enter() { 245 void Monitor::Enter() {
267 int result = pthread_mutex_lock(data_.mutex()); 246 int result = pthread_mutex_lock(data_.mutex());
268 VALIDATE_PTHREAD_RESULT(result); 247 VALIDATE_PTHREAD_RESULT(result);
269 // TODO(iposva): Do we need to track lock owners? 248 // TODO(iposva): Do we need to track lock owners?
270 } 249 }
271 250
272
273 void Monitor::Exit() { 251 void Monitor::Exit() {
274 // TODO(iposva): Do we need to track lock owners? 252 // TODO(iposva): Do we need to track lock owners?
275 int result = pthread_mutex_unlock(data_.mutex()); 253 int result = pthread_mutex_unlock(data_.mutex());
276 VALIDATE_PTHREAD_RESULT(result); 254 VALIDATE_PTHREAD_RESULT(result);
277 } 255 }
278 256
279
280 Monitor::WaitResult Monitor::Wait(int64_t millis) { 257 Monitor::WaitResult Monitor::Wait(int64_t millis) {
281 return WaitMicros(millis * kMicrosecondsPerMillisecond); 258 return WaitMicros(millis * kMicrosecondsPerMillisecond);
282 } 259 }
283 260
284
285 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { 261 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) {
286 // TODO(iposva): Do we need to track lock owners? 262 // TODO(iposva): Do we need to track lock owners?
287 Monitor::WaitResult retval = kNotified; 263 Monitor::WaitResult retval = kNotified;
288 if (micros == kNoTimeout) { 264 if (micros == kNoTimeout) {
289 // Wait forever. 265 // Wait forever.
290 int result = pthread_cond_wait(data_.cond(), data_.mutex()); 266 int result = pthread_cond_wait(data_.cond(), data_.mutex());
291 VALIDATE_PTHREAD_RESULT(result); 267 VALIDATE_PTHREAD_RESULT(result);
292 } else { 268 } else {
293 struct timespec ts; 269 struct timespec ts;
294 ComputeTimeSpecMicros(&ts, micros); 270 ComputeTimeSpecMicros(&ts, micros);
295 int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts); 271 int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts);
296 ASSERT((result == 0) || (result == ETIMEDOUT)); 272 ASSERT((result == 0) || (result == ETIMEDOUT));
297 if (result == ETIMEDOUT) { 273 if (result == ETIMEDOUT) {
298 retval = kTimedOut; 274 retval = kTimedOut;
299 } 275 }
300 } 276 }
301 return retval; 277 return retval;
302 } 278 }
303 279
304
305 void Monitor::Notify() { 280 void Monitor::Notify() {
306 // TODO(iposva): Do we need to track lock owners? 281 // TODO(iposva): Do we need to track lock owners?
307 int result = pthread_cond_signal(data_.cond()); 282 int result = pthread_cond_signal(data_.cond());
308 VALIDATE_PTHREAD_RESULT(result); 283 VALIDATE_PTHREAD_RESULT(result);
309 } 284 }
310 285
311
312 void Monitor::NotifyAll() { 286 void Monitor::NotifyAll() {
313 // TODO(iposva): Do we need to track lock owners? 287 // TODO(iposva): Do we need to track lock owners?
314 int result = pthread_cond_broadcast(data_.cond()); 288 int result = pthread_cond_broadcast(data_.cond());
315 VALIDATE_PTHREAD_RESULT(result); 289 VALIDATE_PTHREAD_RESULT(result);
316 } 290 }
317 291
318 } // namespace bin 292 } // namespace bin
319 } // namespace dart 293 } // namespace dart
320 294
321 #endif // defined(HOST_OS_ANDROID) 295 #endif // defined(HOST_OS_ANDROID)
OLDNEW
« no previous file with comments | « runtime/bin/thread_android.h ('k') | runtime/bin/thread_fuchsia.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698