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
17namespace dart {
18
19#ifndef PRODUCT
20
21DECLARE_FLAG(bool, trace_thread_interrupter);
22
23class 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
52bool ThreadInterrupter::IsDebuggerAttached() {
53 return false;
54}
55
56void 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
65void ThreadInterrupter::InstallSignalHandler() {
66 SignalHandler::Install<
67 ThreadInterrupterAndroid::ThreadInterruptSignalHandler>();
68}
69
70void ThreadInterrupter::RemoveSignalHandler() {
71 SignalHandler::Remove();
72}
73
74#endif // !PRODUCT
75
76} // namespace dart
77
78#endif // defined(HOST_OS_ANDROID)
79