Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2015 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 import os | 5 import os |
| 6 import sys | 6 import sys |
| 7 import time | 7 import time |
| 8 | 8 |
| 9 from systrace import systrace_agent | 9 from systrace.tracing_agents import TracingAgent, TraceResults |
|
Zhen Wang
2016/03/24 22:13:05
Separate this to 2 lines
alexandermont
2016/03/24 23:54:09
Done
| |
| 10 | |
| 11 | 10 |
| 12 class FtraceAgentIo(object): | 11 class FtraceAgentIo(object): |
| 13 | 12 |
| 14 @staticmethod | 13 @staticmethod |
| 15 def writeFile(path, data): | 14 def writeFile(path, data): |
| 16 with open(path, 'w') as f: | 15 with open(path, 'w') as f: |
| 17 f.write(data) | 16 f.write(data) |
| 18 | 17 |
| 19 @staticmethod | 18 @staticmethod |
| 20 def readFile(path): | 19 def readFile(path): |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 } | 82 } |
| 84 } | 83 } |
| 85 | 84 |
| 86 | 85 |
| 87 def try_create_agent(options, categories): | 86 def try_create_agent(options, categories): |
| 88 if options.target != 'linux': | 87 if options.target != 'linux': |
| 89 return False | 88 return False |
| 90 return FtraceAgent(options, categories, FtraceAgentIo) | 89 return FtraceAgent(options, categories, FtraceAgentIo) |
| 91 | 90 |
| 92 | 91 |
| 93 class FtraceAgent(systrace_agent.SystraceAgent): | 92 class FtraceAgent(TracingAgent): |
| 94 | 93 |
| 95 def __init__(self, options, categories, fio=FtraceAgentIo): | 94 def __init__(self, options, categories, fio=FtraceAgentIo): |
| 96 """Initialize a systrace agent. | 95 """Initialize a systrace agent. |
| 97 | 96 |
| 98 Args: | 97 Args: |
| 99 options: The command-line options. | 98 options: The command-line options. |
| 100 categories: The trace categories to capture. | 99 categories: The trace categories to capture. |
| 101 """ | 100 """ |
| 102 super(FtraceAgent, self).__init__(options, categories) | 101 super(FtraceAgent, self).__init__() |
| 103 if not self._categories: | 102 if not categories: |
| 104 self._categories = ["sched"] | 103 self._categories = ["sched"] |
| 104 else: | |
| 105 self._categories = categories | |
| 105 self._fio = fio | 106 self._fio = fio |
| 107 self._options = options | |
| 106 self._categories = [x for x in self._categories | 108 self._categories = [x for x in self._categories |
| 107 if self._is_category_available(x)] | 109 if self._is_category_available(x)] |
| 108 self._expect_trace = False | 110 self._should_output_trace = False |
| 109 | 111 |
| 110 def _get_trace_buffer_size(self): | 112 def _get_trace_buffer_size(self): |
| 111 buffer_size = 4096 | 113 buffer_size = 4096 |
| 112 if ((self._options.trace_buf_size is not None) | 114 if ((self._options.trace_buf_size is not None) |
| 113 and (self._options.trace_buf_size > 0)): | 115 and (self._options.trace_buf_size > 0)): |
| 114 buffer_size = self._options.trace_buf_size | 116 buffer_size = self._options.trace_buf_size |
| 115 return buffer_size | 117 return buffer_size |
| 116 | 118 |
| 117 def _get_trace_time(self): | 119 def _get_trace_time(self): |
| 118 wait_time = 5 | 120 wait_time = 5 |
| 119 if ((self._options.trace_time is not None) | 121 if ((self._options.trace_time is not None) |
| 120 and (self._options.trace_time > 0)): | 122 and (self._options.trace_time > 0)): |
| 121 wait_time = self._options.trace_time | 123 wait_time = self._options.trace_time |
| 122 return wait_time | 124 return wait_time |
| 123 | 125 |
| 124 def start(self): | 126 def StartAgentTracing(self): |
| 125 """Start tracing. | 127 """Start tracing. |
| 126 """ | 128 """ |
| 127 if self._options.list_categories or len(self._categories) == 0: | 129 if self._options.list_categories or len(self._categories) == 0: |
| 128 self._expect_trace = False | 130 self._should_output_trace = False |
| 129 else: | 131 else: |
| 130 self._expect_trace = True | 132 self._should_output_trace = True |
| 131 | 133 |
| 132 self._fio.writeFile(FT_BUFFER_SIZE, str(self._get_trace_buffer_size())) | 134 self._fio.writeFile(FT_BUFFER_SIZE, str(self._get_trace_buffer_size())) |
| 133 | 135 |
| 134 self._fio.writeFile(FT_CLOCK, 'global') | 136 self._fio.writeFile(FT_CLOCK, 'global') |
| 135 self._fio.writeFile(FT_TRACER, 'nop') | 137 self._fio.writeFile(FT_TRACER, 'nop') |
| 136 self._fio.writeFile(FT_OVERWRITE, "0") | 138 self._fio.writeFile(FT_OVERWRITE, "0") |
| 137 | 139 |
| 138 # TODO: riandrews to push necessary patches for TGID option to upstream | 140 # TODO: riandrews to push necessary patches for TGID option to upstream |
| 139 # linux kernel | 141 # linux kernel |
| 140 # self._fio.writeFile(FT_PRINT_TGID, '1') | 142 # self._fio.writeFile(FT_PRINT_TGID, '1') |
| 141 | 143 |
| 142 for category in self._categories: | 144 for category in self._categories: |
| 143 self._category_enable(category) | 145 self._category_enable(category) |
| 144 | 146 |
| 145 self._fio.writeFile(FT_TRACE, '') | 147 self._fio.writeFile(FT_TRACE, '') |
| 146 | 148 |
| 147 print "starting tracing." | 149 print "starting tracing." |
| 148 sys.stdout.flush() | 150 sys.stdout.flush() |
| 149 | 151 |
| 150 self._fio.writeFile(FT_TRACE_ON, '1') | 152 self._fio.writeFile(FT_TRACE_ON, '1') |
| 153 return True | |
| 151 | 154 |
| 152 def collect_result(self): | 155 def StopAgentTracing(self): |
| 153 """Collect the result of tracing. | 156 """Collect the result of tracing. |
| 154 | 157 |
| 155 This function will block while collecting the result. For sync mode, it | 158 This function will block while collecting the result. For sync mode, it |
| 156 reads the data, e.g., from stdout, until it finishes. For async mode, it | 159 reads the data, e.g., from stdout, until it finishes. For async mode, it |
| 157 blocks until the agent is stopped and the data is ready. | 160 blocks until the agent is stopped and the data is ready. |
| 158 """ | 161 """ |
| 159 if self._options.list_categories or len(self._categories) == 0: | 162 if self._options.list_categories or len(self._categories) == 0: |
| 160 self._print_avail_categories() | 163 self._print_avail_categories() |
| 161 else: | 164 else: |
| 162 try: | 165 try: |
| 163 time.sleep(self._get_trace_time()) | 166 time.sleep(self._get_trace_time()) |
| 164 except KeyboardInterrupt: | 167 except KeyboardInterrupt: |
| 165 pass | 168 pass |
| 166 self._fio.writeFile(FT_TRACE_ON, '0') | 169 self._fio.writeFile(FT_TRACE_ON, '0') |
| 167 for category in self._categories: | 170 for category in self._categories: |
| 168 self._category_disable(category) | 171 self._category_disable(category) |
| 169 if self._options.fix_threads: | 172 if self._options.fix_threads: |
| 170 print "WARN: thread name fixing is not yet supported." | 173 print "WARN: thread name fixing is not yet supported." |
| 171 if self._options.fix_tgids: | 174 if self._options.fix_tgids: |
| 172 print "WARN: tgid fixing is not yet supported." | 175 print "WARN: tgid fixing is not yet supported." |
| 173 if self._options.fix_circular: | 176 if self._options.fix_circular: |
| 174 print "WARN: circular buffer fixups are not yet supported." | 177 print "WARN: circular buffer fixups are not yet supported." |
| 178 return True | |
| 175 | 179 |
| 176 def expect_trace(self): | 180 def GetResults(self): |
| 177 """Check if the agent is returning a trace or not. | |
| 178 | |
| 179 This will be determined in collect_result(). | |
| 180 Returns: | |
| 181 Whether the agent is expecting a trace or not. | |
| 182 """ | |
| 183 return self._expect_trace | |
| 184 | |
| 185 def get_trace_data(self): | |
| 186 """Get the trace data. | 181 """Get the trace data. |
| 187 | 182 |
| 188 Returns: | 183 Returns: |
| 189 The trace data. | 184 The trace data. |
| 190 """ | 185 """ |
| 191 d = self._fio.readFile(FT_TRACE) | 186 d = self._fio.readFile(FT_TRACE) |
| 192 self._fio.writeFile(FT_BUFFER_SIZE, "1") | 187 self._fio.writeFile(FT_BUFFER_SIZE, "1") |
| 193 return d | 188 return TraceResults('systemTraceEvents', d, self._should_output_trace) |
| 194 | 189 |
| 195 def get_class_name(self): | 190 def SupportsExplicitClockSync(self): |
| 196 return 'trace-data' | 191 return False |
| 192 | |
| 193 def RecordClockSyncMarker(self, sync_id, callback): | |
| 194 raise NotImplementedError | |
| 197 | 195 |
| 198 def _is_category_available(self, category): | 196 def _is_category_available(self, category): |
| 199 if category not in all_categories: | 197 if category not in all_categories: |
| 200 return False | 198 return False |
| 201 events_dir = FT_DIR + "events/" | 199 events_dir = FT_DIR + "events/" |
| 202 req_events = all_categories[category]["req"] | 200 req_events = all_categories[category]["req"] |
| 203 for event in req_events: | 201 for event in req_events: |
| 204 event_full_path = events_dir + event + "enable" | 202 event_full_path = events_dir + event + "enable" |
| 205 if not self._fio.haveWritePermissions(event_full_path): | 203 if not self._fio.haveWritePermissions(event_full_path): |
| 206 return False | 204 return False |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 236 if self._fio.haveWritePermissions(event_full_path): | 234 if self._fio.haveWritePermissions(event_full_path): |
| 237 yield event_full_path | 235 yield event_full_path |
| 238 | 236 |
| 239 def _category_enable(self, category): | 237 def _category_enable(self, category): |
| 240 for path in self._category_enable_paths(category): | 238 for path in self._category_enable_paths(category): |
| 241 self._fio.writeFile(path, "1") | 239 self._fio.writeFile(path, "1") |
| 242 | 240 |
| 243 def _category_disable(self, category): | 241 def _category_disable(self, category): |
| 244 for path in self._category_enable_paths(category): | 242 for path in self._category_enable_paths(category): |
| 245 self._fio.writeFile(path, "0") | 243 self._fio.writeFile(path, "0") |
| OLD | NEW |