Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(692)

Unified Diff: runtime/vm/timeline_fuchsia.cc

Issue 2984603002: Special-case Timeline.{start,finish}Sync for Fuchsia (Closed)
Patch Set: Address comments Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/timeline_android.cc ('k') | runtime/vm/timeline_linux.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/timeline_fuchsia.cc
diff --git a/runtime/vm/timeline_fuchsia.cc b/runtime/vm/timeline_fuchsia.cc
new file mode 100644
index 0000000000000000000000000000000000000000..23ce85f79a27ba43b6becd07dfdbce83de239477
--- /dev/null
+++ b/runtime/vm/timeline_fuchsia.cc
@@ -0,0 +1,207 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "platform/globals.h"
+#if defined(HOST_OS_FUCHSIA) && !defined(PRODUCT)
+
+#include "apps/tracing/lib/trace/cwriter.h"
+#include "apps/tracing/lib/trace/event.h"
+#include "vm/object.h"
+#include "vm/timeline.h"
+
+namespace dart {
+
+// A recorder that sends events to Fuchsia's tracing app. Events are also stored
+// in a buffer of fixed capacity. When the buffer is full, new events overwrite
+// old events.
+// See: https://fuchsia.googlesource.com/tracing/+/HEAD/docs/usage_guide.md
+
+TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity)
+ : TimelineEventFixedBufferRecorder(capacity) {}
+
+TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
+
+TimelineEventPlatformRecorder*
+TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) {
+ return new TimelineEventPlatformRecorder(capacity);
+}
+
+const char* TimelineEventPlatformRecorder::name() const {
+ return "Fuchsia";
+}
+
+TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() {
+ // TODO(johnmccutchan): This function should only hand out blocks
+ // which have been marked as finished.
+ if (block_cursor_ == num_blocks_) {
+ block_cursor_ = 0;
+ }
+ TimelineEventBlock* block = blocks_[block_cursor_++];
+ block->Reset();
+ block->Open();
+ return block;
+}
+
+void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
+ if (event == NULL) {
+ return;
+ }
+ if (!ctrace_is_enabled()) {
+ ThreadBlockCompleteEvent(event);
+ return;
+ }
+ auto writer = ctrace_writer_acquire();
+
+ // XXX: use ctrace_register_category_string();
+ ctrace_stringref_t category;
+ ctrace_register_string(writer, "dart", &category);
+
+ ctrace_stringref_t name;
+ ctrace_register_string(writer, event->label(), &name);
+
+ ctrace_threadref_t thread;
+ ctrace_register_current_thread(writer, &thread);
+
+ ctrace_argspec_t args[2];
+ ctrace_arglist_t arglist = {0, args};
+
+ if (event->arguments_length() >= 1) {
+ args[0].type = CTRACE_ARGUMENT_STRING;
+ args[0].name = event->arguments()[0].name;
+ args[0].u.s = event->arguments()[0].value;
+ arglist.n_args += 1;
+ }
+ if (event->arguments_length() >= 2) {
+ args[1].type = CTRACE_ARGUMENT_STRING;
+ args[1].name = event->arguments()[1].name;
+ args[1].u.s = event->arguments()[1].value;
+ arglist.n_args += 1;
+ }
+
+ const uint64_t time_scale = mx_ticks_per_second() / kMicrosecondsPerSecond;
+ const uint64_t start_time = event->LowTime() * time_scale;
+ const uint64_t end_time = event->HighTime() * time_scale;
+
+ // TODO(zra): The functions below emit Dart's timeline events all as category
+ // "dart". Instead, we could have finer-grained categories that make use of
+ // the name of the timeline stream, e.g. "VM", "GC", etc.
+ switch (event->event_type()) {
+ case TimelineEvent::kBegin:
+ ctrace_write_duration_begin_event_record(writer, start_time, &thread,
+ &category, &name, &arglist);
+ break;
+ case TimelineEvent::kEnd:
+ ctrace_write_duration_end_event_record(writer, end_time, &thread,
+ &category, &name, &arglist);
+ break;
+ case TimelineEvent::kInstant:
+ ctrace_write_instant_event_record(writer, start_time, &thread, &category,
+ &name, CTRACE_SCOPE_THREAD, &arglist);
+ break;
+ case TimelineEvent::kAsyncBegin:
+ ctrace_write_async_begin_event_record(writer, start_time, &thread,
+ &category, &name, event->AsyncId(),
+ &arglist);
+ break;
+ case TimelineEvent::kAsyncEnd:
+ ctrace_write_async_end_event_record(writer, end_time, &thread, &category,
+ &name, event->AsyncId(), &arglist);
+ break;
+ case TimelineEvent::kAsyncInstant:
+ ctrace_write_async_instant_event_record(writer, start_time, &thread,
+ &category, &name,
+ event->AsyncId(), &arglist);
+ break;
+ case TimelineEvent::kDuration:
+ ctrace_write_duration_event_record(writer, start_time, end_time, &thread,
+ &category, &name, &arglist);
+ break;
+ case TimelineEvent::kFlowBegin:
+ ctrace_write_flow_begin_event_record(writer, start_time, &thread,
+ &category, &name, event->AsyncId(),
+ &arglist);
+ break;
+ case TimelineEvent::kFlowStep:
+ ctrace_write_flow_step_event_record(writer, start_time, &thread,
+ &category, &name, event->AsyncId(),
+ &arglist);
+ break;
+ case TimelineEvent::kFlowEnd:
+ ctrace_write_flow_end_event_record(writer, start_time, &thread, &category,
+ &name, event->AsyncId(), &arglist);
+ break;
+ default:
+ // TODO(zra): Figure out what to do with kCounter and kMetadata.
+ break;
+ }
+ ctrace_writer_release(writer);
+ ThreadBlockCompleteEvent(event);
+}
+
+void DartTimelineEventHelpers::ReportTaskEvent(Thread* thread,
+ Zone* zone,
+ TimelineEvent* event,
+ int64_t start,
+ int64_t id,
+ const char* phase,
+ const char* category,
+ const char* name,
+ const char* args) {
+ char* name_string = strdup(name);
+ ASSERT(phase != NULL);
+ ASSERT((phase[0] == 'n') || (phase[0] == 'b') || (phase[0] == 'e'));
+ ASSERT(phase[1] == '\0');
+ switch (phase[0]) {
+ case 'n':
+ event->AsyncInstant(name_string, id, start);
+ break;
+ case 'b':
+ event->AsyncBegin(name_string, id, start);
+ break;
+ case 'e':
+ event->AsyncEnd(name_string, id, start);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ event->set_owns_label(true);
+ event->SetNumArguments(1);
+ event->CopyArgument(0, "args", args);
+ event->Complete();
+}
+
+void DartTimelineEventHelpers::ReportCompleteEvent(Thread* thread,
+ Zone* zone,
+ TimelineEvent* event,
+ int64_t start,
+ int64_t start_cpu,
+ const char* category,
+ const char* name,
+ const char* args) {
+ const int64_t end = OS::GetCurrentMonotonicMicros();
+ const int64_t end_cpu = OS::GetCurrentThreadCPUMicros();
+ event->Duration(strdup(name), start, end, start_cpu, end_cpu);
+ event->set_owns_label(true);
+ event->SetNumArguments(1);
+ event->CopyArgument(0, "args", args);
+ event->Complete();
+}
+
+void DartTimelineEventHelpers::ReportInstantEvent(Thread* thread,
+ Zone* zone,
+ TimelineEvent* event,
+ int64_t start,
+ const char* category,
+ const char* name,
+ const char* args) {
+ event->Instant(strdup(name), start);
+ event->set_owns_label(true);
+ event->SetNumArguments(1);
+ event->CopyArgument(0, "args", args);
+ event->Complete();
+}
+
+} // namespace dart
+
+#endif // defined(HOST_OS_FUCHSIA) && !defined(PRODUCT)
« no previous file with comments | « runtime/vm/timeline_android.cc ('k') | runtime/vm/timeline_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698