OLD | NEW |
---|---|
(Empty) | |
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 "platform/globals.h" | |
6 #if defined(HOST_OS_ANDROID) && !defined(PRODUCT) | |
7 | |
8 #include <errno.h> | |
9 #include <fcntl.h> | |
10 #include <cstdlib> | |
11 | |
12 #include "vm/atomic.h" | |
13 #include "vm/isolate.h" | |
14 #include "vm/json_stream.h" | |
15 #include "vm/lockers.h" | |
16 #include "vm/log.h" | |
17 #include "vm/object.h" | |
18 #include "vm/service_event.h" | |
19 #include "vm/thread.h" | |
20 #include "vm/timeline.h" | |
21 | |
22 namespace dart { | |
23 | |
24 DECLARE_FLAG(bool, trace_timeline); | |
25 | |
26 TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity) | |
27 : TimelineEventPlatformRecorder(capacity), systrace_fd_(-1) { | |
28 const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker"; | |
29 systrace_fd_ = open(kSystracePath, O_WRONLY); | |
30 if ((systrace_fd_ < 0) && FLAG_trace_timeline) { | |
31 OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n", | |
32 kSystracePath); | |
33 } | |
34 } | |
35 | |
36 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() { | |
37 if (systrace_fd_ >= 0) { | |
38 close(systrace_fd_); | |
39 } | |
40 } | |
41 | |
42 intptr_t TimelineEventSystraceRecorder::PrintSystrace(TimelineEvent* event, | |
43 char* buffer, | |
44 intptr_t buffer_size) { | |
45 ASSERT(buffer != NULL); | |
46 ASSERT(buffer_size > 0); | |
47 buffer[0] = '\0'; | |
48 intptr_t length = 0; | |
49 int64_t pid = OS::ProcessId(); | |
50 switch (event->event_type()) { | |
51 case TimelineEvent::kBegin: { | |
52 length = OS::SNPrint(buffer, buffer_size, "B|%" Pd64 "|%s", pid, | |
53 event->label()); | |
54 } break; | |
55 case TimelineEvent::kEnd: { | |
56 length = OS::SNPrint(buffer, buffer_size, "E"); | |
57 } break; | |
58 case TimelineEvent::kCounter: { | |
59 if (event->arguments_length() > 0) { | |
60 // We only report the first counter value. | |
61 length = OS::SNPrint(buffer, buffer_size, "C|%" Pd64 "|%s|%s", pid, | |
62 event->label(), event->arguments()[0].value); | |
63 } | |
64 } | |
65 default: | |
66 // Ignore event types that we cannot serialize to the Systrace format. | |
67 break; | |
68 } | |
69 return length; | |
70 } | |
71 | |
72 void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) { | |
73 if (event == NULL) { | |
74 return; | |
75 } | |
76 if (systrace_fd_ >= 0) { | |
77 // Serialize to the systrace format. | |
78 const intptr_t kBufferLength = 1024; | |
79 char buffer[kBufferLength]; | |
80 const intptr_t event_length = | |
81 PrintSystrace(event, &buffer[0], kBufferLength); | |
82 if (event_length > 0) { | |
83 ssize_t result; | |
84 // Repeatedly attempt the write while we are being interrupted. | |
85 do { | |
86 result = write(systrace_fd_, buffer, event_length); | |
87 } while ((result == -1L) && (errno == EINTR)); | |
88 } | |
89 } | |
90 ThreadBlockCompleteEvent(event); | |
91 } | |
92 | |
93 TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity) | |
94 : TimelineEventFixedBufferRecorder(capacity) {} | |
95 | |
96 TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {} | |
97 | |
98 TimelineEventPlatformRecorder* | |
99 TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) { | |
100 return new TimelineEventSystraceRecorder(capacity); | |
101 } | |
102 | |
103 const char* TimelineEventPlatformRecorder::name() const { | |
104 return "Systrace"; | |
105 } | |
106 | |
107 TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() { | |
108 // TODO(johnmccutchan): This function should only hand out blocks | |
109 // which have been marked as finished. | |
110 if (block_cursor_ == num_blocks_) { | |
111 block_cursor_ = 0; | |
112 } | |
113 TimelineEventBlock* block = blocks_[block_cursor_++]; | |
114 block->Reset(); | |
115 block->Open(); | |
116 return block; | |
117 } | |
118 | |
119 void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) { | |
120 UNREACHABLE(); | |
121 } | |
122 | |
123 void DartTimelineEventHelpers::ReportTaskEvent(Thread* thread, | |
124 Zone* zone, | |
125 TimelineEvent* event, | |
126 int64_t start, | |
127 int64_t id, | |
128 const char* phase, | |
129 const char* category, | |
130 const char* name, | |
131 const char* args) { | |
132 DartCommonTimelineEventHelpers::ReportTaskEvent( | |
133 thread, zone, event, start, id, phase, category, name, args); | |
134 } | |
135 | |
136 void DartTimelineEventHelpers::ReportCompleteEvent(Thread* thread, | |
137 Zone* zone, | |
138 TimelineEvent* event, | |
139 int64_t start, | |
140 int64_t start_cpu, | |
141 const char* category, | |
142 const char* name, | |
143 const char* args) { | |
144 DartCommonTimelineEventHelpers::ReportCompleteEvent( | |
145 thread, zone, event, start, start_cpu, category, name, args); | |
146 } | |
147 | |
148 void DartTimelineEventHelpers::ReportInstantEvent(Thread* thread, | |
149 Zone* zone, | |
150 TimelineEvent* event, | |
151 int64_t start, | |
152 const char* category, | |
153 const char* name, | |
154 const char* args) { | |
155 DartCommonTimelineEventHelpers::ReportInstantEvent(thread, zone, event, start, | |
156 category, name, args); | |
157 } | |
158 | |
159 } // namespace dart | |
160 | |
161 #endif // !PRODUCT | |
siva
2017/07/21 00:29:52
// defined(HOST_OS_ANDROID) && !defined(PRODUCT)
zra
2017/07/21 15:06:18
Done.
| |
OLD | NEW |