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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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
5 // The synthetic delay framework makes it possible to dynamically inject
6 // arbitrary delays into into different parts of the codebase. This can be used,
7 // for instance, for testing various task scheduling algorithms.
8 //
9 // The delays are specified in terms of a target duration for a given block of
10 // code. If the code executes faster than the duration, the thread is made to
11 // 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
12 //
13 // Code can be instrumented for delays with two sets of macros. First, for
14 // delays that should apply within a scope, use the following macro:
15 //
16 // SYNTHETIC_DELAY("cc.LayerTreeHost.DrawAndSwap");
17 //
18 // For delaying operations that span multiple scopes, use:
19 //
20 // SYNTHETIC_DELAY_BEGIN("cc.Scheduler.BeginMainFrame");
21 // SYNTHETIC_DELAY_END("cc.Scheduler.BeginMainFrame");
22 //
23 // Note that while the same delay can be applied in several threads
24 // simultaneously, a single delay operation cannot begin on one thread and end
25 // on another.
26
27 #ifndef BASE_DEBUG_SYNTHETIC_DELAY_H_
28 #define BASE_DEBUG_SYNTHETIC_DELAY_H_
29
30 #include "base/atomicops.h"
31 #include "base/synchronization/lock.h"
32 #include "base/threading/thread_local.h"
33 #include "base/time/time.h"
34
35 #define INTERNAL_SYNTHETIC_DELAY_UID3(a, b) synthetic_delay_unique_##a##b
36 #define INTERNAL_SYNTHETIC_DELAY_UID2(a, b) INTERNAL_SYNTHETIC_DELAY_UID3(a, b)
37 #define INTERNAL_SYNTHETIC_DELAY_UID(name_prefix) \
38 INTERNAL_SYNTHETIC_DELAY_UID2(name_prefix, __LINE__)
39
40 #define SYNTHETIC_DELAY(name) \
41 static base::subtle::AtomicWord INTERNAL_SYNTHETIC_DELAY_UID(impl_ptr) = 0; \
42 base::debug::ScopedSyntheticDelay INTERNAL_SYNTHETIC_DELAY_UID(delay)( \
43 name, &INTERNAL_SYNTHETIC_DELAY_UID(impl_ptr));
44
45 #define SYNTHETIC_DELAY_BEGIN(name) \
46 do { \
47 static base::subtle::AtomicWord impl_ptr = 0; \
48 base::debug::synthetic_delay_internal::GetOrCreateDelay(name, &impl_ptr) \
49 ->Begin(); \
50 } while (false)
51
52 #define SYNTHETIC_DELAY_END(name) \
53 do { \
54 static base::subtle::AtomicWord impl_ptr = 0; \
55 base::debug::synthetic_delay_internal::GetOrCreateDelay(name, &impl_ptr) \
56 ->End(); \
57 } while (false)
58
59 template <typename Type>
60 struct DefaultSingletonTraits;
61
62 namespace base {
63 namespace debug {
64
65 class SyntheticDelay {
66 public:
67 void SetTargetDuration(TimeDelta target_duration);
68 void Begin();
69 void End();
70
71 private:
72 SyntheticDelay();
73 friend class SyntheticDelayController;
74
75 void Initialize(const char* name);
76
77 struct ThreadState {
78 base::TimeTicks start_time;
79 };
80
81 Lock lock_;
82 const char* name_;
83 base::TimeDelta target_duration_;
84 ThreadLocalPointer<ThreadState> thread_state_;
85
86 DISALLOW_COPY_AND_ASSIGN(SyntheticDelay);
87 };
88
89 class ScopedSyntheticDelay {
90 public:
91 explicit ScopedSyntheticDelay(const char* name, subtle::AtomicWord* impl_ptr);
92 ~ScopedSyntheticDelay();
93
94 private:
95 SyntheticDelay* delay_impl_;
96
97 DISALLOW_COPY_AND_ASSIGN(ScopedSyntheticDelay);
98 };
99
100 const int kMaxSyntheticDelays = 32;
101
102 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
103 public:
104 static SyntheticDelayController* GetInstance();
105
106 SyntheticDelay* GetOrCreateDelay(const char* name);
107
108 private:
109 SyntheticDelayController();
110
111 friend struct DefaultSingletonTraits<SyntheticDelayController>;
112
113 Lock lock_;
114 SyntheticDelay delays_[kMaxSyntheticDelays];
115 SyntheticDelay dummy_delay_;
116 int delay_count_;
117
118 DISALLOW_COPY_AND_ASSIGN(SyntheticDelayController);
119 };
120
121 namespace synthetic_delay_internal {
122
123 SyntheticDelay* GetOrCreateDelay(const char* name,
124 subtle::AtomicWord* impl_ptr);
125
126 } // namespace synthetic_delay_internal
127 } // namespace debug
128 } // namespace base
129
130 #endif /* BASE_DEBUG_SYNTHETIC_DELAY_H_ */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698