Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
thread_interrupter_macos.cc
Go to the documentation of this file.
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#include "platform/globals.h"
6#if defined(DART_HOST_OS_MACOS)
7
8#include <assert.h> // NOLINT
9#include <errno.h> // NOLINT
10#include <mach/kern_return.h> // NOLINT
11#include <mach/mach.h> // NOLINT
12#include <mach/thread_act.h> // NOLINT
13#include <stdbool.h> // NOLINT
14#include <sys/sysctl.h> // NOLINT
15#include <sys/types.h> // NOLINT
16#include <unistd.h> // NOLINT
17
18#include "vm/flags.h"
19#include "vm/os.h"
20#include "vm/profiler.h"
21#include "vm/signal_handler.h"
23
24namespace dart {
25
26#ifndef PRODUCT
27
28DECLARE_FLAG(bool, trace_thread_interrupter);
29
30#if defined(HOST_ARCH_X64)
31#define THREAD_STATE_FLAVOR x86_THREAD_STATE64
32#define THREAD_STATE_FLAVOR_SIZE x86_THREAD_STATE64_COUNT
33typedef x86_thread_state64_t thread_state_flavor_t;
34#elif defined(HOST_ARCH_ARM64)
35#define THREAD_STATE_FLAVOR ARM_THREAD_STATE64
36#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE64_COUNT
37typedef arm_thread_state64_t thread_state_flavor_t;
38#elif defined(HOST_ARCH_ARM)
39#define THREAD_STATE_FLAVOR ARM_THREAD_STATE32
40#define THREAD_STATE_FLAVOR_SIZE ARM_THREAD_STATE32_COUNT
41typedef arm_thread_state32_t thread_state_flavor_t;
42#else
43#error "Unsupported architecture."
44#endif // HOST_ARCH_...
45
46class ThreadInterrupterMacOS {
47 public:
48 explicit ThreadInterrupterMacOS(OSThread* os_thread) : os_thread_(os_thread) {
49 ASSERT(os_thread != nullptr);
50 mach_thread_ = pthread_mach_thread_np(os_thread->id());
51 ASSERT(reinterpret_cast<void*>(mach_thread_) != nullptr);
52 res = thread_suspend(mach_thread_);
53 }
54
55 void CollectSample() {
56 if (res != KERN_SUCCESS) {
57 return;
58 }
59 auto count = static_cast<mach_msg_type_number_t>(THREAD_STATE_FLAVOR_SIZE);
60 thread_state_flavor_t state;
61 kern_return_t res =
62 thread_get_state(mach_thread_, THREAD_STATE_FLAVOR,
63 reinterpret_cast<thread_state_t>(&state), &count);
64 ASSERT(res == KERN_SUCCESS);
65 Thread* thread = static_cast<Thread*>(os_thread_->thread());
66 if (thread == nullptr) {
67 return;
68 }
69 ThreadInterruptScope signal_handler_scope;
70 Profiler::SampleThread(thread, ProcessState(state));
71 }
72
73 ~ThreadInterrupterMacOS() {
74 if (res != KERN_SUCCESS) {
75 return;
76 }
77 res = thread_resume(mach_thread_);
78 ASSERT(res == KERN_SUCCESS);
79 }
80
81 private:
82 static InterruptedThreadState ProcessState(thread_state_flavor_t state) {
83 InterruptedThreadState its;
84#if defined(HOST_ARCH_X64)
85 its.pc = state.__rip;
86 its.fp = state.__rbp;
87 its.csp = state.__rsp;
88 its.dsp = state.__rsp;
89 its.lr = 0;
90#elif defined(HOST_ARCH_ARM64)
91 its.pc = state.__pc;
92 its.fp = state.__fp;
93 its.csp = state.__sp;
94 its.dsp = state.__sp;
95 its.lr = state.__lr;
96#elif defined(HOST_ARCH_ARM)
97 its.pc = state.__pc;
98 its.fp = state.__r[7];
99 its.csp = state.__sp;
100 its.dsp = state.__sp;
101 its.lr = state.__lr;
102#endif // HOST_ARCH_...
103
104#if defined(TARGET_ARCH_ARM64) && !defined(USING_SIMULATOR)
105 its.dsp = state.__x[SPREG];
106#endif
107 return its;
108 }
109
110 kern_return_t res;
111 OSThread* os_thread_;
112 mach_port_t mach_thread_;
113};
114
115void ThreadInterrupter::InterruptThread(OSThread* os_thread) {
117 if (FLAG_trace_thread_interrupter) {
118 OS::PrintErr("ThreadInterrupter interrupting %p\n", os_thread->id());
119 }
120
121 ThreadInterrupterMacOS interrupter(os_thread);
122 interrupter.CollectSample();
123}
124
125void ThreadInterrupter::InstallSignalHandler() {
126 // Nothing to do on MacOS.
127}
128
129void ThreadInterrupter::RemoveSignalHandler() {
130 // Nothing to do on MacOS.
131}
132
133#endif // !PRODUCT
134
135} // namespace dart
136
137#endif // defined(DART_HOST_OS_MACOS)
int count
static ThreadId GetCurrentThreadId()
static bool Compare(ThreadId a, ThreadId b)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void InterruptThread(OSThread *thread)
#define ASSERT(E)
AtkStateType state
#define DECLARE_FLAG(type, name)
Definition flags.h:14
const Register SPREG