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

Side by Side Diff: chrome/browser/metrics/tracking_synchronizer.h

Issue 8588023: Collect profiler stats from browser child processes. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_ 5 #ifndef CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_
6 #define CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_ 6 #define CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_
7 #pragma once 7 #pragma once
8 8
9 #include <map> 9 #include <map>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h" 15 #include "base/memory/weak_ptr.h"
16 #include "base/message_loop.h"
17 #include "base/process.h"
16 #include "base/time.h" 18 #include "base/time.h"
17 #include "base/values.h" 19 #include "base/values.h"
18 #include "chrome/browser/ui/webui/profiler_ui.h" 20 #include "chrome/browser/ui/webui/profiler_ui.h"
19 #include "content/common/child_process_info.h" 21 #include "content/browser/profiler_controller.h"
20 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
21 23
22 // This class maintains state that is used to upload tracking data from the 24 // This class maintains state that is used to upload profiler data from the
23 // various processes, into the browser process. Such transactions are usually 25 // various processes, into the browser process. Such transactions are usually
24 // instigated by the browser. In general, a process will respond by gathering 26 // instigated by the browser. In general, a process will respond by gathering
25 // tracking data, and transmitting the pickled tracking data. We collect the 27 // profiler data, and transmitting the pickled profiler data. We collect the
26 // data in asynchronous mode that doesn't block the UI thread. 28 // data in asynchronous mode that doesn't block the UI thread.
27 // 29 //
28 // To assure that all the processes have responded, a counter is maintained 30 // To assure that all the processes have responded, a counter is maintained
29 // to indicate the number of pending (not yet responsive) processes. We tag 31 // to indicate the number of pending (not yet responsive) processes. We tag
30 // each group of requests with a sequence number. For each group of requests, we 32 // each group of requests with a sequence number. For each group of requests, we
31 // create RequestContext object which stores the sequence number, pending 33 // create RequestContext object which stores the sequence number, pending
32 // processes and the callback_object that needs to be notified when we receive 34 // processes and the callback_object that needs to be notified when we receive
33 // an update from processes. When an update arrives we find the RequestContext 35 // an update from processes. When an update arrives we find the RequestContext
34 // associated with sequence number and send the unpickled tracking data to the 36 // associated with sequence number and send the unpickled profiler data to the
35 // |callback_object_|. 37 // |callback_object_|.
36 38
37 namespace chrome_browser_metrics { 39 namespace chrome_browser_metrics {
38 40
39 class TrackingSynchronizer : public 41 class TrackingSynchronizer
40 base::RefCountedThreadSafe<TrackingSynchronizer> { 42 : public ProfilerSubscriber,
43 public base::RefCountedThreadSafe<TrackingSynchronizer> {
41 public: 44 public:
42 // The "RequestContext" structure describes an individual request received 45 // The "RequestContext" structure describes an individual request received
43 // from the UI. 46 // from the UI.
44 struct RequestContext { 47 struct RequestContext {
45 RequestContext(const base::WeakPtr<ProfilerUI>& callback_object, 48 RequestContext(const base::WeakPtr<ProfilerUI>& callback_object,
46 int sequence_number, 49 int sequence_number,
47 int processes_pending, 50 int ui_processes_pending,
51 int io_processes_pending,
52 int threads_pending,
48 base::TimeTicks callback_start_time) 53 base::TimeTicks callback_start_time)
49 : callback_object_(callback_object), 54 : callback_object_(callback_object),
50 sequence_number_(sequence_number), 55 sequence_number_(sequence_number),
51 processes_pending_(processes_pending), 56 ui_processes_pending_(ui_processes_pending),
57 io_processes_pending_(io_processes_pending),
58 threads_pending_(threads_pending),
52 request_start_time_(callback_start_time) { 59 request_start_time_(callback_start_time) {
53 } 60 }
54 61
55 ~RequestContext() {} 62 ~RequestContext() {}
56 63
57 // Requests are made to asynchronously send data to the |callback_object_|. 64 // Requests are made to asynchronously send data to the |callback_object_|.
58 base::WeakPtr<ProfilerUI> callback_object_; 65 base::WeakPtr<ProfilerUI> callback_object_;
59 66
60 // The sequence number used by the most recent update request to contact all 67 // The sequence number used by the most recent update request to contact all
61 // processes. 68 // processes.
62 int sequence_number_; 69 int sequence_number_;
63 70
64 // The number of processes that have not yet responded to requests. 71 // The number of renderer processes that have not yet responded to requests.
65 int processes_pending_; 72 // This is updated on UI thread.
73 int ui_processes_pending_;
74
75 // The number of browser child processes that have not yet responded to
76 // requests. This is updated on IO thread.
77 int io_processes_pending_;
78
79 // The number of threads (UI and IO) we are waiting for. This is initialized
80 // to 2. This is decremented by 1 whenever either ui_processes_pending_ or
81 // io_processes_pending_ become zero (in other words, this will be zero when
82 // ui_processes_pending_ and io_processes_pending_ are zero).
83 // This is updated on UI thread.
84 int threads_pending_;
66 85
67 // The time when we were told to start the fetching of data from processes. 86 // The time when we were told to start the fetching of data from processes.
68 base::TimeTicks request_start_time_; 87 base::TimeTicks request_start_time_;
69 }; 88 };
70 89
71 // A map from sequence_number_ to the actual RequestContexts. 90 // A map from sequence_number_ to the actual RequestContexts.
72 typedef std::map<int, RequestContext*> RequestContextMap; 91 typedef std::map<int, RequestContext*> RequestContextMap;
73 92
93 // The DecrementProcessesCallback receives one argument:
94 // RequestContext request - the request in which we need to decrement the
95 // pending processes count (either ui_processes_pending_ or
96 // io_processes_pending_).
97 typedef base::Callback<void(RequestContext*)> DecrementProcessesCallback;
98
74 // Construction also sets up the global singleton instance. This instance is 99 // Construction also sets up the global singleton instance. This instance is
75 // used to communicate between the IO and UI thread, and is destroyed only as 100 // used to communicate between the IO and UI thread, and is destroyed only as
76 // the main thread (browser_main) terminates, which means the IO thread has 101 // the main thread (browser_main) terminates, which means the IO thread has
77 // already completed, and will not need this instance any further. 102 // already completed, and will not need this instance any further.
78 TrackingSynchronizer(); 103 TrackingSynchronizer();
79 104
80 // Return pointer to the singleton instance, which is allocated and
81 // deallocated on the main UI thread (during system startup and teardown).
82 static TrackingSynchronizer* CurrentSynchronizer();
83
84 // Contact all processes, and get them to upload to the browser any/all 105 // Contact all processes, and get them to upload to the browser any/all
85 // changes to tracking data. It calls |callback_object|'s SetData method with 106 // changes to profiler data. It calls |callback_object|'s SetData method with
86 // the data received from each sub-process. 107 // the data received from each sub-process.
87 // This method is accessible on UI thread. 108 // This method is accessible on UI thread.
88 static void FetchTrackingDataAsynchronously( 109 static void FetchProfilerDataAsynchronously(
89 const base::WeakPtr<ProfilerUI>& callback_object); 110 const base::WeakPtr<ProfilerUI>& callback_object);
90 111
91 // Contact all processes and set tracking status to |enable|. 112 // Contact all processes and set profiler status to |enable|.
92 // This method is accessible on UI thread. 113 // This method is accessible on UI thread.
93 static void SetTrackingStatus(bool enable); 114 static void SetProfilerStatus(bool enable);
94 115
95 // Respond to this message from the renderer by setting the tracking status 116 // Respond to this message from the renderer by setting the profiler status
96 // (SetTrackingStatusInProcess) in that renderer process. 117 // (SendRendererSetProfilerStatusOnUI) in that renderer process.
97 // |process_id| is used to find the renderer process. 118 // |renderer_process_id| is used to find the renderer process.
98 // This method is accessible on IO thread. 119 // This method is accessible on IO thread.
99 static void IsTrackingEnabled(int process_id); 120 static void IsProfilerEnabledForRenderer(int renderer_process_id);
100 121
101 // Get the current tracking status from the browser process and set it in the 122 // Deserialize the profiler data and record that we have received profiler
102 // renderer process. |process_id| is used to find the renderer process. 123 // data from a renderer process. This method posts a task to call
103 // This method is accessible on UI thread. 124 // OnRendererProfilerDatatCollectedOnUI on UI thread to send the
104 static void SetTrackingStatusInProcess(int process_id); 125 // |profiler_data| to callback_object_.
126 // This method is accessible on IO thread.
127 static void OnRendererProfilerDatatCollected(
128 int sequence_number,
129 const std::string& profiler_data);
105 130
106 // Deserialize the tracking data and record that we have received tracking 131 // ------------------------------------------------------
107 // data from a process. This method posts a task to call 132 // ProfilerSubscriber methods for browser child processes
108 // DeserializeTrackingListOnUI on UI thread to send the |tracking_data| to 133 // ------------------------------------------------------
109 // callback_object_. This method is accessible on IO thread. 134
110 static void DeserializeTrackingList( 135 // Deserialize the profiler data and record that we have received profiler
136 // data from a browser child process. This method is accessible on IO thread.
137 virtual void OnBrowserChildProfilerDataCollected(
111 int sequence_number, 138 int sequence_number,
112 const std::string& tracking_data, 139 const std::string& profiler_data) OVERRIDE;
113 ChildProcessInfo::ProcessType process_type);
114 140
115 // Deserialize the tracking data and record that we have received tracking 141 // Respond to this message from the browser child process by setting the
116 // data from a process. This method is accessible on UI thread. 142 // profiler status in that browser child process. |child_process_id| is used
117 static void DeserializeTrackingListOnUI( 143 // to find the child process. This method is accessible on IO thread.
118 int sequence_number, 144 virtual void OnIsProfilerEnabledForChildProcess(
119 const std::string& tracking_data, 145 base::ProcessId child_process_id) OVERRIDE;
120 ChildProcessInfo::ProcessType process_type);
121 146
122 private: 147 private:
123 friend class base::RefCountedThreadSafe<TrackingSynchronizer>; 148 friend class base::RefCountedThreadSafe<TrackingSynchronizer>;
124 149
125 virtual ~TrackingSynchronizer(); 150 virtual ~TrackingSynchronizer();
126 151
152 // Return pointer to the singleton instance, which is allocated and
153 // deallocated on the main UI thread (during system startup and teardown).
154 static TrackingSynchronizer* CurrentSynchronizer();
155
127 // Establish a new sequence_number_, and use it to notify all the processes of 156 // Establish a new sequence_number_, and use it to notify all the processes of
128 // the need to supply, to the browser, their tracking data. It also registers 157 // the need to supply, to the browser, their profiler data. It also registers
129 // |callback_object| in |outstanding_requests_| map. Return the 158 // |callback_object| in |outstanding_requests_| map. Return the
130 // sequence_number_ that was used. This method is accessible on UI thread. 159 // sequence_number_ that was used. This method is accessible on UI thread.
131 int RegisterAndNotifyAllProcesses( 160 int RegisterAndNotifyAllProcesses(
132 const base::WeakPtr<ProfilerUI>& callback_object); 161 const base::WeakPtr<ProfilerUI>& callback_object);
133 162
134 // It finds the |callback_object_| in |outstanding_requests_| map for the 163 // Notify all renderer processes that they need to supply, to the browser,
135 // given |sequence_number| and notifies the |callback_object_| about the 164 // their profiler data. This method is accessible on UI thread.
136 // |value|. This is called whenever we receive tracked data from processes. It 165 void NotifyAllRendererProcesses(RequestContext* request);
137 // also records that we are waiting for one less tracking data from a process
138 // for the given sequence number. If we have received a response from all
139 // renderers, then it deletes the entry for sequence_number from
140 // |outstanding_requests_| map. This method is accessible on UI thread.
141 void DecrementPendingProcessesAndSendData(int sequence_number,
142 base::DictionaryValue* value);
143 166
144 // Records that we are waiting for one less tracking data from a process for 167 // Notify all browser child processes that they need to supply, to the
145 // the given sequence number. 168 // browser, their profiler data. This method is accessible on IO thread.
169 void NotifyAllChildProcesses(RequestContext* request);
170
171 // Deserialize the profiler data and record that we have received profiler
172 // data from a renderer process. This method is accessible on UI thread.
173 static void OnRendererProfilerDatatCollectedOnUI(
174 int sequence_number,
175 const std::string& profiler_data);
176
177 // It builds a DecrementProcessesCallback for DecrementUIProcesses to record
178 // that we are waiting for one less profiler data from a process for the given
179 // sequence number and it calls DecrementPendingProcessesAndSendData to send
180 // the data to requester. This method is accessible on UI thread.
181 void DecrementPendingProcessesAndSendDataOnUI(int sequence_number,
182 base::DictionaryValue* value);
183
184 // It builds a DecrementProcessesCallback for DecrementIOProcesses to record
185 // that we are waiting for one less profiler data from a process for the given
186 // sequence number and it calls DecrementPendingProcessesAndSendData to send
187 // the data to requester. This method is accessible on IO thread.
188 void DecrementPendingProcessesAndSendDataOnIO(int sequence_number,
189 base::DictionaryValue* value);
190
191 // It finds the Request in |outstanding_requests_| map for the given
192 // |sequence_number| and notifies the Request's |callback_object_| about the
193 // |value|. It posts a task (RunDecrementProcessesCallback) on
194 // |callback_thread| to call |decrement_pending_process_cb| (which records
195 // that we are waiting for one less profiler data from a process for the
196 // given sequence number). This method is accessible on UI thread.
197 void DecrementPendingProcessesAndSendData(
198 int sequence_number,
199 base::DictionaryValue* value,
200 MessageLoop* callback_thread,
201 const DecrementProcessesCallback& decrement_pending_process_cb);
202
203 // Records that we are waiting for one less profiler data from a process for
204 // the given sequence number. If we have received a response from all
205 // renderers, then it calls DeleteIfAllDone which will delete the entry for
206 // sequence_number from |outstanding_requests_| map if |request|'s
207 // |threads_pending_| is zero.
208 // This method is accessible on UI thread (for renderer process).
209 void DecrementUIProcesses(RequestContext* request);
210
211 // Records that we are waiting for one less profiler data from a process for
212 // the given sequence number. If we have received a response from all child
213 // processes, then it posts a task on UI thread to call DeleteIfAllDone which
214 // will delete the entry for sequence_number from |outstanding_requests_| map
215 // if |request|'s |threads_pending_| is zero.
216 // This method is accessible on IO thread (for browser child process).
217 void DecrementIOProcesses(RequestContext* request);
218
219 // Deletes the entry for sequence_number from |outstanding_requests_| map (by
220 // calling ForceProfilerSynchronizationDoneCallback) if we have heard from all
221 // child and renderer processes.
146 // This method is accessible on UI thread. 222 // This method is accessible on UI thread.
147 void DecrementPendingProcesses(int sequence_number); 223 void DeleteIfAllDone(RequestContext* request);
148 224
149 // When all changes have been acquired, or when the wait time expires 225 // When all changes have been acquired, or when the wait time expires
150 // (whichever is sooner), this method is called. This method deletes the entry 226 // (whichever is sooner), this method is called. This method deletes the entry
151 // for the given sequence_number from |outstanding_requests_| map. 227 // for the given sequence_number from |outstanding_requests_| map.
152 // This method is accessible on UI thread. 228 // This method is accessible on UI thread.
153 void ForceTrackingSynchronizationDoneCallback(int sequence_number); 229 void ForceProfilerSynchronizationDoneCallback(int sequence_number);
154 230
155 // Get a new sequence number to be sent to processes from browser process. 231 // Get a new sequence number to be sent to processes from browser process.
156 // This method is accessible on UI thread. 232 // This method is accessible on UI thread.
157 int GetNextAvailableSequenceNumber(); 233 int GetNextAvailableSequenceNumber();
158 234
235 // Runs the |decrement_pending_process_cb| callback.
236 // |decrement_pending_process_cb| is either |DecrementUIProcesses| or
237 // |DecrementIOProcesses| which decrements |request|'s pending process count.
238 void RunDecrementProcessesCallback(
239 const DecrementProcessesCallback& decrement_pending_process_cb,
240 RequestContext* request);
241
242 // Contact all browser child processes and set profiler status to |enable|.
243 // This method is accessible on IO thread.
244 static void SetProfilerStatusInChildProcesses(bool enable);
245
246 // Get the current profiler status from the browser process and set it in the
247 // renderer process. |renderer_process_id| is used to find the renderer
248 // process. This method is accessible on UI thread.
249 static void SendRendererSetProfilerStatusOnUI(int renderer_process_id);
250
251 // Get the current profiler status from the browser process and set it in the
252 // browser child process. |child_process_id| is used to find the browser child
253 // process. This method is accessible on IO thread.
254 static void SendChildSetProfilerStatusOnIO(base::ProcessId child_process_id);
255
159 // Map of all outstanding RequestContexts, from sequence_number_ to 256 // Map of all outstanding RequestContexts, from sequence_number_ to
160 // RequestContext. 257 // RequestContext.
161 RequestContextMap outstanding_requests_; 258 RequestContextMap outstanding_requests_;
162 259
163 // We don't track the actual processes that are contacted for an update, only 260 // We don't track the actual processes that are contacted for an update, only
164 // the count of the number of processes, and we can sometimes time-out and 261 // the count of the number of processes, and we can sometimes time-out and
165 // give up on a "slow to respond" process. We use a sequence_number to be 262 // give up on a "slow to respond" process. We use a sequence_number to be
166 // sure a response from a process is associated with the current round of 263 // sure a response from a process is associated with the current round of
167 // requests. All sequence numbers used are non-negative. 264 // requests. All sequence numbers used are non-negative.
168 // last_used_sequence_number_ is the most recently used number (used to avoid 265 // last_used_sequence_number_ is the most recently used number (used to avoid
169 // reuse for a long time). 266 // reuse for a long time).
170 int last_used_sequence_number_; 267 int last_used_sequence_number_;
171 268
172 // This singleton instance should be started during the single threaded 269 // This singleton instance should be started during the single threaded
173 // portion of main(). It initializes globals to provide support for all future 270 // portion of main(). It initializes globals to provide support for all future
174 // calls. This object is created on the UI thread, and it is destroyed after 271 // calls. This object is created on the UI thread, and it is destroyed after
175 // all the other threads have gone away. As a result, it is ok to call it 272 // all the other threads have gone away. As a result, it is ok to call it
176 // from the UI thread, or for about:tracking. 273 // from the UI thread, or for about:profiler.
177 static TrackingSynchronizer* tracking_synchronizer_; 274 static TrackingSynchronizer* tracking_synchronizer_;
178 275
179 DISALLOW_COPY_AND_ASSIGN(TrackingSynchronizer); 276 DISALLOW_COPY_AND_ASSIGN(TrackingSynchronizer);
180 }; 277 };
181 278
182 } // namespace chrome_browser_metrics 279 } // namespace chrome_browser_metrics
183 280
184 #endif // CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_ 281 #endif // CHROME_BROWSER_METRICS_TRACKING_SYNCHRONIZER_H_
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/metrics/tracking_synchronizer.cc » ('j') | chrome/browser/metrics/tracking_synchronizer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698