[tracing] Implement Add/RemoveTraceStateObserver for default platform.

BUG=chromium:406277

Review-Url: https://codereview.chromium.org/2369073003
Cr-Commit-Position: refs/heads/master@{#39794}
This commit is contained in:
alph 2016-09-27 13:12:41 -07:00 committed by Commit bot
parent ff135975b0
commit fcf1bac99a
5 changed files with 136 additions and 11 deletions

View File

@ -7,11 +7,17 @@
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <unordered_set>
#include <vector> #include <vector>
#include "include/v8-platform.h" #include "include/v8-platform.h"
namespace v8 { namespace v8 {
namespace base {
class Mutex;
} // namespace base
namespace platform { namespace platform {
namespace tracing { namespace tracing {
@ -227,7 +233,8 @@ class TracingController {
ENABLED_FOR_ETW_EXPORT = 1 << 3 ENABLED_FOR_ETW_EXPORT = 1 << 3
}; };
TracingController() {} TracingController();
~TracingController();
void Initialize(TraceBuffer* trace_buffer); void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group); const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag); static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
@ -244,6 +251,9 @@ class TracingController {
void StartTracing(TraceConfig* trace_config); void StartTracing(TraceConfig* trace_config);
void StopTracing(); void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
private: private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group); const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index); void UpdateCategoryGroupEnabledFlag(size_t category_index);
@ -251,6 +261,8 @@ class TracingController {
std::unique_ptr<TraceBuffer> trace_buffer_; std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_; std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
Mode mode_ = DISABLED; Mode mode_ = DISABLED;
// Disallow copy and assign // Disallow copy and assign

View File

@ -39,9 +39,14 @@ void SetTracingController(
const int DefaultPlatform::kMaxThreadPoolSize = 8; const int DefaultPlatform::kMaxThreadPoolSize = 8;
DefaultPlatform::DefaultPlatform() DefaultPlatform::DefaultPlatform()
: initialized_(false), thread_pool_size_(0), tracing_controller_(NULL) {} : initialized_(false), thread_pool_size_(0) {}
DefaultPlatform::~DefaultPlatform() { DefaultPlatform::~DefaultPlatform() {
if (tracing_controller_) {
tracing_controller_->StopTracing();
tracing_controller_.reset();
}
base::LockGuard<base::Mutex> guard(&lock_); base::LockGuard<base::Mutex> guard(&lock_);
queue_.Terminate(); queue_.Terminate();
if (initialized_) { if (initialized_) {
@ -63,11 +68,6 @@ DefaultPlatform::~DefaultPlatform() {
i->second.pop(); i->second.pop();
} }
} }
if (tracing_controller_) {
tracing_controller_->StopTracing();
delete tracing_controller_;
}
} }
@ -219,12 +219,22 @@ const char* DefaultPlatform::GetCategoryGroupName(
void DefaultPlatform::SetTracingController( void DefaultPlatform::SetTracingController(
tracing::TracingController* tracing_controller) { tracing::TracingController* tracing_controller) {
tracing_controller_ = tracing_controller; tracing_controller_.reset(tracing_controller);
} }
size_t DefaultPlatform::NumberOfAvailableBackgroundThreads() { size_t DefaultPlatform::NumberOfAvailableBackgroundThreads() {
return static_cast<size_t>(thread_pool_size_); 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 platform
} // namespace v8 } // namespace v8

View File

@ -7,6 +7,7 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory>
#include <queue> #include <queue>
#include <vector> #include <vector>
@ -62,6 +63,9 @@ class DefaultPlatform : public Platform {
const char* name, uint64_t handle) override; const char* name, uint64_t handle) override;
void SetTracingController(tracing::TracingController* tracing_controller); void SetTracingController(tracing::TracingController* tracing_controller);
void AddTraceStateObserver(TraceStateObserver* observer) override;
void RemoveTraceStateObserver(TraceStateObserver* observer) override;
private: private:
static const int kMaxThreadPoolSize; static const int kMaxThreadPoolSize;
@ -80,7 +84,7 @@ class DefaultPlatform : public Platform {
std::priority_queue<DelayedEntry, std::vector<DelayedEntry>, std::priority_queue<DelayedEntry, std::vector<DelayedEntry>,
std::greater<DelayedEntry> > > std::greater<DelayedEntry> > >
main_thread_delayed_queue_; main_thread_delayed_queue_;
tracing::TracingController* tracing_controller_; std::unique_ptr<tracing::TracingController> tracing_controller_;
DISALLOW_COPY_AND_ASSIGN(DefaultPlatform); DISALLOW_COPY_AND_ASSIGN(DefaultPlatform);
}; };

View File

@ -38,8 +38,13 @@ const int g_num_builtin_categories = 4;
// Skip default categories. // Skip default categories.
v8::base::AtomicWord g_category_index = g_num_builtin_categories; v8::base::AtomicWord g_category_index = g_num_builtin_categories;
TracingController::TracingController() {}
TracingController::~TracingController() {}
void TracingController::Initialize(TraceBuffer* trace_buffer) { void TracingController::Initialize(TraceBuffer* trace_buffer) {
trace_buffer_.reset(trace_buffer); trace_buffer_.reset(trace_buffer);
mutex_.reset(new base::Mutex());
} }
uint64_t TracingController::AddTraceEvent( uint64_t TracingController::AddTraceEvent(
@ -93,13 +98,29 @@ const char* TracingController::GetCategoryGroupName(
void TracingController::StartTracing(TraceConfig* trace_config) { void TracingController::StartTracing(TraceConfig* trace_config) {
trace_config_.reset(trace_config); trace_config_.reset(trace_config);
std::unordered_set<Platform::TraceStateObserver*> observers_copy;
{
base::LockGuard<base::Mutex> lock(mutex_.get());
mode_ = RECORDING_MODE; mode_ = RECORDING_MODE;
UpdateCategoryGroupEnabledFlags(); UpdateCategoryGroupEnabledFlags();
observers_copy = observers_;
}
for (auto o : observers_copy) {
o->OnTraceEnabled();
}
} }
void TracingController::StopTracing() { void TracingController::StopTracing() {
mode_ = DISABLED; mode_ = DISABLED;
UpdateCategoryGroupEnabledFlags(); 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(); trace_buffer_->Flush();
} }
@ -174,6 +195,24 @@ const uint8_t* TracingController::GetCategoryGroupEnabledInternal(
return category_group_enabled; 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 tracing
} // namespace platform } // namespace platform
} // namespace v8 } // namespace v8

View File

@ -332,6 +332,66 @@ TEST(TestTracingControllerMultipleArgsAndCopy) {
i::V8::SetPlatformForTesting(old_platform); 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 tracing
} // namespace platform } // namespace platform
} // namespace v8 } // namespace v8