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

Side by Side Diff: src/v8threads.cc

Issue 6816038: Do not rely on uniquiness of pthread_t Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Win32 build fix Created 9 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/v8threads.h ('k') | test/cctest/test-threads.cc » ('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 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 } 140 }
141 141
142 142
143 namespace internal { 143 namespace internal {
144 144
145 145
146 bool ThreadManager::RestoreThread() { 146 bool ThreadManager::RestoreThread() {
147 // First check whether the current thread has been 'lazily archived', ie 147 // First check whether the current thread has been 'lazily archived', ie
148 // not archived at all. If that is the case we put the state storage we 148 // not archived at all. If that is the case we put the state storage we
149 // had prepared back in the free list, since we didn't need it after all. 149 // had prepared back in the free list, since we didn't need it after all.
150 if (lazily_archived_thread_.IsSelf()) { 150 if (lazily_archived_thread_.Equals(ThreadId::Current())) {
151 lazily_archived_thread_.Initialize(ThreadHandle::INVALID); 151 lazily_archived_thread_ = ThreadId::Invalid();
152 ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() == 152 ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() ==
153 lazily_archived_thread_state_); 153 lazily_archived_thread_state_);
154 lazily_archived_thread_state_->set_id(kInvalidId); 154 lazily_archived_thread_state_->set_id(ThreadId::Invalid());
155 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); 155 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST);
156 lazily_archived_thread_state_ = NULL; 156 lazily_archived_thread_state_ = NULL;
157 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); 157 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL);
158 return true; 158 return true;
159 } 159 }
160 160
161 // Make sure that the preemption thread cannot modify the thread state while 161 // Make sure that the preemption thread cannot modify the thread state while
162 // it is being archived or restored. 162 // it is being archived or restored.
163 ExecutionAccess access(isolate_); 163 ExecutionAccess access(isolate_);
164 164
(...skipping 18 matching lines...) Expand all
183 from = isolate_->debug()->RestoreDebug(from); 183 from = isolate_->debug()->RestoreDebug(from);
184 #endif 184 #endif
185 from = isolate_->stack_guard()->RestoreStackGuard(from); 185 from = isolate_->stack_guard()->RestoreStackGuard(from);
186 from = isolate_->regexp_stack()->RestoreStack(from); 186 from = isolate_->regexp_stack()->RestoreStack(from);
187 from = isolate_->bootstrapper()->RestoreState(from); 187 from = isolate_->bootstrapper()->RestoreState(from);
188 per_thread->set_thread_state(NULL); 188 per_thread->set_thread_state(NULL);
189 if (state->terminate_on_restore()) { 189 if (state->terminate_on_restore()) {
190 isolate_->stack_guard()->TerminateExecution(); 190 isolate_->stack_guard()->TerminateExecution();
191 state->set_terminate_on_restore(false); 191 state->set_terminate_on_restore(false);
192 } 192 }
193 state->set_id(kInvalidId); 193 state->set_id(ThreadId::Invalid());
194 state->Unlink(); 194 state->Unlink();
195 state->LinkInto(ThreadState::FREE_LIST); 195 state->LinkInto(ThreadState::FREE_LIST);
196 return true; 196 return true;
197 } 197 }
198 198
199 199
200 void ThreadManager::Lock() { 200 void ThreadManager::Lock() {
201 mutex_->Lock(); 201 mutex_->Lock();
202 mutex_owner_.Initialize(ThreadHandle::SELF); 202 mutex_owner_ = ThreadId::Current();
203 ASSERT(IsLockedByCurrentThread()); 203 ASSERT(IsLockedByCurrentThread());
204 } 204 }
205 205
206 206
207 void ThreadManager::Unlock() { 207 void ThreadManager::Unlock() {
208 mutex_owner_.Initialize(ThreadHandle::INVALID); 208 mutex_owner_ = ThreadId::Invalid();
209 mutex_->Unlock(); 209 mutex_->Unlock();
210 } 210 }
211 211
212 212
213 static int ArchiveSpacePerThread() { 213 static int ArchiveSpacePerThread() {
214 return HandleScopeImplementer::ArchiveSpacePerThread() + 214 return HandleScopeImplementer::ArchiveSpacePerThread() +
215 Isolate::ArchiveSpacePerThread() + 215 Isolate::ArchiveSpacePerThread() +
216 #ifdef ENABLE_DEBUGGER_SUPPORT 216 #ifdef ENABLE_DEBUGGER_SUPPORT
217 Debug::ArchiveSpacePerThread() + 217 Debug::ArchiveSpacePerThread() +
218 #endif 218 #endif
219 StackGuard::ArchiveSpacePerThread() + 219 StackGuard::ArchiveSpacePerThread() +
220 RegExpStack::ArchiveSpacePerThread() + 220 RegExpStack::ArchiveSpacePerThread() +
221 Bootstrapper::ArchiveSpacePerThread() + 221 Bootstrapper::ArchiveSpacePerThread() +
222 Relocatable::ArchiveSpacePerThread(); 222 Relocatable::ArchiveSpacePerThread();
223 } 223 }
224 224
225 225
226 ThreadState::ThreadState(ThreadManager* thread_manager) 226 ThreadState::ThreadState(ThreadManager* thread_manager)
227 : id_(ThreadManager::kInvalidId), 227 : id_(ThreadId::Invalid()),
228 terminate_on_restore_(false), 228 terminate_on_restore_(false),
229 next_(this), 229 next_(this),
230 previous_(this), 230 previous_(this),
231 thread_manager_(thread_manager) { 231 thread_manager_(thread_manager) {
232 } 232 }
233 233
234 234
235 void ThreadState::AllocateSpace() { 235 void ThreadState::AllocateSpace() {
236 data_ = NewArray<char>(ArchiveSpacePerThread()); 236 data_ = NewArray<char>(ArchiveSpacePerThread());
237 } 237 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 if (next_ == thread_manager_->in_use_anchor_) return NULL; 275 if (next_ == thread_manager_->in_use_anchor_) return NULL;
276 return next_; 276 return next_;
277 } 277 }
278 278
279 279
280 // Thread ids must start with 1, because in TLS having thread id 0 can't 280 // Thread ids must start with 1, because in TLS having thread id 0 can't
281 // be distinguished from not having a thread id at all (since NULL is 281 // be distinguished from not having a thread id at all (since NULL is
282 // defined as 0.) 282 // defined as 0.)
283 ThreadManager::ThreadManager() 283 ThreadManager::ThreadManager()
284 : mutex_(OS::CreateMutex()), 284 : mutex_(OS::CreateMutex()),
285 mutex_owner_(ThreadHandle::INVALID), 285 mutex_owner_(ThreadId::Invalid()),
286 lazily_archived_thread_(ThreadHandle::INVALID), 286 lazily_archived_thread_(ThreadId::Invalid()),
287 lazily_archived_thread_state_(NULL), 287 lazily_archived_thread_state_(NULL),
288 free_anchor_(NULL), 288 free_anchor_(NULL),
289 in_use_anchor_(NULL) { 289 in_use_anchor_(NULL) {
290 free_anchor_ = new ThreadState(this); 290 free_anchor_ = new ThreadState(this);
291 in_use_anchor_ = new ThreadState(this); 291 in_use_anchor_ = new ThreadState(this);
292 } 292 }
293 293
294 294
295 ThreadManager::~ThreadManager() { 295 ThreadManager::~ThreadManager() {
296 // TODO(isolates): Destroy mutexes. 296 // TODO(isolates): Destroy mutexes.
297 } 297 }
298 298
299 299
300 void ThreadManager::ArchiveThread() { 300 void ThreadManager::ArchiveThread() {
301 ASSERT(!lazily_archived_thread_.IsValid()); 301 ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid()));
302 ASSERT(!IsArchived()); 302 ASSERT(!IsArchived());
303 ThreadState* state = GetFreeThreadState(); 303 ThreadState* state = GetFreeThreadState();
304 state->Unlink(); 304 state->Unlink();
305 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); 305 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state);
306 lazily_archived_thread_.Initialize(ThreadHandle::SELF); 306 lazily_archived_thread_ = ThreadId::Current();
307 lazily_archived_thread_state_ = state; 307 lazily_archived_thread_state_ = state;
308 ASSERT(state->id() == kInvalidId); 308 ASSERT(state->id().Equals(ThreadId::Invalid()));
309 state->set_id(CurrentId()); 309 state->set_id(CurrentId());
310 ASSERT(state->id() != kInvalidId); 310 ASSERT(!state->id().Equals(ThreadId::Invalid()));
311 } 311 }
312 312
313 313
314 void ThreadManager::EagerlyArchiveThread() { 314 void ThreadManager::EagerlyArchiveThread() {
315 ThreadState* state = lazily_archived_thread_state_; 315 ThreadState* state = lazily_archived_thread_state_;
316 state->LinkInto(ThreadState::IN_USE_LIST); 316 state->LinkInto(ThreadState::IN_USE_LIST);
317 char* to = state->data(); 317 char* to = state->data();
318 // Ensure that data containing GC roots are archived first, and handle them 318 // Ensure that data containing GC roots are archived first, and handle them
319 // in ThreadManager::Iterate(ObjectVisitor*). 319 // in ThreadManager::Iterate(ObjectVisitor*).
320 to = isolate_->handle_scope_implementer()->ArchiveThread(to); 320 to = isolate_->handle_scope_implementer()->ArchiveThread(to);
321 to = isolate_->ArchiveThread(to); 321 to = isolate_->ArchiveThread(to);
322 to = Relocatable::ArchiveState(to); 322 to = Relocatable::ArchiveState(to);
323 #ifdef ENABLE_DEBUGGER_SUPPORT 323 #ifdef ENABLE_DEBUGGER_SUPPORT
324 to = isolate_->debug()->ArchiveDebug(to); 324 to = isolate_->debug()->ArchiveDebug(to);
325 #endif 325 #endif
326 to = isolate_->stack_guard()->ArchiveStackGuard(to); 326 to = isolate_->stack_guard()->ArchiveStackGuard(to);
327 to = isolate_->regexp_stack()->ArchiveStack(to); 327 to = isolate_->regexp_stack()->ArchiveStack(to);
328 to = isolate_->bootstrapper()->ArchiveState(to); 328 to = isolate_->bootstrapper()->ArchiveState(to);
329 lazily_archived_thread_.Initialize(ThreadHandle::INVALID); 329 lazily_archived_thread_ = ThreadId::Invalid();
330 lazily_archived_thread_state_ = NULL; 330 lazily_archived_thread_state_ = NULL;
331 } 331 }
332 332
333 333
334 void ThreadManager::FreeThreadResources() { 334 void ThreadManager::FreeThreadResources() {
335 isolate_->handle_scope_implementer()->FreeThreadResources(); 335 isolate_->handle_scope_implementer()->FreeThreadResources();
336 isolate_->FreeThreadResources(); 336 isolate_->FreeThreadResources();
337 #ifdef ENABLE_DEBUGGER_SUPPORT 337 #ifdef ENABLE_DEBUGGER_SUPPORT
338 isolate_->debug()->FreeThreadResources(); 338 isolate_->debug()->FreeThreadResources();
339 #endif 339 #endif
(...skipping 26 matching lines...) Expand all
366 for (ThreadState* state = FirstThreadStateInUse(); 366 for (ThreadState* state = FirstThreadStateInUse();
367 state != NULL; 367 state != NULL;
368 state = state->Next()) { 368 state = state->Next()) {
369 char* data = state->data(); 369 char* data = state->data();
370 data += HandleScopeImplementer::ArchiveSpacePerThread(); 370 data += HandleScopeImplementer::ArchiveSpacePerThread();
371 isolate_->IterateThread(v, data); 371 isolate_->IterateThread(v, data);
372 } 372 }
373 } 373 }
374 374
375 375
376 int ThreadManager::CurrentId() { 376 ThreadId ThreadManager::CurrentId() {
377 return Thread::GetThreadLocalInt(Isolate::thread_id_key()); 377 return ThreadId::Current();
378 } 378 }
379 379
380 380
381 void ThreadManager::TerminateExecution(int thread_id) { 381 void ThreadManager::TerminateExecution(ThreadId thread_id) {
382 for (ThreadState* state = FirstThreadStateInUse(); 382 for (ThreadState* state = FirstThreadStateInUse();
383 state != NULL; 383 state != NULL;
384 state = state->Next()) { 384 state = state->Next()) {
385 if (thread_id == state->id()) { 385 if (thread_id.Equals(state->id())) {
386 state->set_terminate_on_restore(true); 386 state->set_terminate_on_restore(true);
387 } 387 }
388 } 388 }
389 } 389 }
390 390
391 391
392 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms) 392 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms)
393 : Thread(isolate, "v8:CtxtSwitcher"), 393 : Thread(isolate, "v8:CtxtSwitcher"),
394 keep_going_(true), 394 keep_going_(true),
395 sleep_ms_(every_n_ms) { 395 sleep_ms_(every_n_ms) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 // Acknowledge the preemption by the receiving thread. 444 // Acknowledge the preemption by the receiving thread.
445 void ContextSwitcher::PreemptionReceived() { 445 void ContextSwitcher::PreemptionReceived() {
446 ASSERT(Locker::IsLocked()); 446 ASSERT(Locker::IsLocked());
447 // There is currently no accounting being done for this. But could be in the 447 // There is currently no accounting being done for this. But could be in the
448 // future, which is why we leave this in. 448 // future, which is why we leave this in.
449 } 449 }
450 450
451 451
452 } // namespace internal 452 } // namespace internal
453 } // namespace v8 453 } // namespace v8
OLDNEW
« no previous file with comments | « src/v8threads.h ('k') | test/cctest/test-threads.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698