Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(662)

Side by Side Diff: runtime/vm/thread_interrupter_fuchsia.cc

Issue 2796143002: [Fuchsia] Implements the thread interrupter for CPU profiling. (Closed)
Patch Set: Small fix Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/os_thread_fuchsia.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(HOST_OS_FUCHSIA) 6 #if defined(HOST_OS_FUCHSIA)
7 7
8 #include "vm/thread_interrupter.h" 8 #include "vm/thread_interrupter.h"
9 9
10 #include "platform/assert.h" 10 #include <magenta/process.h>
11 #include <magenta/status.h>
12 #include <magenta/syscalls.h>
13 #include <magenta/syscalls/debug.h>
14 #include <magenta/types.h>
15
16 #include "vm/flags.h"
17 #include "vm/instructions.h"
18 #include "vm/os.h"
19 #include "vm/profiler.h"
11 20
12 namespace dart { 21 namespace dart {
13 22
23 #ifndef PRODUCT
24
25 DECLARE_FLAG(bool, thread_interrupter);
26 DECLARE_FLAG(bool, trace_thread_interrupter);
27
28 class ThreadInterrupterFuchsia : public AllStatic {
29 public:
30 static bool GrabRegisters(mx_handle_t thread, InterruptedThreadState* state) {
31 // TODO(zra): Enable this when mx_thread_read_state() works on suspended
32 // threads.
33 while (false) {
34 char buf[MX_MAX_THREAD_STATE_SIZE];
35 uint32_t regset_size = MX_MAX_THREAD_STATE_SIZE;
36 mx_status_t status = mx_thread_read_state(
37 thread, MX_THREAD_STATE_REGSET0, &buf[0], regset_size, &regset_size);
38 if (status != NO_ERROR) {
39 OS::Print("ThreadInterrupter failed to get registers: %s\n",
40 mx_status_get_string(status));
siva 2017/05/18 00:11:30 OS::PrintErr here?
zra 2017/05/23 16:09:43 Done.
41 return false;
42 }
43 #if defined(TARGET_ARCH_X64)
44 mx_x86_64_general_regs_t* regs =
45 reinterpret_cast<mx_x86_64_general_regs_t*>(&buf[0]);
46 state->pc = static_cast<uintptr_t>(regs->rip);
47 state->fp = static_cast<uintptr_t>(regs->rbp);
48 state->csp = static_cast<uintptr_t>(regs->rsp);
49 state->dsp = static_cast<uintptr_t>(regs->rsp);
50 #elif defined(TARGET_ARCH_ARM64)
51 mx_aarch64_general_regs_t* regs =
52 reinterpret_cast<mx_aarch64_general_regs_t*>(&buf[0]);
53 state->pc = static_cast<uintptr_t>(regs->pc);
54 state->fp = static_cast<uintptr_t>(regs->r[29]);
siva 2017/05/18 00:11:30 can we use a name here instead of 29
zra 2017/05/23 16:09:43 Done.
55 state->csp = static_cast<uintptr_t>(regs->sp);
56 state->dsp = static_cast<uintptr_t>(regs->r[SPREG]);
57 state->lr = static_cast<uintptr_t>(regs->lr);
58 #else
59 #error "Unsupported architecture"
60 #endif
61 }
62 return true;
63 }
64
65
66 static void Interrupt(OSThread* os_thread) {
67 ASSERT(!OSThread::Compare(OSThread::GetCurrentThreadId(), os_thread->id()));
68 mx_status_t status;
69
70 // Get a handle on the target thread.
71 mx_koid_t target_thread_koid = os_thread->id();
72 if (FLAG_trace_thread_interrupter) {
73 OS::Print("ThreadInterrupter: interrupting thread with koid=%d\n",
74 target_thread_koid);
75 }
76 mx_handle_t target_thread_handle;
77 status = mx_object_get_child(mx_process_self(),
rmacnak 2017/05/18 01:31:27 Why use the koid as the ThreadId and keep creating
zra 2017/05/23 16:09:43 Mostly because it's not entirely clear whether an
78 target_thread_koid,
79 MX_RIGHT_SAME_RIGHTS,
80 &target_thread_handle);
81 if (status != NO_ERROR) {
82 if (FLAG_trace_thread_interrupter) {
83 OS::Print("ThreadInterrupter failed to get the thread handle: %s\n",
84 mx_status_get_string(status));
85 }
86 FATAL1("mx_object_get_child failed: %s", mx_status_get_string(status));
87 }
88 if (target_thread_handle == MX_HANDLE_INVALID) {
89 FATAL("ThreadInterrupter got an invalid target thread handle!");
90 }
91
92 // Pause the target thread.
93 status = mx_task_suspend(target_thread_handle);
94 if (status != NO_ERROR) {
95 if (FLAG_trace_thread_interrupter) {
96 OS::Print("ThreadInterrupter failed to suspend thread %ld: %s\n",
97 static_cast<intptr_t>(os_thread->id()),
98 mx_status_get_string(status));
99 }
100 mx_handle_close(target_thread_handle);
101 FATAL1("mx_task_suspend failed: %s", mx_status_get_string(status));
102 }
103
104 // TODO(zra): Enable this when mx_thread_read_state() works on suspended
105 // threads.
106 while (false) {
107 // Grab the target thread's registers.
108 InterruptedThreadState its;
109 if (!GrabRegisters(target_thread_handle, &its)) {
110 // Failed to get thread registers.
111 status = mx_task_resume(target_thread_handle, 0);
112 if (status != NO_ERROR) {
113 FATAL1("mx_task_resume failed: %s", mx_status_get_string(status));
114 }
115 mx_handle_close(target_thread_handle);
116 return;
117 }
118 // Currently we sample only threads that are associated
119 // with an isolate. It is safe to call 'os_thread->thread()'
120 // here as the thread which is being queried is suspended.
121 Thread* thread = os_thread->thread();
122 if (thread != NULL) {
123 Profiler::SampleThread(thread, its);
124 }
125 }
126
127 // Resume the target thread.
128 status = mx_task_resume(target_thread_handle, 0);
129 if (status != NO_ERROR) {
130 FATAL1("mx_task_resume failed: %s", mx_status_get_string(status));
131 }
132 mx_handle_close(target_thread_handle);
133 }
134 };
135
136
14 bool ThreadInterrupter::IsDebuggerAttached() { 137 bool ThreadInterrupter::IsDebuggerAttached() {
15 return false; 138 return false;
16 } 139 }
17 140
141
18 void ThreadInterrupter::InterruptThread(OSThread* thread) { 142 void ThreadInterrupter::InterruptThread(OSThread* thread) {
19 UNIMPLEMENTED(); 143 if (FLAG_trace_thread_interrupter) {
144 OS::Print("ThreadInterrupter suspending %p\n",
145 reinterpret_cast<void*>(thread->id()));
146 }
147 ThreadInterrupterFuchsia::Interrupt(thread);
148 if (FLAG_trace_thread_interrupter) {
149 OS::Print("ThreadInterrupter resuming %p\n",
150 reinterpret_cast<void*>(thread->id()));
151 }
20 } 152 }
21 153
22 154
23 void ThreadInterrupter::InstallSignalHandler() { 155 void ThreadInterrupter::InstallSignalHandler() {
24 UNIMPLEMENTED(); 156 // Nothing to do on Fuchsia.
25 } 157 }
26 158
27 159
28 void ThreadInterrupter::RemoveSignalHandler() { 160 void ThreadInterrupter::RemoveSignalHandler() {
29 UNIMPLEMENTED(); 161 // Nothing to do on Fuchsia.
30 } 162 }
31 163
164 #endif // !PRODUCT
165
32 } // namespace dart 166 } // namespace dart
33 167
34 #endif // defined(HOST_OS_FUCHSIA) 168 #endif // defined(HOST_OS_FUCHSIA)
OLDNEW
« no previous file with comments | « runtime/vm/os_thread_fuchsia.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698