// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #ifndef VM_THREAD_INTERRUPTER_H_ #define VM_THREAD_INTERRUPTER_H_ #include "vm/allocation.h" #include "vm/signal_handler.h" #include "vm/thread.h" namespace dart { struct InterruptedThreadState { ThreadId tid; uintptr_t pc; uintptr_t sp; uintptr_t fp; }; // When a thread is interrupted the thread specific interrupt // callback will be invoked at the interrupt period. Each callback is given an // InterruptedThreadState and the thread specific data pointer. When inside a // thread interrupt callback doing any of the following // is forbidden: // * Accessing TLS. // * Allocating memory. // * Taking a lock. typedef void (*ThreadInterruptCallback)(const InterruptedThreadState& state, void* data); class ThreadInterrupter : public AllStatic { public: static void InitOnce(); static void Shutdown(); // Delay between interrupts. static void SetInterruptPeriod(intptr_t period); // Register the currently running thread for interrupts. If the current thread // is already registered, callback and data will be updated. static void Register(ThreadInterruptCallback callback, void* data); // Unregister the currently running thread for interrupts. static void Unregister(); // Enable interrupts for this thread. Does not alter callback. static void Enable(); // Disable interrupts for this thread. Does not alter callback. static void Disable(); private: static const intptr_t kMaxThreads = 4096; static bool initialized_; static bool shutdown_; static bool thread_running_; static ThreadId interrupter_thread_id_; static Monitor* monitor_; static intptr_t interrupt_period_; static ThreadLocalKey thread_state_key_; // State stored per registered thread. struct ThreadState { ThreadId id; ThreadInterruptCallback callback; void* data; }; static void UpdateStateObject(ThreadInterruptCallback callback, void* data); static ThreadState* CurrentThreadState(); static void SetCurrentThreadState(ThreadState* state); // Registered thread table. static ThreadState** threads_; static intptr_t threads_capacity_; static intptr_t threads_size_; static void _EnsureThreadStateCreated(); static void _Enable(); static void _Disable(); static void ResizeThreads(intptr_t new_capacity); static void AddThread(ThreadId id); static intptr_t FindThreadIndex(ThreadId id); static ThreadState* RemoveThread(intptr_t i); friend class ThreadInterrupterAndroid; friend class ThreadInterrupterMacOS; friend class ThreadInterrupterLinux; friend class ThreadInterrupterWin; static void InterruptThreads(int64_t current_time); static void ThreadMain(uword parameters); static void InstallSignalHandler(); }; void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data); } // namespace dart #endif // VM_THREAD_INTERRUPTER_H_