| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 #ifndef VM_THREAD_H_ | 5 #ifndef VM_THREAD_H_ |
| 6 #define VM_THREAD_H_ | 6 #define VM_THREAD_H_ |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #include "vm/handles.h" | 9 #include "vm/handles.h" |
| 10 #include "vm/os_thread.h" | 10 #include "vm/os_thread.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 V(uword, native_call_wrapper_entry_point_, \ | 85 V(uword, native_call_wrapper_entry_point_, \ |
| 86 NativeEntry::NativeCallWrapperEntry(), 0) \ | 86 NativeEntry::NativeCallWrapperEntry(), 0) \ |
| 87 V(RawString**, predefined_symbols_address_, \ | 87 V(RawString**, predefined_symbols_address_, \ |
| 88 Symbols::PredefinedAddress(), NULL) \ | 88 Symbols::PredefinedAddress(), NULL) \ |
| 89 | 89 |
| 90 #define CACHED_CONSTANTS_LIST(V) \ | 90 #define CACHED_CONSTANTS_LIST(V) \ |
| 91 CACHED_VM_OBJECTS_LIST(V) \ | 91 CACHED_VM_OBJECTS_LIST(V) \ |
| 92 CACHED_ADDRESSES_LIST(V) \ | 92 CACHED_ADDRESSES_LIST(V) \ |
| 93 | 93 |
| 94 struct InterruptedThreadState { | 94 struct InterruptedThreadState { |
| 95 ThreadId tid; |
| 95 uintptr_t pc; | 96 uintptr_t pc; |
| 96 uintptr_t csp; | 97 uintptr_t csp; |
| 97 uintptr_t dsp; | 98 uintptr_t dsp; |
| 98 uintptr_t fp; | 99 uintptr_t fp; |
| 99 uintptr_t lr; | 100 uintptr_t lr; |
| 100 }; | 101 }; |
| 101 | 102 |
| 102 // When a thread is interrupted the thread specific interrupt callback will be | 103 // When a thread is interrupted the thread specific interrupt callback will be |
| 103 // invoked. Each callback is given an InterruptedThreadState and the user data | 104 // invoked. Each callback is given an InterruptedThreadState and the user data |
| 104 // pointer. When inside a thread interrupt callback doing any of the following | 105 // pointer. When inside a thread interrupt callback doing any of the following |
| 105 // is forbidden: | 106 // is forbidden: |
| 106 // * Accessing TLS -- Because on Windows the callback will be running in a | 107 // * Accessing TLS -- Because on Windows the callback will be running in a |
| 107 // different thread. | 108 // different thread. |
| 108 // * Allocating memory -- Because this takes locks which may already be held, | 109 // * Allocating memory -- Because this takes locks which may already be held, |
| 109 // resulting in a dead lock. | 110 // resulting in a dead lock. |
| 110 // * Taking a lock -- See above. | 111 // * Taking a lock -- See above. |
| 111 typedef void (*ThreadInterruptCallback)(Thread* thread, | 112 typedef void (*ThreadInterruptCallback)(const InterruptedThreadState& state, |
| 112 const InterruptedThreadState& state); | 113 void* data); |
| 113 | 114 |
| 114 // A VM thread; may be executing Dart code or performing helper tasks like | 115 // A VM thread; may be executing Dart code or performing helper tasks like |
| 115 // garbage collection or compilation. The Thread structure associated with | 116 // garbage collection or compilation. The Thread structure associated with |
| 116 // a thread is allocated by EnsureInit before entering an isolate, and destroyed | 117 // a thread is allocated by EnsureInit before entering an isolate, and destroyed |
| 117 // automatically when the underlying OS thread exits. NOTE: On Windows, CleanUp | 118 // automatically when the underlying OS thread exits. NOTE: On Windows, CleanUp |
| 118 // must currently be called manually (issue 23474). | 119 // must currently be called manually (issue 23474). |
| 119 class Thread { | 120 class Thread { |
| 120 public: | 121 public: |
| 121 // The currently executing thread, or NULL if not yet initialized. | 122 // The currently executing thread, or NULL if not yet initialized. |
| 122 static Thread* Current() { | 123 static Thread* Current() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 // The topmost zone used for allocation in this thread. | 156 // The topmost zone used for allocation in this thread. |
| 156 Zone* zone() const { return state_.zone; } | 157 Zone* zone() const { return state_.zone; } |
| 157 | 158 |
| 158 // The isolate that this thread is operating on, or NULL if none. | 159 // The isolate that this thread is operating on, or NULL if none. |
| 159 Isolate* isolate() const { return isolate_; } | 160 Isolate* isolate() const { return isolate_; } |
| 160 static intptr_t isolate_offset() { | 161 static intptr_t isolate_offset() { |
| 161 return OFFSET_OF(Thread, isolate_); | 162 return OFFSET_OF(Thread, isolate_); |
| 162 } | 163 } |
| 163 bool IsMutatorThread() const; | 164 bool IsMutatorThread() const; |
| 164 | 165 |
| 165 // Is |this| executing Dart code? | |
| 166 bool IsExecutingDartCode() const; | |
| 167 | |
| 168 // Has |this| exited Dart code? | |
| 169 bool HasExitedDartCode() const; | |
| 170 | |
| 171 // The (topmost) CHA for the compilation in this thread. | 166 // The (topmost) CHA for the compilation in this thread. |
| 172 CHA* cha() const; | 167 CHA* cha() const; |
| 173 void set_cha(CHA* value); | 168 void set_cha(CHA* value); |
| 174 | 169 |
| 175 int32_t no_callback_scope_depth() const { | 170 int32_t no_callback_scope_depth() const { |
| 176 return no_callback_scope_depth_; | 171 return no_callback_scope_depth_; |
| 177 } | 172 } |
| 178 | 173 |
| 179 void IncrementNoCallbackScopeDepth() { | 174 void IncrementNoCallbackScopeDepth() { |
| 180 ASSERT(no_callback_scope_depth_ < INT_MAX); | 175 ASSERT(no_callback_scope_depth_ < INT_MAX); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 ThreadId id() const { | 370 ThreadId id() const { |
| 376 ASSERT(id_ != OSThread::kInvalidThreadId); | 371 ASSERT(id_ != OSThread::kInvalidThreadId); |
| 377 return id_; | 372 return id_; |
| 378 } | 373 } |
| 379 | 374 |
| 380 ThreadId join_id() const { | 375 ThreadId join_id() const { |
| 381 ASSERT(join_id_ != OSThread::kInvalidThreadJoinId); | 376 ASSERT(join_id_ != OSThread::kInvalidThreadJoinId); |
| 382 return join_id_; | 377 return join_id_; |
| 383 } | 378 } |
| 384 | 379 |
| 385 // Used to temporarily disable or enable thread interrupts. | 380 void SetThreadInterrupter(ThreadInterruptCallback callback, void* data); |
| 386 void DisableThreadInterrupts(); | 381 |
| 387 void EnableThreadInterrupts(); | 382 bool IsThreadInterrupterEnabled(ThreadInterruptCallback* callback, |
| 388 bool ThreadInterruptsEnabled(); | 383 void** data) const; |
| 389 | 384 |
| 390 #if defined(DEBUG) | 385 #if defined(DEBUG) |
| 391 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object) \ | 386 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object) \ |
| 392 void set_reusable_##object##_handle_scope_active(bool value) { \ | 387 void set_reusable_##object##_handle_scope_active(bool value) { \ |
| 393 reusable_##object##_handle_scope_active_ = value; \ | 388 reusable_##object##_handle_scope_active_ = value; \ |
| 394 } \ | 389 } \ |
| 395 bool reusable_##object##_handle_scope_active() const { \ | 390 bool reusable_##object##_handle_scope_active() const { \ |
| 396 return reusable_##object##_handle_scope_active_; \ | 391 return reusable_##object##_handle_scope_active_; \ |
| 397 } | 392 } |
| 398 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_ACCESSORS) | 393 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_ACCESSORS) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 422 | 417 |
| 423 static bool IsThreadInList(ThreadId join_id); | 418 static bool IsThreadInList(ThreadId join_id); |
| 424 | 419 |
| 425 private: | 420 private: |
| 426 template<class T> T* AllocateReusableHandle(); | 421 template<class T> T* AllocateReusableHandle(); |
| 427 | 422 |
| 428 static ThreadLocalKey thread_key_; | 423 static ThreadLocalKey thread_key_; |
| 429 | 424 |
| 430 const ThreadId id_; | 425 const ThreadId id_; |
| 431 const ThreadId join_id_; | 426 const ThreadId join_id_; |
| 432 uintptr_t thread_interrupt_disabled_; | 427 ThreadInterruptCallback thread_interrupt_callback_; |
| 428 void* thread_interrupt_data_; |
| 433 Isolate* isolate_; | 429 Isolate* isolate_; |
| 434 Heap* heap_; | 430 Heap* heap_; |
| 435 State state_; | 431 State state_; |
| 436 Mutex timeline_block_lock_; | 432 Mutex timeline_block_lock_; |
| 437 TimelineEventBlock* timeline_block_; | 433 TimelineEventBlock* timeline_block_; |
| 438 StoreBufferBlock* store_buffer_block_; | 434 StoreBufferBlock* store_buffer_block_; |
| 439 class Log* log_; | 435 class Log* log_; |
| 440 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \ | 436 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \ |
| 441 type_name member_name; | 437 type_name member_name; |
| 442 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS) | 438 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS) |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 | 535 |
| 540 private: | 536 private: |
| 541 Thread* next_; | 537 Thread* next_; |
| 542 }; | 538 }; |
| 543 | 539 |
| 544 #if defined(TARGET_OS_WINDOWS) | 540 #if defined(TARGET_OS_WINDOWS) |
| 545 // Clears the state of the current thread and frees the allocation. | 541 // Clears the state of the current thread and frees the allocation. |
| 546 void WindowsThreadCleanUp(); | 542 void WindowsThreadCleanUp(); |
| 547 #endif | 543 #endif |
| 548 | 544 |
| 549 | |
| 550 // Disable thread interrupts. | |
| 551 class DisableThreadInterruptsScope : public StackResource { | |
| 552 public: | |
| 553 explicit DisableThreadInterruptsScope(Thread* thread); | |
| 554 ~DisableThreadInterruptsScope(); | |
| 555 }; | |
| 556 | |
| 557 } // namespace dart | 545 } // namespace dart |
| 558 | 546 |
| 559 #endif // VM_THREAD_H_ | 547 #endif // VM_THREAD_H_ |
| OLD | NEW |