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

Unified Diff: runtime/vm/dart_api_impl_test.cc

Issue 1483113002: Thread and Timeline fixes for Mojo. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Cleanup Created 5 years 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/dart_api_impl.cc ('k') | runtime/vm/os_thread.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/dart_api_impl_test.cc
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index b49491a64432fc25843ad02c5f7363379a73158b..aab541af6fd01fb8fd0d1421a536ce2385604890 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -9260,8 +9260,14 @@ TEST_CASE(Timeline_Dart_GlobalTimelineGetTrace) {
// Grab the global trace.
AppendData data;
- success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
- EXPECT(success);
+ {
+ Thread* T = Thread::Current();
+ StackZone zone(T);
+ success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
+ EXPECT(success);
+ // The call should do no zone allocation.
+ EXPECT(zone.SizeInBytes() == 0);
+ }
buffer = reinterpret_cast<char*>(data.buffer);
buffer_length = data.buffer_length;
EXPECT(buffer_length > 0);
@@ -9301,8 +9307,13 @@ TEST_CASE(Timeline_Dart_GlobalTimelineGetTrace) {
}
// Grab the global trace.
- success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
- EXPECT(success);
+ {
+ Thread* T = Thread::Current();
+ StackZone zone(T);
+ success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
+ EXPECT(success);
+ EXPECT(zone.SizeInBytes() == 0);
+ }
buffer = reinterpret_cast<char*>(data.buffer);
buffer_length = data.buffer_length;
EXPECT(buffer_length > 0);
@@ -9327,4 +9338,165 @@ TEST_CASE(Timeline_Dart_GlobalTimelineGetTrace) {
free(data.buffer);
}
+
+class GlobalTimelineThreadData {
+ public:
+ GlobalTimelineThreadData()
+ : monitor_(new Monitor()),
+ data_(new AppendData()),
+ running_(true),
+ join_id_(OSThread::kInvalidThreadJoinId) {
+ }
+
+ ~GlobalTimelineThreadData() {
+ delete monitor_;
+ monitor_ = NULL;
+ free(data_->buffer);
+ data_->buffer = NULL;
+ data_->buffer_length = 0;
+ delete data_;
+ data_ = NULL;
+ }
+
+ Monitor* monitor() const { return monitor_; }
+ bool running() const { return running_; }
+ AppendData* data() const { return data_; }
+ uint8_t* buffer() const { return data_->buffer; }
+ intptr_t buffer_length() const { return data_->buffer_length; }
+ ThreadJoinId join_id() const { return join_id_; }
+
+ void set_running(bool running) { running_ = running; }
+ void set_join_id(ThreadJoinId join_id) { join_id_ = join_id; }
+
+ private:
+ Monitor* monitor_;
+ AppendData* data_;
+ bool running_;
+ ThreadJoinId join_id_;
+};
+
+
+static void GlobalTimelineThread(uword parameter) {
+ GlobalTimelineThreadData* data =
+ reinterpret_cast<GlobalTimelineThreadData*>(parameter);
+ Thread* T = Thread::Current();
+ // When there is no current Thread, then Zone allocation will fail.
+ EXPECT(T == NULL);
+ {
+ MonitorLocker ml(data->monitor());
+ bool success =
+ Dart_GlobalTimelineGetTrace(AppendStreamConsumer, data->data());
+ EXPECT(success);
+ data->set_running(false);
+ data->set_join_id(OSThread::Current()->join_id());
+ ml.Notify();
+ }
+}
+
+
+// This test is the same as the one above except that the calls to
+// Dart_GlobalTimelineGetTrace are made from a fresh thread. This ensures that
+// we can call the function from a thread for which we have not set up a
+// Thread object.
+TEST_CASE(Timeline_Dart_GlobalTimelineGetTrace_Threaded) {
+ const char* kScriptChars =
+ "bar() => 'z';\n"
+ "foo() => 'a';\n"
+ "main() => foo();\n";
+
+ // Enable all streams.
+ Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL |
+ DART_TIMELINE_STREAM_VM);
+ Dart_Handle lib;
+ {
+ // Add something to the VM stream.
+ TimelineDurationScope tds(Timeline::GetVMStream(),
+ "TestVMDuration");
+ lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ }
+
+ // Invoke main, which will be compiled resulting in a compiler event in
+ // the timeline.
+ Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+ EXPECT_VALID(result);
+
+ const char* buffer = NULL;
+ intptr_t buffer_length = 0;
+
+ // Run Dart_GlobalTimelineGetTrace on a fresh thread.
+ GlobalTimelineThreadData data;
+ int err = OSThread::Start("Timeline test thread",
+ GlobalTimelineThread, reinterpret_cast<uword>(&data));
+ EXPECT(err == 0);
+ {
+ MonitorLocker ml(data.monitor());
+ while (data.running()) {
+ ml.Wait();
+ }
+ buffer = reinterpret_cast<char*>(data.buffer());
+ buffer_length = data.buffer_length();
+ OSThread::Join(data.join_id());
+ }
+ EXPECT(buffer_length > 0);
+ EXPECT(buffer != NULL);
+
+ // Response starts with a '{' character and not a '['.
+ EXPECT(buffer[0] == '{');
+ // Response ends with a '}' character and not a ']'.
+ EXPECT(buffer[buffer_length - 1] == '\0');
+ EXPECT(buffer[buffer_length - 2] == '}');
+
+ // Heartbeat test.
+ EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
+ EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
+ EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
+ EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
+ EXPECT_NOTSUBSTRING("\"function\":\"::_bar\"", buffer);
+
+ // Retrieving the global trace resulted in all open blocks being reclaimed.
+ // Add some new events and verify that both sets of events are present
+ // in the resulting trace.
+ {
+ // Add something to the VM stream.
+ TimelineDurationScope tds(Timeline::GetVMStream(),
+ "TestVMDuration2");
+ // Invoke bar, which will be compiled resulting in a compiler event in
+ // the timeline.
+ result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
+ }
+
+ // Grab the global trace.
+ GlobalTimelineThreadData data2;
+ err = OSThread::Start("Timeline test thread",
+ GlobalTimelineThread, reinterpret_cast<uword>(&data2));
+ EXPECT(err == 0);
+ {
+ MonitorLocker ml(data2.monitor());
+ while (data2.running()) {
+ ml.Wait();
+ }
+ buffer = reinterpret_cast<char*>(data2.buffer());
+ buffer_length = data2.buffer_length();
+ OSThread::Join(data2.join_id());
+ }
+
+ EXPECT(buffer_length > 0);
+ EXPECT(buffer != NULL);
+ // Response starts with a '{' character and not a '['.
+ EXPECT(buffer[0] == '{');
+ // Response ends with a '}' character and not a ']'.
+ EXPECT(buffer[buffer_length - 1] == '\0');
+ EXPECT(buffer[buffer_length - 2] == '}');
+
+ // Heartbeat test for old events.
+ EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
+ EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
+ EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
+ EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
+
+ // Heartbeat test for new events.
+ EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer);
+ EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer);
+}
+
} // namespace dart
« no previous file with comments | « runtime/vm/dart_api_impl.cc ('k') | runtime/vm/os_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698