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

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

Powered by Google App Engine
This is Rietveld 408576698