blob: 332e0f7995cf3ca60bb37a64068b4d51ed7ac96e [file] [log] [blame]
lpy48e4c322017-01-27 18:22:341// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gin/public/v8_platform.h"
6
Etienne Pierre-doray9caa721e2020-05-19 15:22:227#include <atomic>
8
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:189#include "base/barrier_closure.h"
Etienne Pierre-doray9caa721e2020-05-19 15:22:2210#include "base/test/task_environment.h"
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:1811#include "base/test/test_waitable_event.h"
lpy48e4c322017-01-27 18:22:3412#include "base/trace_event/trace_event.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15class TestTraceStateObserver
Nico Weber43ddd7a32017-08-15 19:19:2716 : public v8::TracingController::TraceStateObserver {
lpy48e4c322017-01-27 18:22:3417 public:
18 void OnTraceEnabled() final { ++enabled_; }
19 void OnTraceDisabled() final { ++disabled_; }
20 int Enabled() { return enabled_; }
21 int Disabled() { return disabled_; }
22
23 private:
24 int enabled_ = 0;
25 int disabled_ = 0;
26};
27
28namespace gin {
29
30TEST(V8PlatformTest, TraceStateObserverAPI) {
Jeremy Roman367b0602018-06-12 14:33:0231 TestTraceStateObserver test_observer;
32 ASSERT_EQ(0, test_observer.Enabled());
33 ASSERT_EQ(0, test_observer.Disabled());
lpy48e4c322017-01-27 18:22:3434
Jochen Eisingerb896fd82017-07-07 09:00:5135 V8Platform::Get()->GetTracingController()->AddTraceStateObserver(
Jeremy Roman367b0602018-06-12 14:33:0236 &test_observer);
lpy48e4c322017-01-27 18:22:3437 base::trace_event::TraceLog::GetInstance()->SetEnabled(
38 base::trace_event::TraceConfig("*", ""),
39 base::trace_event::TraceLog::RECORDING_MODE);
Jeremy Roman367b0602018-06-12 14:33:0240 ASSERT_EQ(1, test_observer.Enabled());
41 ASSERT_EQ(0, test_observer.Disabled());
lpy48e4c322017-01-27 18:22:3442 base::trace_event::TraceLog::GetInstance()->SetDisabled();
Jeremy Roman367b0602018-06-12 14:33:0243 ASSERT_EQ(1, test_observer.Enabled());
44 ASSERT_EQ(1, test_observer.Disabled());
lpy48e4c322017-01-27 18:22:3445
Jochen Eisingerb896fd82017-07-07 09:00:5146 V8Platform::Get()->GetTracingController()->RemoveTraceStateObserver(
Jeremy Roman367b0602018-06-12 14:33:0247 &test_observer);
lpy48e4c322017-01-27 18:22:3448 base::trace_event::TraceLog::GetInstance()->SetEnabled(
49 base::trace_event::TraceConfig("*", ""),
50 base::trace_event::TraceLog::RECORDING_MODE);
51 base::trace_event::TraceLog::GetInstance()->SetDisabled();
Jeremy Roman367b0602018-06-12 14:33:0252 ASSERT_EQ(1, test_observer.Enabled());
53 ASSERT_EQ(1, test_observer.Disabled());
lpy48e4c322017-01-27 18:22:3454}
55
56TEST(V8PlatformTest, TraceStateObserverFired) {
Jeremy Roman367b0602018-06-12 14:33:0257 TestTraceStateObserver test_observer;
58 ASSERT_EQ(0, test_observer.Enabled());
59 ASSERT_EQ(0, test_observer.Disabled());
lpy48e4c322017-01-27 18:22:3460
61 base::trace_event::TraceLog::GetInstance()->SetEnabled(
62 base::trace_event::TraceConfig("*", ""),
63 base::trace_event::TraceLog::RECORDING_MODE);
Jochen Eisingerb896fd82017-07-07 09:00:5164 V8Platform::Get()->GetTracingController()->AddTraceStateObserver(
Jeremy Roman367b0602018-06-12 14:33:0265 &test_observer);
66 ASSERT_EQ(1, test_observer.Enabled());
67 ASSERT_EQ(0, test_observer.Disabled());
lpy48e4c322017-01-27 18:22:3468}
69
Etienne Pierre-doray9caa721e2020-05-19 15:22:2270// Tests that PostJob runs a task and is done after Join.
71TEST(V8PlatformTest, PostJobSimple) {
72 base::test::TaskEnvironment task_environment;
73 std::atomic_size_t num_tasks_to_run(4);
74 class Task : public v8::JobTask {
75 public:
76 explicit Task(std::atomic_size_t* num_tasks_to_run)
77 : num_tasks_to_run(num_tasks_to_run) {}
78 void Run(v8::JobDelegate* delegate) override { --(*num_tasks_to_run); }
Etienne Pierre-doray5bbb5dd2020-08-26 15:14:3079
Etienne Pierre-doray5bbb5dd2020-08-26 15:14:3080 size_t GetMaxConcurrency(size_t /* worker_count*/) const override {
Etienne Pierre-dorayf5a73122020-09-14 14:17:4681 return *num_tasks_to_run;
Etienne Pierre-doray5bbb5dd2020-08-26 15:14:3082 }
Etienne Pierre-doray9caa721e2020-05-19 15:22:2283
84 std::atomic_size_t* num_tasks_to_run;
85 };
86 auto handle =
87 V8Platform::Get()->PostJob(v8::TaskPriority::kUserVisible,
88 std::make_unique<Task>(&num_tasks_to_run));
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:1889 EXPECT_TRUE(handle->IsValid());
Etienne Pierre-doray9caa721e2020-05-19 15:22:2290 handle->Join();
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:1891 EXPECT_FALSE(handle->IsValid());
Etienne Pierre-doray9caa721e2020-05-19 15:22:2292 DCHECK_EQ(num_tasks_to_run, 0U);
93}
94
Etienne Pierre-doray2e0c74cf2020-12-03 15:17:1895// Tests that JobTask's lifetime is extended beyond job handle, until no
96// references are left; and is gracefully destroyed.
97TEST(V8PlatformTest, PostJobLifetime) {
98 std::atomic_size_t num_tasks_to_run(4);
99
100 base::TestWaitableEvent threads_running;
101 base::TestWaitableEvent threads_continue;
102 base::RepeatingClosure threads_running_barrier = base::BarrierClosure(
103 num_tasks_to_run,
104 BindOnce(&base::TestWaitableEvent::Signal, Unretained(&threads_running)));
105
106 class Task : public v8::JobTask {
107 public:
108 explicit Task(std::atomic_size_t* num_tasks_to_run,
109 base::RepeatingClosure threads_running_barrier,
110 base::TestWaitableEvent* threads_continue)
111 : num_tasks_to_run_(num_tasks_to_run),
112 threads_running_barrier_(std::move(threads_running_barrier)),
113 threads_continue_(threads_continue) {}
114 ~Task() override {
115 // This should only be destroyed once all workers returned.
116 EXPECT_EQ(*num_tasks_to_run_, 0U);
117 }
118
119 void Run(v8::JobDelegate* delegate) override {
120 threads_running_barrier_.Run();
121 threads_continue_->Wait();
122 --(*num_tasks_to_run_);
123 }
124
125 size_t GetMaxConcurrency(size_t /* worker_count*/) const override {
126 return *num_tasks_to_run_;
127 }
128
129 std::atomic_size_t* num_tasks_to_run_;
130 base::RepeatingClosure threads_running_barrier_;
131 base::TestWaitableEvent* threads_continue_;
132 };
133
134 base::test::TaskEnvironment task_environment;
135
136 auto handle = V8Platform::Get()->PostJob(
137 v8::TaskPriority::kUserVisible,
138 std::make_unique<Task>(&num_tasks_to_run,
139 std::move(threads_running_barrier),
140 &threads_continue));
141 EXPECT_TRUE(handle->IsValid());
142 threads_running.Wait();
143 handle->CancelAndDetach();
144 handle.reset();
145
146 // Release workers and let the job get destroyed.
147 threads_continue.Signal();
148}
149
lpy48e4c322017-01-27 18:22:34150} // namespace gin