OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 #ifndef VM_THREAD_INTERRUPTER_H_ |
| 6 #define VM_THREAD_INTERRUPTER_H_ |
| 7 |
| 8 #include "vm/allocation.h" |
| 9 #include "vm/signal_handler.h" |
| 10 #include "vm/thread.h" |
| 11 |
| 12 |
| 13 namespace dart { |
| 14 |
| 15 struct InterruptedThreadState { |
| 16 ThreadId tid; |
| 17 uintptr_t pc; |
| 18 uintptr_t sp; |
| 19 uintptr_t fp; |
| 20 }; |
| 21 |
| 22 // When a thread is interrupted the thread specific interrupt |
| 23 // callback will be invoked at the interrupt period. Each callback is given an |
| 24 // InterruptedThreadState and the thread specific data pointer. When inside a |
| 25 // thread interrupt callback doing any of the following |
| 26 // is forbidden: |
| 27 // * Accessing TLS. |
| 28 // * Allocating memory. |
| 29 // * Taking a lock. |
| 30 typedef void (*ThreadInterruptCallback)(const InterruptedThreadState& state, |
| 31 void* data); |
| 32 |
| 33 class ThreadInterrupter : public AllStatic { |
| 34 public: |
| 35 static void InitOnce(); |
| 36 static void Shutdown(); |
| 37 |
| 38 // Delay between interrupts. |
| 39 static void SetInterruptPeriod(intptr_t period); |
| 40 |
| 41 // Register the currently running thread for interrupts. If the current thread |
| 42 // is already registered, callback and data will be updated. |
| 43 static void Register(ThreadInterruptCallback callback, void* data); |
| 44 // Unregister the currently running thread for interrupts. |
| 45 static void Unregister(); |
| 46 |
| 47 // Enable interrupts for this thread. Does not alter callback. |
| 48 static void Enable(); |
| 49 // Disable interrupts for this thread. Does not alter callback. |
| 50 static void Disable(); |
| 51 |
| 52 private: |
| 53 static const intptr_t kMaxThreads = 4096; |
| 54 static bool initialized_; |
| 55 static bool shutdown_; |
| 56 static bool thread_running_; |
| 57 static ThreadId interrupter_thread_id_; |
| 58 static Monitor* monitor_; |
| 59 static intptr_t interrupt_period_; |
| 60 static ThreadLocalKey thread_state_key_; |
| 61 // State stored per registered thread. |
| 62 struct ThreadState { |
| 63 ThreadId id; |
| 64 ThreadInterruptCallback callback; |
| 65 void* data; |
| 66 }; |
| 67 |
| 68 static void UpdateStateObject(ThreadInterruptCallback callback, void* data); |
| 69 static ThreadState* CurrentThreadState(); |
| 70 static void SetCurrentThreadState(ThreadState* state); |
| 71 |
| 72 // Registered thread table. |
| 73 static ThreadState** threads_; |
| 74 static intptr_t threads_capacity_; |
| 75 static intptr_t threads_size_; |
| 76 static void _EnsureThreadStateCreated(); |
| 77 static void _Enable(); |
| 78 static void _Disable(); |
| 79 static void ResizeThreads(intptr_t new_capacity); |
| 80 static void AddThread(ThreadId id); |
| 81 static intptr_t FindThreadIndex(ThreadId id); |
| 82 static ThreadState* RemoveThread(intptr_t i); |
| 83 |
| 84 friend class ThreadInterrupterAndroid; |
| 85 friend class ThreadInterrupterMacOS; |
| 86 friend class ThreadInterrupterLinux; |
| 87 friend class ThreadInterrupterWin; |
| 88 |
| 89 static void InterruptThreads(int64_t current_time); |
| 90 static void ThreadMain(uword parameters); |
| 91 |
| 92 static void InstallSignalHandler(); |
| 93 }; |
| 94 |
| 95 void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data); |
| 96 |
| 97 } // namespace dart |
| 98 |
| 99 #endif // VM_THREAD_INTERRUPTER_H_ |
OLD | NEW |