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

Unified Diff: base/debug/trace_event_synthetic_delay.cc

Issue 83183005: Add synthetic delay points for latency testing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Begin delay on one thread and end it on another. Created 7 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 | « base/debug/trace_event_synthetic_delay.h ('k') | base/debug/trace_event_synthetic_delay_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/debug/trace_event_synthetic_delay.cc
diff --git a/base/debug/trace_event_synthetic_delay.cc b/base/debug/trace_event_synthetic_delay.cc
index cb9904621f6082cb944eb3a7e38a957a92073f46..5d7444ae319eadbfdbede0e8f76d326b96baeef9 100644
--- a/base/debug/trace_event_synthetic_delay.cc
+++ b/base/debug/trace_event_synthetic_delay.cc
@@ -4,8 +4,6 @@
#include "base/debug/trace_event_synthetic_delay.h"
#include "base/memory/singleton.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread_local.h"
namespace {
const int kMaxSyntheticDelays = 32;
@@ -17,24 +15,11 @@ namespace debug {
TraceEventSyntheticDelayClock::TraceEventSyntheticDelayClock() {}
TraceEventSyntheticDelayClock::~TraceEventSyntheticDelayClock() {}
-// Thread-local state for each synthetic delay point. This allows the same delay
-// to be applied to multiple threads simultaneously.
-struct ThreadState {
- ThreadState();
-
- base::TimeTicks start_time;
- unsigned trigger_count;
- int generation;
-};
-
-ThreadState::ThreadState() : trigger_count(0u), generation(0) {}
-
class TraceEventSyntheticDelayRegistry : public TraceEventSyntheticDelayClock {
public:
static TraceEventSyntheticDelayRegistry* GetInstance();
TraceEventSyntheticDelay* GetOrCreateDelay(const char* name);
- ThreadState* GetThreadState(int index);
void ResetAllDelays();
// TraceEventSyntheticDelayClock implementation.
@@ -50,13 +35,11 @@ class TraceEventSyntheticDelayRegistry : public TraceEventSyntheticDelayClock {
TraceEventSyntheticDelay dummy_delay_;
base::subtle::Atomic32 delay_count_;
- ThreadLocalPointer<ThreadState> thread_states_;
-
DISALLOW_COPY_AND_ASSIGN(TraceEventSyntheticDelayRegistry);
};
TraceEventSyntheticDelay::TraceEventSyntheticDelay()
- : mode_(STATIC), generation_(0), thread_state_index_(0), clock_(NULL) {}
+ : mode_(STATIC), begin_count_(0), trigger_count_(0), clock_(NULL) {}
TraceEventSyntheticDelay::~TraceEventSyntheticDelay() {}
@@ -68,33 +51,30 @@ TraceEventSyntheticDelay* TraceEventSyntheticDelay::Lookup(
void TraceEventSyntheticDelay::Initialize(
const std::string& name,
- TraceEventSyntheticDelayClock* clock,
- int thread_state_index) {
+ TraceEventSyntheticDelayClock* clock) {
name_ = name;
clock_ = clock;
- thread_state_index_ = thread_state_index;
}
void TraceEventSyntheticDelay::SetTargetDuration(
base::TimeDelta target_duration) {
AutoLock lock(lock_);
target_duration_ = target_duration;
- generation_++;
+ trigger_count_ = 0;
+ begin_count_ = 0;
}
void TraceEventSyntheticDelay::SetMode(Mode mode) {
AutoLock lock(lock_);
mode_ = mode;
- generation_++;
}
void TraceEventSyntheticDelay::SetClock(TraceEventSyntheticDelayClock* clock) {
AutoLock lock(lock_);
clock_ = clock;
- generation_++;
}
-void TraceEventSyntheticDelay::Activate() {
+void TraceEventSyntheticDelay::Begin() {
// Note that we check for a non-zero target duration without locking to keep
// things quick for the common case when delays are disabled. Since the delay
// calculation is done with a lock held, it will always be correct. The only
@@ -104,47 +84,52 @@ void TraceEventSyntheticDelay::Activate() {
if (!target_duration_.ToInternalValue())
return;
- ThreadState* thread_state =
- TraceEventSyntheticDelayRegistry::GetInstance()->
- GetThreadState(thread_state_index_);
- if (!thread_state->start_time.ToInternalValue())
- thread_state->start_time = clock_->Now();
+ BeginInternal(1, false);
}
-void TraceEventSyntheticDelay::Apply() {
+void TraceEventSyntheticDelay::BeginInternal(int begin_delta, bool reset) {
brianderson 2013/12/10 02:25:39 When reset is true, is it possible that there is a
+ AutoLock lock(lock_);
+ if (reset)
+ begin_count_ = begin_delta;
+ else
+ begin_count_ += begin_delta;
+
+ if (!reset && begin_count_ - begin_delta > 0)
+ return;
+ start_time_ = clock_->Now();
+}
+
+void TraceEventSyntheticDelay::End() {
ANNOTATE_BENIGN_RACE(&target_duration_, "Synthetic delay duration");
if (!target_duration_.ToInternalValue())
return;
- ThreadState* thread_state =
- TraceEventSyntheticDelayRegistry::GetInstance()->
- GetThreadState(thread_state_index_);
- if (!thread_state->start_time.ToInternalValue())
- return;
- base::TimeTicks now = clock_->Now();
- base::TimeTicks start_time = thread_state->start_time;
base::TimeTicks end_time;
- thread_state->start_time = base::TimeTicks();
-
{
AutoLock lock(lock_);
- if (thread_state->generation != generation_) {
- thread_state->trigger_count = 0;
- thread_state->generation = generation_;
- }
+ if (!begin_count_ || --begin_count_ > 0)
+ return;
+ base::TimeTicks now = clock_->Now();
- if (mode_ == ONE_SHOT && thread_state->trigger_count++)
+ if (mode_ == ONE_SHOT && trigger_count_++)
return;
- else if (mode_ == ALTERNATING && thread_state->trigger_count++ % 2)
+ else if (mode_ == ALTERNATING && trigger_count_++ % 2)
return;
- end_time = start_time + target_duration_;
+ end_time = start_time_ + target_duration_;
if (now >= end_time)
return;
}
ApplyDelay(end_time);
}
+void TraceEventSyntheticDelay::ResetAndBeginMultiple(int begin_count) {
+ ANNOTATE_BENIGN_RACE(&target_duration_, "Synthetic delay duration");
+ if (!target_duration_.ToInternalValue())
+ return;
+ BeginInternal(begin_count, true);
+}
+
void TraceEventSyntheticDelay::ApplyDelay(base::TimeTicks end_time) {
TRACE_EVENT0("synthetic_delay", name_.c_str());
while (clock_->Now() < end_time) {
@@ -184,24 +169,11 @@ TraceEventSyntheticDelay* TraceEventSyntheticDelayRegistry::GetOrCreateDelay(
if (delay_count >= kMaxSyntheticDelays)
return &dummy_delay_;
- delays_[delay_count].Initialize(std::string(name), this, delay_count);
+ delays_[delay_count].Initialize(std::string(name), this);
base::subtle::Release_Store(&delay_count_, delay_count + 1);
return &delays_[delay_count];
}
-ThreadState* TraceEventSyntheticDelayRegistry::GetThreadState(int index) {
- DCHECK(index >= 0 && index < kMaxSyntheticDelays);
- if (index < 0 || index >= kMaxSyntheticDelays)
- return NULL;
-
- // Note that these thread states are leaked at program exit. They will only
- // get allocated if synthetic delays are actually used.
- ThreadState* thread_states = thread_states_.Get();
- if (!thread_states)
- thread_states_.Set((thread_states = new ThreadState[kMaxSyntheticDelays]));
- return &thread_states[index];
-}
-
base::TimeTicks TraceEventSyntheticDelayRegistry::Now() {
return base::TimeTicks::HighResNow();
}
@@ -225,10 +197,10 @@ namespace trace_event_internal {
ScopedSyntheticDelay::ScopedSyntheticDelay(const char* name,
base::subtle::AtomicWord* impl_ptr)
: delay_impl_(GetOrCreateDelay(name, impl_ptr)) {
- delay_impl_->Activate();
+ delay_impl_->Begin();
}
-ScopedSyntheticDelay::~ScopedSyntheticDelay() { delay_impl_->Apply(); }
+ScopedSyntheticDelay::~ScopedSyntheticDelay() { delay_impl_->End(); }
base::debug::TraceEventSyntheticDelay* GetOrCreateDelay(
const char* name,
« no previous file with comments | « base/debug/trace_event_synthetic_delay.h ('k') | base/debug/trace_event_synthetic_delay_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698