| Index: runtime/vm/thread.cc
|
| diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
|
| index 26357bb4f1d75f0ddc7efba5e06128e544463e02..a19440d0799edf3719542aa4b06416b006997ded 100644
|
| --- a/runtime/vm/thread.cc
|
| +++ b/runtime/vm/thread.cc
|
| @@ -214,7 +214,8 @@ void Thread::EnsureInit() {
|
| Thread::Thread(bool init_vm_constants)
|
| : id_(OSThread::GetCurrentThreadId()),
|
| join_id_(OSThread::GetCurrentThreadJoinId()),
|
| - thread_interrupt_disabled_(1), // Thread interrupts disabled by default.
|
| + thread_interrupt_callback_(NULL),
|
| + thread_interrupt_data_(NULL),
|
| isolate_(NULL),
|
| heap_(NULL),
|
| timeline_block_(NULL),
|
| @@ -330,7 +331,8 @@ void Thread::EnterIsolate(Isolate* isolate) {
|
| ASSERT(isolate->heap() != NULL);
|
| thread->heap_ = isolate->heap();
|
| thread->Schedule(isolate);
|
| - thread->EnableThreadInterrupts();
|
| + // TODO(koda): Migrate profiler interface to use Thread.
|
| + Profiler::BeginExecution(isolate);
|
| }
|
|
|
|
|
| @@ -341,10 +343,10 @@ void Thread::ExitIsolate() {
|
| #if defined(DEBUG)
|
| ASSERT(!thread->IsAnyReusableHandleScopeActive());
|
| #endif // DEBUG
|
| - thread->DisableThreadInterrupts();
|
| // Clear since GC will not visit the thread once it is unscheduled.
|
| thread->ClearReusableHandles();
|
| Isolate* isolate = thread->isolate();
|
| + Profiler::EndExecution(isolate);
|
| thread->Unschedule();
|
| // TODO(koda): Move store_buffer_block_ into State.
|
| thread->StoreBufferRelease();
|
| @@ -371,17 +373,17 @@ void Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) {
|
| thread->isolate()->store_buffer()->PopEmptyBlock();
|
| ASSERT(isolate->heap() != NULL);
|
| thread->heap_ = isolate->heap();
|
| + ASSERT(thread->thread_interrupt_callback_ == NULL);
|
| + ASSERT(thread->thread_interrupt_data_ == NULL);
|
| // Do not update isolate->mutator_thread, but perform sanity check:
|
| // this thread should not be both the main mutator and helper.
|
| ASSERT(!thread->IsMutatorThread());
|
| thread->Schedule(isolate, bypass_safepoint);
|
| - thread->EnableThreadInterrupts();
|
| }
|
|
|
|
|
| void Thread::ExitIsolateAsHelper(bool bypass_safepoint) {
|
| Thread* thread = Thread::Current();
|
| - thread->DisableThreadInterrupts();
|
| Isolate* isolate = thread->isolate();
|
| ASSERT(isolate != NULL);
|
| thread->Unschedule(bypass_safepoint);
|
| @@ -445,18 +447,6 @@ bool Thread::IsMutatorThread() const {
|
| }
|
|
|
|
|
| -bool Thread::IsExecutingDartCode() const {
|
| - return (top_exit_frame_info() == 0) &&
|
| - (vm_tag() == VMTag::kDartTagId);
|
| -}
|
| -
|
| -
|
| -bool Thread::HasExitedDartCode() const {
|
| - return (top_exit_frame_info() != 0) &&
|
| - (vm_tag() != VMTag::kDartTagId);
|
| -}
|
| -
|
| -
|
| CHA* Thread::cha() const {
|
| ASSERT(isolate_ != NULL);
|
| return cha_;
|
| @@ -503,31 +493,29 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor) {
|
| }
|
|
|
|
|
| -void Thread::DisableThreadInterrupts() {
|
| +void Thread::SetThreadInterrupter(ThreadInterruptCallback callback,
|
| + void* data) {
|
| ASSERT(Thread::Current() == this);
|
| - AtomicOperations::FetchAndIncrement(&thread_interrupt_disabled_);
|
| + thread_interrupt_callback_ = callback;
|
| + thread_interrupt_data_ = data;
|
| }
|
|
|
|
|
| -void Thread::EnableThreadInterrupts() {
|
| - ASSERT(Thread::Current() == this);
|
| - uintptr_t old =
|
| - AtomicOperations::FetchAndDecrement(&thread_interrupt_disabled_);
|
| - if (old == 1) {
|
| - // We just decremented from 1 to 0.
|
| - // Make sure the thread interrupter is awake.
|
| - ThreadInterrupter::WakeUp();
|
| - }
|
| - if (old == 0) {
|
| - // We just decremented from 0, this means we've got a mismatched pair
|
| - // of calls to EnableThreadInterrupts and DisableThreadInterrupts.
|
| - FATAL("Invalid call to Thread::EnableThreadInterrupts()");
|
| - }
|
| -}
|
| -
|
| -
|
| -bool Thread::ThreadInterruptsEnabled() {
|
| - return AtomicOperations::LoadRelaxed(&thread_interrupt_disabled_) == 0;
|
| +bool Thread::IsThreadInterrupterEnabled(ThreadInterruptCallback* callback,
|
| + void** data) const {
|
| +#if defined(TARGET_OS_WINDOWS)
|
| + // On Windows we expect this to be called from the thread interrupter thread.
|
| + ASSERT(id() != OSThread::GetCurrentThreadId());
|
| +#else
|
| + // On posix platforms, we expect this to be called from signal handler.
|
| + ASSERT(id() == OSThread::GetCurrentThreadId());
|
| +#endif
|
| + ASSERT(callback != NULL);
|
| + ASSERT(data != NULL);
|
| + *callback = thread_interrupt_callback_;
|
| + *data = thread_interrupt_data_;
|
| + return (*callback != NULL) &&
|
| + (*data != NULL);
|
| }
|
|
|
|
|
| @@ -602,18 +590,4 @@ Thread* ThreadIterator::Next() {
|
| }
|
|
|
|
|
| -DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
|
| - : StackResource(thread) {
|
| - if (thread != NULL) {
|
| - thread->DisableThreadInterrupts();
|
| - }
|
| -}
|
| -
|
| -
|
| -DisableThreadInterruptsScope::~DisableThreadInterruptsScope() {
|
| - if (thread() != NULL) {
|
| - thread()->EnableThreadInterrupts();
|
| - }
|
| -}
|
| -
|
| } // namespace dart
|
|
|