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(HOST_OS_ANDROID) |
7 | |
8 | #include <errno.h> // NOLINT |
9 | #include <sys/syscall.h> // NOLINT |
10 | |
11 | #include "vm/flags.h" |
12 | #include "vm/os.h" |
13 | #include "vm/profiler.h" |
14 | #include "vm/signal_handler.h" |
15 | #include "vm/thread_interrupter.h" |
16 | |
17 | namespace dart { |
18 | |
19 | #ifndef PRODUCT |
20 | |
21 | DECLARE_FLAG(bool, trace_thread_interrupter); |
22 | |
23 | class ThreadInterrupterAndroid : public AllStatic { |
24 | public: |
25 | static void ThreadInterruptSignalHandler(int signal, |
26 | siginfo_t* info, |
27 | void* context_) { |
28 | if (signal != SIGPROF) { |
29 | return; |
30 | } |
31 | Thread* thread = Thread::Current(); |
32 | if (thread == NULL) { |
33 | return; |
34 | } |
35 | ThreadInterrupter::SampleBufferWriterScope scope; |
36 | if (!scope.CanSample()) { |
37 | return; |
38 | } |
39 | // Extract thread state. |
40 | ucontext_t* context = reinterpret_cast<ucontext_t*>(context_); |
41 | mcontext_t mcontext = context->uc_mcontext; |
42 | InterruptedThreadState its; |
43 | its.pc = SignalHandler::GetProgramCounter(mcontext); |
44 | its.fp = SignalHandler::GetFramePointer(mcontext); |
45 | its.csp = SignalHandler::GetCStackPointer(mcontext); |
46 | its.dsp = SignalHandler::GetDartStackPointer(mcontext); |
47 | its.lr = SignalHandler::GetLinkRegister(mcontext); |
48 | Profiler::SampleThread(thread, its); |
49 | } |
50 | }; |
51 | |
52 | bool ThreadInterrupter::IsDebuggerAttached() { |
53 | return false; |
54 | } |
55 | |
56 | void ThreadInterrupter::InterruptThread(OSThread* thread) { |
57 | if (FLAG_trace_thread_interrupter) { |
58 | OS::PrintErr("ThreadInterrupter interrupting %p\n" , |
59 | reinterpret_cast<void*>(thread->id())); |
60 | } |
61 | int result = syscall(__NR_tgkill, getpid(), thread->id(), SIGPROF); |
62 | ASSERT((result == 0) || (result == ESRCH)); |
63 | } |
64 | |
65 | void ThreadInterrupter::InstallSignalHandler() { |
66 | SignalHandler::Install< |
67 | ThreadInterrupterAndroid::ThreadInterruptSignalHandler>(); |
68 | } |
69 | |
70 | void ThreadInterrupter::RemoveSignalHandler() { |
71 | SignalHandler::Remove(); |
72 | } |
73 | |
74 | #endif // !PRODUCT |
75 | |
76 | } // namespace dart |
77 | |
78 | #endif // defined(HOST_OS_ANDROID) |
79 | |