Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
timeline_linux.cc
Go to the documentation of this file.
1// Copyright (c) 2017, 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 "vm/globals.h"
6#if defined(DART_HOST_OS_LINUX) && defined(SUPPORT_TIMELINE)
7
8#include <errno.h>
9#include <fcntl.h>
10#include <cstdlib>
11
12#include "platform/atomic.h"
14#include "vm/isolate.h"
15#include "vm/json_stream.h"
16#include "vm/lockers.h"
17#include "vm/log.h"
18#include "vm/object.h"
19#include "vm/service_event.h"
20#include "vm/thread.h"
21#include "vm/timeline.h"
22
23namespace dart {
24
25DECLARE_FLAG(bool, trace_timeline);
26
27static int OpenTraceFD() {
28 const char* kSystraceDebugPath = "/sys/kernel/debug/tracing/trace_marker";
29 const char* kSystracePath = "/sys/kernel/tracing/trace_marker";
30
31 int fd = TEMP_FAILURE_RETRY(::open(kSystracePath, O_WRONLY));
32 if (fd < 0) {
33 fd = TEMP_FAILURE_RETRY(::open(kSystraceDebugPath, O_WRONLY));
34 }
35
36 if (fd < 0 && FLAG_trace_timeline) {
37 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s` or `%s`\n",
38 kSystraceDebugPath, kSystracePath);
39 }
40 return fd;
41}
42
43TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
44 : TimelineEventPlatformRecorder(), systrace_fd_(OpenTraceFD()) {
45 Timeline::set_recorder_discards_clock_values(true);
46}
47
48TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() {
49 if (systrace_fd_ >= 0) {
50 close(systrace_fd_);
51 }
52}
53
54intptr_t TimelineEventSystraceRecorder::PrintSystrace(TimelineEvent* event,
55 char* buffer,
56 intptr_t buffer_size) {
57 ASSERT(buffer != nullptr);
59 buffer[0] = '\0';
60 intptr_t length = 0;
61 int64_t pid = OS::ProcessId();
62 switch (event->event_type()) {
63 case TimelineEvent::kBegin: {
64 length = Utils::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid,
65 event->label());
66 break;
67 }
68 case TimelineEvent::kEnd: {
69 length = Utils::SNPrint(buffer, buffer_size, "E");
70 break;
71 }
72 case TimelineEvent::kCounter: {
73 if (event->arguments_length() > 0) {
74 // We only report the first counter value.
75 length = Utils::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid,
76 event->label(), event->arguments()[0].value);
77 }
78 break;
79 }
80 case TimelineEvent::kAsyncBegin: {
81 length = Utils::SNPrint(buffer, buffer_size, "S|%" Pd64 "|%s|%" Pd64 "",
82 pid, event->label(), event->Id());
83 break;
84 }
85 case TimelineEvent::kAsyncEnd: {
86 length = Utils::SNPrint(buffer, buffer_size, "F|%" Pd64 "|%s|%" Pd64 "",
87 pid, event->label(), event->Id());
88 break;
89 }
90 default:
91 // Ignore event types that we cannot serialize to the Systrace format.
92 break;
93 }
94 return length;
95}
96
97void TimelineEventSystraceRecorder::OnEvent(TimelineEvent* event) {
98 if (event == nullptr) {
99 return;
100 }
101 if (systrace_fd_ < 0) {
102 return;
103 }
104
105 // Serialize to the systrace format.
106 const intptr_t kBufferLength = 1024;
107 char buffer[kBufferLength];
108 const intptr_t event_length = PrintSystrace(event, &buffer[0], kBufferLength);
109 if (event_length > 0) {
110 ssize_t result;
111 // Repeatedly attempt the write while we are being interrupted.
112 do {
113 result = write(systrace_fd_, buffer, event_length);
114 } while ((result == -1L) && (errno == EINTR));
115 }
116}
117
118} // namespace dart
119
120#endif // defined(DART_HOST_OS_LINUX) && !defined(PRODUCT)
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
#define ASSERT(E)
FlKeyEvent * event
static const uint8_t buffer[]
GAsyncResult * result
#define DECLARE_FLAG(type, name)
Definition flags.h:14
size_t length
#define Pd64
Definition globals.h:416
#define TEMP_FAILURE_RETRY(expression)
void write(SkWStream *wStream, const T &text)
Definition skqp.cpp:188