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