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

Unified Diff: base/debug/synthetic_delay.h

Issue 53923005: Add synthetic delay testing framework (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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
Index: base/debug/synthetic_delay.h
diff --git a/base/debug/synthetic_delay.h b/base/debug/synthetic_delay.h
new file mode 100644
index 0000000000000000000000000000000000000000..4639bb0d4bc4698a4ee5a180e3de1370c2229944
--- /dev/null
+++ b/base/debug/synthetic_delay.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// The synthetic delay framework makes it possible to dynamically inject
+// arbitrary delays into into different parts of the codebase. This can be used,
+// for instance, for testing various task scheduling algorithms.
+//
+// The delays are specified in terms of a target duration for a given block of
+// code. If the code executes faster than the duration, the thread is made to
+// sleep until the deadline is met.
Dominik Grewe 2013/11/07 16:45:53 Would it be better to busy wait rather than to sle
brianderson 2013/11/18 21:04:06 A sleep should work well if we are just testing th
+//
+// Code can be instrumented for delays with two sets of macros. First, for
+// delays that should apply within a scope, use the following macro:
+//
+// SYNTHETIC_DELAY("cc.LayerTreeHost.DrawAndSwap");
+//
+// For delaying operations that span multiple scopes, use:
+//
+// SYNTHETIC_DELAY_BEGIN("cc.Scheduler.BeginMainFrame");
+// SYNTHETIC_DELAY_END("cc.Scheduler.BeginMainFrame");
+//
+// Note that while the same delay can be applied in several threads
+// simultaneously, a single delay operation cannot begin on one thread and end
+// on another.
+
+#ifndef BASE_DEBUG_SYNTHETIC_DELAY_H_
+#define BASE_DEBUG_SYNTHETIC_DELAY_H_
+
+#include "base/atomicops.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_local.h"
+#include "base/time/time.h"
+
+#define INTERNAL_SYNTHETIC_DELAY_UID3(a, b) synthetic_delay_unique_##a##b
+#define INTERNAL_SYNTHETIC_DELAY_UID2(a, b) INTERNAL_SYNTHETIC_DELAY_UID3(a, b)
+#define INTERNAL_SYNTHETIC_DELAY_UID(name_prefix) \
+ INTERNAL_SYNTHETIC_DELAY_UID2(name_prefix, __LINE__)
+
+#define SYNTHETIC_DELAY(name) \
+ static base::subtle::AtomicWord INTERNAL_SYNTHETIC_DELAY_UID(impl_ptr) = 0; \
+ base::debug::ScopedSyntheticDelay INTERNAL_SYNTHETIC_DELAY_UID(delay)( \
+ name, &INTERNAL_SYNTHETIC_DELAY_UID(impl_ptr));
+
+#define SYNTHETIC_DELAY_BEGIN(name) \
+ do { \
+ static base::subtle::AtomicWord impl_ptr = 0; \
+ base::debug::synthetic_delay_internal::GetOrCreateDelay(name, &impl_ptr) \
+ ->Begin(); \
+ } while (false)
+
+#define SYNTHETIC_DELAY_END(name) \
+ do { \
+ static base::subtle::AtomicWord impl_ptr = 0; \
+ base::debug::synthetic_delay_internal::GetOrCreateDelay(name, &impl_ptr) \
+ ->End(); \
+ } while (false)
+
+template <typename Type>
+struct DefaultSingletonTraits;
+
+namespace base {
+namespace debug {
+
+class SyntheticDelay {
+ public:
+ void SetTargetDuration(TimeDelta target_duration);
+ void Begin();
+ void End();
+
+ private:
+ SyntheticDelay();
+ friend class SyntheticDelayController;
+
+ void Initialize(const char* name);
+
+ struct ThreadState {
+ base::TimeTicks start_time;
+ };
+
+ Lock lock_;
+ const char* name_;
+ base::TimeDelta target_duration_;
+ ThreadLocalPointer<ThreadState> thread_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticDelay);
+};
+
+class ScopedSyntheticDelay {
+ public:
+ explicit ScopedSyntheticDelay(const char* name, subtle::AtomicWord* impl_ptr);
+ ~ScopedSyntheticDelay();
+
+ private:
+ SyntheticDelay* delay_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSyntheticDelay);
+};
+
+const int kMaxSyntheticDelays = 32;
+
+class SyntheticDelayController {
brianderson 2013/11/05 03:12:05 Seems like you could move this class into the impl
Sami 2013/11/22 18:29:13 I'll need access to GetOrCreateDelay() later confi
+ public:
+ static SyntheticDelayController* GetInstance();
+
+ SyntheticDelay* GetOrCreateDelay(const char* name);
+
+ private:
+ SyntheticDelayController();
+
+ friend struct DefaultSingletonTraits<SyntheticDelayController>;
+
+ Lock lock_;
+ SyntheticDelay delays_[kMaxSyntheticDelays];
+ SyntheticDelay dummy_delay_;
+ int delay_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyntheticDelayController);
+};
+
+namespace synthetic_delay_internal {
+
+SyntheticDelay* GetOrCreateDelay(const char* name,
+ subtle::AtomicWord* impl_ptr);
+
+} // namespace synthetic_delay_internal
+} // namespace debug
+} // namespace base
+
+#endif /* BASE_DEBUG_SYNTHETIC_DELAY_H_ */

Powered by Google App Engine
This is Rietveld 408576698