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

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: ThreadRef -> ThreadId 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
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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 v8::internal::ContextSwitcher::StartPreemption(every_n_ms); 134 v8::internal::ContextSwitcher::StartPreemption(every_n_ms);
135 } 135 }
136 136
137 137
138 void Locker::StopPreemption() { 138 void Locker::StopPreemption() {
139 v8::internal::ContextSwitcher::StopPreemption(); 139 v8::internal::ContextSwitcher::StopPreemption();
140 } 140 }
141 141
142 142
143 namespace internal { 143 namespace internal {
144 144
Vitaly Repeshko 2011/04/11 19:28:52 Remove the newly added blank line.
145 145
146
146 bool ThreadManager::RestoreThread() { 147 bool ThreadManager::RestoreThread() {
147 // First check whether the current thread has been 'lazily archived', ie 148 // 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 149 // 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. 150 // had prepared back in the free list, since we didn't need it after all.
150 if (lazily_archived_thread_.IsSelf()) { 151 if (lazily_archived_thread_.Equals(ThreadId::Current())) {
151 lazily_archived_thread_.Initialize(ThreadHandle::INVALID); 152 lazily_archived_thread_ = ThreadId::Invalid();
152 ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() == 153 ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() ==
153 lazily_archived_thread_state_); 154 lazily_archived_thread_state_);
154 lazily_archived_thread_state_->set_id(kInvalidId); 155 lazily_archived_thread_state_->set_id(ThreadId::Invalid());
155 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); 156 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST);
156 lazily_archived_thread_state_ = NULL; 157 lazily_archived_thread_state_ = NULL;
157 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); 158 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL);
158 return true; 159 return true;
159 } 160 }
160 161
161 // Make sure that the preemption thread cannot modify the thread state while 162 // Make sure that the preemption thread cannot modify the thread state while
162 // it is being archived or restored. 163 // it is being archived or restored.
163 ExecutionAccess access(isolate_); 164 ExecutionAccess access(isolate_);
164 165
165 // If there is another thread that was lazily archived then we have to really 166 // If there is another thread that was lazily archived then we have to really
166 // archive it now. 167 // archive it now.
167 if (lazily_archived_thread_.IsValid()) { 168 if (!lazily_archived_thread_.Equals(ThreadId::Invalid())) {
168 EagerlyArchiveThread(); 169 EagerlyArchiveThread();
169 } 170 }
170 Isolate::PerIsolateThreadData* per_thread = 171 Isolate::PerIsolateThreadData* per_thread =
171 Isolate::CurrentPerIsolateThreadData(); 172 Isolate::CurrentPerIsolateThreadData();
172 if (per_thread == NULL || per_thread->thread_state() == NULL) { 173 if (per_thread == NULL || per_thread->thread_state() == NULL) {
173 // This is a new thread. 174 // This is a new thread.
174 isolate_->stack_guard()->InitThread(access); 175 isolate_->stack_guard()->InitThread(access);
175 return false; 176 return false;
176 } 177 }
177 ThreadState* state = per_thread->thread_state(); 178 ThreadState* state = per_thread->thread_state();
178 char* from = state->data(); 179 char* from = state->data();
179 from = isolate_->handle_scope_implementer()->RestoreThread(from); 180 from = isolate_->handle_scope_implementer()->RestoreThread(from);
180 from = isolate_->RestoreThread(from); 181 from = isolate_->RestoreThread(from);
181 from = Relocatable::RestoreState(from); 182 from = Relocatable::RestoreState(from);
182 #ifdef ENABLE_DEBUGGER_SUPPORT 183 #ifdef ENABLE_DEBUGGER_SUPPORT
183 from = isolate_->debug()->RestoreDebug(from); 184 from = isolate_->debug()->RestoreDebug(from);
184 #endif 185 #endif
185 from = isolate_->stack_guard()->RestoreStackGuard(from); 186 from = isolate_->stack_guard()->RestoreStackGuard(from);
186 from = isolate_->regexp_stack()->RestoreStack(from); 187 from = isolate_->regexp_stack()->RestoreStack(from);
187 from = isolate_->bootstrapper()->RestoreState(from); 188 from = isolate_->bootstrapper()->RestoreState(from);
188 per_thread->set_thread_state(NULL); 189 per_thread->set_thread_state(NULL);
189 if (state->terminate_on_restore()) { 190 if (state->terminate_on_restore()) {
190 isolate_->stack_guard()->TerminateExecution(); 191 isolate_->stack_guard()->TerminateExecution();
191 state->set_terminate_on_restore(false); 192 state->set_terminate_on_restore(false);
192 } 193 }
193 state->set_id(kInvalidId); 194 state->set_id(ThreadId::Invalid());
194 state->Unlink(); 195 state->Unlink();
195 state->LinkInto(ThreadState::FREE_LIST); 196 state->LinkInto(ThreadState::FREE_LIST);
196 return true; 197 return true;
197 } 198 }
198 199
199 200
200 void ThreadManager::Lock() { 201 void ThreadManager::Lock() {
201 mutex_->Lock(); 202 mutex_->Lock();
202 mutex_owner_.Initialize(ThreadHandle::SELF); 203 mutex_owner_ = ThreadId::Current();
203 ASSERT(IsLockedByCurrentThread()); 204 ASSERT(IsLockedByCurrentThread());
204 } 205 }
205 206
206 207
207 void ThreadManager::Unlock() { 208 void ThreadManager::Unlock() {
208 mutex_owner_.Initialize(ThreadHandle::INVALID); 209 mutex_owner_ = ThreadId::Invalid();
209 mutex_->Unlock(); 210 mutex_->Unlock();
210 } 211 }
211 212
212 213
213 static int ArchiveSpacePerThread() { 214 static int ArchiveSpacePerThread() {
214 return HandleScopeImplementer::ArchiveSpacePerThread() + 215 return HandleScopeImplementer::ArchiveSpacePerThread() +
215 Isolate::ArchiveSpacePerThread() + 216 Isolate::ArchiveSpacePerThread() +
216 #ifdef ENABLE_DEBUGGER_SUPPORT 217 #ifdef ENABLE_DEBUGGER_SUPPORT
217 Debug::ArchiveSpacePerThread() + 218 Debug::ArchiveSpacePerThread() +
218 #endif 219 #endif
219 StackGuard::ArchiveSpacePerThread() + 220 StackGuard::ArchiveSpacePerThread() +
220 RegExpStack::ArchiveSpacePerThread() + 221 RegExpStack::ArchiveSpacePerThread() +
221 Bootstrapper::ArchiveSpacePerThread() + 222 Bootstrapper::ArchiveSpacePerThread() +
222 Relocatable::ArchiveSpacePerThread(); 223 Relocatable::ArchiveSpacePerThread();
223 } 224 }
224 225
225 226
226 ThreadState::ThreadState(ThreadManager* thread_manager) 227 ThreadState::ThreadState(ThreadManager* thread_manager)
227 : id_(ThreadManager::kInvalidId), 228 : id_(ThreadId::Invalid()),
228 terminate_on_restore_(false), 229 terminate_on_restore_(false),
229 next_(this), 230 next_(this),
230 previous_(this), 231 previous_(this),
231 thread_manager_(thread_manager) { 232 thread_manager_(thread_manager) {
232 } 233 }
233 234
234 235
235 void ThreadState::AllocateSpace() { 236 void ThreadState::AllocateSpace() {
236 data_ = NewArray<char>(ArchiveSpacePerThread()); 237 data_ = NewArray<char>(ArchiveSpacePerThread());
237 } 238 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 if (next_ == thread_manager_->in_use_anchor_) return NULL; 276 if (next_ == thread_manager_->in_use_anchor_) return NULL;
276 return next_; 277 return next_;
277 } 278 }
278 279
279 280
280 // Thread ids must start with 1, because in TLS having thread id 0 can't 281 // 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 282 // be distinguished from not having a thread id at all (since NULL is
282 // defined as 0.) 283 // defined as 0.)
283 ThreadManager::ThreadManager() 284 ThreadManager::ThreadManager()
284 : mutex_(OS::CreateMutex()), 285 : mutex_(OS::CreateMutex()),
285 mutex_owner_(ThreadHandle::INVALID), 286 mutex_owner_(ThreadId::Invalid()),
286 lazily_archived_thread_(ThreadHandle::INVALID), 287 lazily_archived_thread_(ThreadId::Invalid()),
287 lazily_archived_thread_state_(NULL), 288 lazily_archived_thread_state_(NULL),
288 free_anchor_(NULL), 289 free_anchor_(NULL),
289 in_use_anchor_(NULL) { 290 in_use_anchor_(NULL) {
290 free_anchor_ = new ThreadState(this); 291 free_anchor_ = new ThreadState(this);
291 in_use_anchor_ = new ThreadState(this); 292 in_use_anchor_ = new ThreadState(this);
292 } 293 }
293 294
294 295
295 ThreadManager::~ThreadManager() { 296 ThreadManager::~ThreadManager() {
296 // TODO(isolates): Destroy mutexes. 297 // TODO(isolates): Destroy mutexes.
297 } 298 }
298 299
299 300
300 void ThreadManager::ArchiveThread() { 301 void ThreadManager::ArchiveThread() {
301 ASSERT(!lazily_archived_thread_.IsValid()); 302 ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid()));
302 ASSERT(!IsArchived()); 303 ASSERT(!IsArchived());
303 ThreadState* state = GetFreeThreadState(); 304 ThreadState* state = GetFreeThreadState();
304 state->Unlink(); 305 state->Unlink();
305 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); 306 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state);
306 lazily_archived_thread_.Initialize(ThreadHandle::SELF); 307 lazily_archived_thread_ = ThreadId::Current();
307 lazily_archived_thread_state_ = state; 308 lazily_archived_thread_state_ = state;
308 ASSERT(state->id() == kInvalidId); 309 ASSERT(state->id().Equals(ThreadId::Invalid()));
309 state->set_id(CurrentId()); 310 state->set_id(CurrentId());
310 ASSERT(state->id() != kInvalidId); 311 ASSERT(!state->id().Equals(ThreadId::Invalid()));
311 } 312 }
312 313
313 314
314 void ThreadManager::EagerlyArchiveThread() { 315 void ThreadManager::EagerlyArchiveThread() {
315 ThreadState* state = lazily_archived_thread_state_; 316 ThreadState* state = lazily_archived_thread_state_;
316 state->LinkInto(ThreadState::IN_USE_LIST); 317 state->LinkInto(ThreadState::IN_USE_LIST);
317 char* to = state->data(); 318 char* to = state->data();
318 // Ensure that data containing GC roots are archived first, and handle them 319 // Ensure that data containing GC roots are archived first, and handle them
319 // in ThreadManager::Iterate(ObjectVisitor*). 320 // in ThreadManager::Iterate(ObjectVisitor*).
320 to = isolate_->handle_scope_implementer()->ArchiveThread(to); 321 to = isolate_->handle_scope_implementer()->ArchiveThread(to);
321 to = isolate_->ArchiveThread(to); 322 to = isolate_->ArchiveThread(to);
322 to = Relocatable::ArchiveState(to); 323 to = Relocatable::ArchiveState(to);
323 #ifdef ENABLE_DEBUGGER_SUPPORT 324 #ifdef ENABLE_DEBUGGER_SUPPORT
324 to = isolate_->debug()->ArchiveDebug(to); 325 to = isolate_->debug()->ArchiveDebug(to);
325 #endif 326 #endif
326 to = isolate_->stack_guard()->ArchiveStackGuard(to); 327 to = isolate_->stack_guard()->ArchiveStackGuard(to);
327 to = isolate_->regexp_stack()->ArchiveStack(to); 328 to = isolate_->regexp_stack()->ArchiveStack(to);
328 to = isolate_->bootstrapper()->ArchiveState(to); 329 to = isolate_->bootstrapper()->ArchiveState(to);
329 lazily_archived_thread_.Initialize(ThreadHandle::INVALID); 330 lazily_archived_thread_ = ThreadId::Invalid();
330 lazily_archived_thread_state_ = NULL; 331 lazily_archived_thread_state_ = NULL;
331 } 332 }
332 333
333 334
334 void ThreadManager::FreeThreadResources() { 335 void ThreadManager::FreeThreadResources() {
335 isolate_->handle_scope_implementer()->FreeThreadResources(); 336 isolate_->handle_scope_implementer()->FreeThreadResources();
336 isolate_->FreeThreadResources(); 337 isolate_->FreeThreadResources();
337 #ifdef ENABLE_DEBUGGER_SUPPORT 338 #ifdef ENABLE_DEBUGGER_SUPPORT
338 isolate_->debug()->FreeThreadResources(); 339 isolate_->debug()->FreeThreadResources();
339 #endif 340 #endif
(...skipping 26 matching lines...) Expand all
366 for (ThreadState* state = FirstThreadStateInUse(); 367 for (ThreadState* state = FirstThreadStateInUse();
367 state != NULL; 368 state != NULL;
368 state = state->Next()) { 369 state = state->Next()) {
369 char* data = state->data(); 370 char* data = state->data();
370 data += HandleScopeImplementer::ArchiveSpacePerThread(); 371 data += HandleScopeImplementer::ArchiveSpacePerThread();
371 isolate_->IterateThread(v, data); 372 isolate_->IterateThread(v, data);
372 } 373 }
373 } 374 }
374 375
375 376
376 int ThreadManager::CurrentId() { 377 ThreadId ThreadManager::CurrentId() {
377 return Thread::GetThreadLocalInt(Isolate::thread_id_key()); 378 return ThreadId::Current();
378 } 379 }
379 380
380 381
381 void ThreadManager::TerminateExecution(int thread_id) { 382 void ThreadManager::TerminateExecution(ThreadId thread_id) {
382 for (ThreadState* state = FirstThreadStateInUse(); 383 for (ThreadState* state = FirstThreadStateInUse();
383 state != NULL; 384 state != NULL;
384 state = state->Next()) { 385 state = state->Next()) {
385 if (thread_id == state->id()) { 386 if (thread_id.Equals(state->id())) {
386 state->set_terminate_on_restore(true); 387 state->set_terminate_on_restore(true);
387 } 388 }
388 } 389 }
389 } 390 }
390 391
391 392
392 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms) 393 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms)
393 : Thread(isolate, "v8:CtxtSwitcher"), 394 : Thread(isolate, "v8:CtxtSwitcher"),
394 keep_going_(true), 395 keep_going_(true),
395 sleep_ms_(every_n_ms) { 396 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. 445 // Acknowledge the preemption by the receiving thread.
445 void ContextSwitcher::PreemptionReceived() { 446 void ContextSwitcher::PreemptionReceived() {
446 ASSERT(Locker::IsLocked()); 447 ASSERT(Locker::IsLocked());
447 // There is currently no accounting being done for this. But could be in the 448 // There is currently no accounting being done for this. But could be in the
448 // future, which is why we leave this in. 449 // future, which is why we leave this in.
449 } 450 }
450 451
451 452
452 } // namespace internal 453 } // namespace internal
453 } // namespace v8 454 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698