OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 Unlocker::~Unlocker() { | 126 Unlocker::~Unlocker() { |
127 ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread()); | 127 ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread()); |
128 isolate_->thread_manager()->Lock(); | 128 isolate_->thread_manager()->Lock(); |
129 isolate_->thread_manager()->RestoreThread(); | 129 isolate_->thread_manager()->RestoreThread(); |
130 if (isolate_->IsDefaultIsolate()) { | 130 if (isolate_->IsDefaultIsolate()) { |
131 isolate_->Enter(); | 131 isolate_->Enter(); |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 | 135 |
136 void Locker::StartPreemption(v8::Isolate* isolate, int every_n_ms) { | |
137 v8::internal::ContextSwitcher::StartPreemption( | |
138 reinterpret_cast<i::Isolate*>(isolate), every_n_ms); | |
139 } | |
140 | |
141 | |
142 void Locker::StopPreemption(v8::Isolate* isolate) { | |
143 v8::internal::ContextSwitcher::StopPreemption( | |
144 reinterpret_cast<i::Isolate*>(isolate)); | |
145 } | |
146 | |
147 | |
148 namespace internal { | 136 namespace internal { |
149 | 137 |
150 | 138 |
151 bool ThreadManager::RestoreThread() { | 139 bool ThreadManager::RestoreThread() { |
152 ASSERT(IsLockedByCurrentThread()); | 140 ASSERT(IsLockedByCurrentThread()); |
153 // First check whether the current thread has been 'lazily archived', i.e. | 141 // First check whether the current thread has been 'lazily archived', i.e. |
154 // not archived at all. If that is the case we put the state storage we | 142 // not archived at all. If that is the case we put the state storage we |
155 // had prepared back in the free list, since we didn't need it after all. | 143 // had prepared back in the free list, since we didn't need it after all. |
156 if (lazily_archived_thread_.Equals(ThreadId::Current())) { | 144 if (lazily_archived_thread_.Equals(ThreadId::Current())) { |
157 lazily_archived_thread_ = ThreadId::Invalid(); | 145 lazily_archived_thread_ = ThreadId::Invalid(); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 for (ThreadState* state = FirstThreadStateInUse(); | 400 for (ThreadState* state = FirstThreadStateInUse(); |
413 state != NULL; | 401 state != NULL; |
414 state = state->Next()) { | 402 state = state->Next()) { |
415 if (thread_id.Equals(state->id())) { | 403 if (thread_id.Equals(state->id())) { |
416 state->set_terminate_on_restore(true); | 404 state->set_terminate_on_restore(true); |
417 } | 405 } |
418 } | 406 } |
419 } | 407 } |
420 | 408 |
421 | 409 |
422 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms) | |
423 : Thread("v8:CtxtSwitcher"), | |
424 keep_going_(true), | |
425 sleep_ms_(every_n_ms), | |
426 isolate_(isolate) { | |
427 } | |
428 | |
429 | |
430 // Set the scheduling interval of V8 threads. This function starts the | |
431 // ContextSwitcher thread if needed. | |
432 void ContextSwitcher::StartPreemption(Isolate* isolate, int every_n_ms) { | |
433 ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate))); | |
434 if (isolate->context_switcher() == NULL) { | |
435 // If the ContextSwitcher thread is not running at the moment start it now. | |
436 isolate->set_context_switcher(new ContextSwitcher(isolate, every_n_ms)); | |
437 isolate->context_switcher()->Start(); | |
438 } else { | |
439 // ContextSwitcher thread is already running, so we just change the | |
440 // scheduling interval. | |
441 isolate->context_switcher()->sleep_ms_ = every_n_ms; | |
442 } | |
443 } | |
444 | |
445 | |
446 // Disable preemption of V8 threads. If multiple threads want to use V8 they | |
447 // must cooperatively schedule amongst them from this point on. | |
448 void ContextSwitcher::StopPreemption(Isolate* isolate) { | |
449 ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate))); | |
450 if (isolate->context_switcher() != NULL) { | |
451 // The ContextSwitcher thread is running. We need to stop it and release | |
452 // its resources. | |
453 isolate->context_switcher()->keep_going_ = false; | |
454 // Wait for the ContextSwitcher thread to exit. | |
455 isolate->context_switcher()->Join(); | |
456 // Thread has exited, now we can delete it. | |
457 delete(isolate->context_switcher()); | |
458 isolate->set_context_switcher(NULL); | |
459 } | |
460 } | |
461 | |
462 | |
463 // Main loop of the ContextSwitcher thread: Preempt the currently running V8 | |
464 // thread at regular intervals. | |
465 void ContextSwitcher::Run() { | |
466 while (keep_going_) { | |
467 OS::Sleep(sleep_ms_); | |
468 isolate()->stack_guard()->Preempt(); | |
469 } | |
470 } | |
471 | |
472 | |
473 // Acknowledge the preemption by the receiving thread. | |
474 void ContextSwitcher::PreemptionReceived() { | |
475 // There is currently no accounting being done for this. But could be in the | |
476 // future, which is why we leave this in. | |
477 } | |
478 | |
479 | |
480 } // namespace internal | 410 } // namespace internal |
481 } // namespace v8 | 411 } // namespace v8 |
OLD | NEW |