v8_platform_unittest.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // 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. #include "gin/public/v8_platform.h"
  5. #include <atomic>
  6. #include "base/barrier_closure.h"
  7. #include "base/memory/raw_ptr.h"
  8. #include "base/test/task_environment.h"
  9. #include "base/test/test_waitable_event.h"
  10. #include "base/trace_event/trace_event.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. class TestTraceStateObserver
  13. : public v8::TracingController::TraceStateObserver {
  14. public:
  15. void OnTraceEnabled() final { ++enabled_; }
  16. void OnTraceDisabled() final { ++disabled_; }
  17. int Enabled() { return enabled_; }
  18. int Disabled() { return disabled_; }
  19. private:
  20. int enabled_ = 0;
  21. int disabled_ = 0;
  22. };
  23. namespace gin {
  24. TEST(V8PlatformTest, TraceStateObserverAPI) {
  25. TestTraceStateObserver test_observer;
  26. ASSERT_EQ(0, test_observer.Enabled());
  27. ASSERT_EQ(0, test_observer.Disabled());
  28. V8Platform::Get()->GetTracingController()->AddTraceStateObserver(
  29. &test_observer);
  30. base::trace_event::TraceLog::GetInstance()->SetEnabled(
  31. base::trace_event::TraceConfig("*", ""),
  32. base::trace_event::TraceLog::RECORDING_MODE);
  33. ASSERT_EQ(1, test_observer.Enabled());
  34. ASSERT_EQ(0, test_observer.Disabled());
  35. base::trace_event::TraceLog::GetInstance()->SetDisabled();
  36. ASSERT_EQ(1, test_observer.Enabled());
  37. ASSERT_EQ(1, test_observer.Disabled());
  38. V8Platform::Get()->GetTracingController()->RemoveTraceStateObserver(
  39. &test_observer);
  40. base::trace_event::TraceLog::GetInstance()->SetEnabled(
  41. base::trace_event::TraceConfig("*", ""),
  42. base::trace_event::TraceLog::RECORDING_MODE);
  43. base::trace_event::TraceLog::GetInstance()->SetDisabled();
  44. ASSERT_EQ(1, test_observer.Enabled());
  45. ASSERT_EQ(1, test_observer.Disabled());
  46. }
  47. TEST(V8PlatformTest, TraceStateObserverFired) {
  48. TestTraceStateObserver test_observer;
  49. ASSERT_EQ(0, test_observer.Enabled());
  50. ASSERT_EQ(0, test_observer.Disabled());
  51. base::trace_event::TraceLog::GetInstance()->SetEnabled(
  52. base::trace_event::TraceConfig("*", ""),
  53. base::trace_event::TraceLog::RECORDING_MODE);
  54. V8Platform::Get()->GetTracingController()->AddTraceStateObserver(
  55. &test_observer);
  56. ASSERT_EQ(1, test_observer.Enabled());
  57. ASSERT_EQ(0, test_observer.Disabled());
  58. }
  59. // Tests that PostJob runs a task and is done after Join.
  60. TEST(V8PlatformTest, PostJobSimple) {
  61. base::test::TaskEnvironment task_environment;
  62. std::atomic_size_t num_tasks_to_run(4);
  63. class Task : public v8::JobTask {
  64. public:
  65. explicit Task(std::atomic_size_t* num_tasks_to_run)
  66. : num_tasks_to_run(num_tasks_to_run) {}
  67. void Run(v8::JobDelegate* delegate) override { --(*num_tasks_to_run); }
  68. size_t GetMaxConcurrency(size_t /* worker_count*/) const override {
  69. return *num_tasks_to_run;
  70. }
  71. raw_ptr<std::atomic_size_t> num_tasks_to_run;
  72. };
  73. auto handle =
  74. V8Platform::Get()->PostJob(v8::TaskPriority::kUserVisible,
  75. std::make_unique<Task>(&num_tasks_to_run));
  76. EXPECT_TRUE(handle->IsValid());
  77. handle->Join();
  78. EXPECT_FALSE(handle->IsValid());
  79. DCHECK_EQ(num_tasks_to_run, 0U);
  80. }
  81. // Tests that JobTask's lifetime is extended beyond job handle, until no
  82. // references are left; and is gracefully destroyed.
  83. TEST(V8PlatformTest, PostJobLifetime) {
  84. std::atomic_size_t num_tasks_to_run(4);
  85. base::TestWaitableEvent threads_running;
  86. base::TestWaitableEvent threads_continue;
  87. base::RepeatingClosure threads_running_barrier = base::BarrierClosure(
  88. num_tasks_to_run,
  89. BindOnce(&base::TestWaitableEvent::Signal, Unretained(&threads_running)));
  90. class Task : public v8::JobTask {
  91. public:
  92. explicit Task(std::atomic_size_t* num_tasks_to_run,
  93. base::RepeatingClosure threads_running_barrier,
  94. base::TestWaitableEvent* threads_continue)
  95. : num_tasks_to_run_(num_tasks_to_run),
  96. threads_running_barrier_(std::move(threads_running_barrier)),
  97. threads_continue_(threads_continue) {}
  98. ~Task() override {
  99. // This should only be destroyed once all workers returned.
  100. EXPECT_EQ(*num_tasks_to_run_, 0U);
  101. }
  102. void Run(v8::JobDelegate* delegate) override {
  103. threads_running_barrier_.Run();
  104. threads_continue_->Wait();
  105. --(*num_tasks_to_run_);
  106. }
  107. size_t GetMaxConcurrency(size_t /* worker_count*/) const override {
  108. return *num_tasks_to_run_;
  109. }
  110. raw_ptr<std::atomic_size_t> num_tasks_to_run_;
  111. base::RepeatingClosure threads_running_barrier_;
  112. raw_ptr<base::TestWaitableEvent> threads_continue_;
  113. };
  114. base::test::TaskEnvironment task_environment;
  115. auto handle = V8Platform::Get()->PostJob(
  116. v8::TaskPriority::kUserVisible,
  117. std::make_unique<Task>(&num_tasks_to_run,
  118. std::move(threads_running_barrier),
  119. &threads_continue));
  120. EXPECT_TRUE(handle->IsValid());
  121. threads_running.Wait();
  122. handle->CancelAndDetach();
  123. handle.reset();
  124. // Release workers and let the job get destroyed.
  125. threads_continue.Signal();
  126. }
  127. } // namespace gin