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