Commit fcf1bac9 authored by alph's avatar alph Committed by Commit bot

[tracing] Implement Add/RemoveTraceStateObserver for default platform.

BUG=chromium:406277

Review-Url: https://codereview.chromium.org/2369073003
Cr-Commit-Position: refs/heads/master@{#39794}
parent ff135975
......@@ -7,11 +7,17 @@
#include <fstream>
#include <memory>
#include <unordered_set>
#include <vector>
#include "include/v8-platform.h"
namespace v8 {
namespace base {
class Mutex;
} // namespace base
namespace platform {
namespace tracing {
......@@ -227,7 +233,8 @@ class TracingController {
ENABLED_FOR_ETW_EXPORT = 1 << 3
};
TracingController() {}
TracingController();
~TracingController();
void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
......@@ -244,6 +251,9 @@ class TracingController {
void StartTracing(TraceConfig* trace_config);
void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index);
......@@ -251,6 +261,8 @@ class TracingController {
std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
Mode mode_ = DISABLED;
// Disallow copy and assign
......
......@@ -39,9 +39,14 @@ void SetTracingController(
const int DefaultPlatform::kMaxThreadPoolSize = 8;
DefaultPlatform::DefaultPlatform()
: initialized_(false), thread_pool_size_(0), tracing_controller_(NULL) {}
: initialized_(false), thread_pool_size_(0) {}
DefaultPlatform::~DefaultPlatform() {
if (tracing_controller_) {
tracing_controller_->StopTracing();
tracing_controller_.reset();
}
base::LockGuard<base::Mutex> guard(&lock_);
queue_.Terminate();
if (initialized_) {
......@@ -63,11 +68,6 @@ DefaultPlatform::~DefaultPlatform() {
i->second.pop();
}
}
if (tracing_controller_) {
tracing_controller_->StopTracing();
delete tracing_controller_;
}
}
......@@ -219,12 +219,22 @@ const char* DefaultPlatform::GetCategoryGroupName(
void DefaultPlatform::SetTracingController(
tracing::TracingController* tracing_controller) {
tracing_controller_ = tracing_controller;
tracing_controller_.reset(tracing_controller);
}
size_t DefaultPlatform::NumberOfAvailableBackgroundThreads() {
return static_cast<size_t>(thread_pool_size_);
}
void DefaultPlatform::AddTraceStateObserver(TraceStateObserver* observer) {
if (!tracing_controller_) return;
tracing_controller_->AddTraceStateObserver(observer);
}
void DefaultPlatform::RemoveTraceStateObserver(TraceStateObserver* observer) {
if (!tracing_controller_) return;
tracing_controller_->RemoveTraceStateObserver(observer);
}
} // namespace platform
} // namespace v8
......@@ -7,6 +7,7 @@
#include <functional>
#include <map>
#include <memory>
#include <queue>
#include <vector>
......@@ -62,6 +63,9 @@ class DefaultPlatform : public Platform {
const char* name, uint64_t handle) override;
void SetTracingController(tracing::TracingController* tracing_controller);
void AddTraceStateObserver(TraceStateObserver* observer) override;
void RemoveTraceStateObserver(TraceStateObserver* observer) override;
private:
static const int kMaxThreadPoolSize;
......@@ -80,7 +84,7 @@ class DefaultPlatform : public Platform {
std::priority_queue<DelayedEntry, std::vector<DelayedEntry>,
std::greater<DelayedEntry> > >
main_thread_delayed_queue_;
tracing::TracingController* tracing_controller_;
std::unique_ptr<tracing::TracingController> tracing_controller_;
DISALLOW_COPY_AND_ASSIGN(DefaultPlatform);
};
......
......@@ -38,8 +38,13 @@ const int g_num_builtin_categories = 4;
// Skip default categories.
v8::base::AtomicWord g_category_index = g_num_builtin_categories;
TracingController::TracingController() {}
TracingController::~TracingController() {}
void TracingController::Initialize(TraceBuffer* trace_buffer) {
trace_buffer_.reset(trace_buffer);
mutex_.reset(new base::Mutex());
}
uint64_t TracingController::AddTraceEvent(
......@@ -93,13 +98,29 @@ const char* TracingController::GetCategoryGroupName(
void TracingController::StartTracing(TraceConfig* trace_config) {
trace_config_.reset(trace_config);
mode_ = RECORDING_MODE;
UpdateCategoryGroupEnabledFlags();
std::unordered_set<Platform::TraceStateObserver*> observers_copy;
{
base::LockGuard<base::Mutex> lock(mutex_.get());
mode_ = RECORDING_MODE;
UpdateCategoryGroupEnabledFlags();
observers_copy = observers_;
}
for (auto o : observers_copy) {
o->OnTraceEnabled();
}
}
void TracingController::StopTracing() {
mode_ = DISABLED;
UpdateCategoryGroupEnabledFlags();
std::unordered_set<Platform::TraceStateObserver*> observers_copy;
{
base::LockGuard<base::Mutex> lock(mutex_.get());
observers_copy = observers_;
}
for (auto o : observers_copy) {
o->OnTraceDisabled();
}
trace_buffer_->Flush();
}
......@@ -174,6 +195,24 @@ const uint8_t* TracingController::GetCategoryGroupEnabledInternal(
return category_group_enabled;
}
void TracingController::AddTraceStateObserver(
Platform::TraceStateObserver* observer) {
{
base::LockGuard<base::Mutex> lock(mutex_.get());
observers_.insert(observer);
if (mode_ != RECORDING_MODE) return;
}
// Fire the observer if recording is already in progress.
observer->OnTraceEnabled();
}
void TracingController::RemoveTraceStateObserver(
Platform::TraceStateObserver* observer) {
base::LockGuard<base::Mutex> lock(mutex_.get());
DCHECK(observers_.find(observer) != observers_.end());
observers_.erase(observer);
}
} // namespace tracing
} // namespace platform
} // namespace v8
......@@ -332,6 +332,66 @@ TEST(TestTracingControllerMultipleArgsAndCopy) {
i::V8::SetPlatformForTesting(old_platform);
}
namespace {
class TraceStateObserverImpl : public Platform::TraceStateObserver {
public:
void OnTraceEnabled() override { ++enabled_count; }
void OnTraceDisabled() override { ++disabled_count; }
int enabled_count = 0;
int disabled_count = 0;
};
} // namespace
TEST(TracingObservers) {
v8::Platform* old_platform = i::V8::GetCurrentPlatform();
v8::Platform* default_platform = v8::platform::CreateDefaultPlatform();
i::V8::SetPlatformForTesting(default_platform);
v8::platform::tracing::TracingController tracing_controller;
v8::platform::SetTracingController(default_platform, &tracing_controller);
MockTraceWriter* writer = new MockTraceWriter();
v8::platform::tracing::TraceBuffer* ring_buffer =
v8::platform::tracing::TraceBuffer::CreateTraceBufferRingBuffer(1,
writer);
tracing_controller.Initialize(ring_buffer);
v8::platform::tracing::TraceConfig* trace_config =
new v8::platform::tracing::TraceConfig();
trace_config->AddIncludedCategory("v8");
TraceStateObserverImpl observer;
default_platform->AddTraceStateObserver(&observer);
CHECK_EQ(0, observer.enabled_count);
CHECK_EQ(0, observer.disabled_count);
tracing_controller.StartTracing(trace_config);
CHECK_EQ(1, observer.enabled_count);
CHECK_EQ(0, observer.disabled_count);
tracing_controller.StopTracing();
CHECK_EQ(1, observer.enabled_count);
CHECK_EQ(1, observer.disabled_count);
default_platform->RemoveTraceStateObserver(&observer);
CHECK_EQ(1, observer.enabled_count);
CHECK_EQ(1, observer.disabled_count);
trace_config = new v8::platform::tracing::TraceConfig();
tracing_controller.StartTracing(trace_config);
tracing_controller.StopTracing();
CHECK_EQ(1, observer.enabled_count);
CHECK_EQ(1, observer.disabled_count);
i::V8::SetPlatformForTesting(old_platform);
}
} // namespace tracing
} // namespace platform
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment