1<!DOCTYPE html>
2<!--
3Copyright (c) 2012 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/extras/importer/linux_perf/parser.html">
9
10<script>
11'use strict';
12
13/**
14 * @fileoverview Parses sync events in the Linux event trace format.
15 */
16tr.exportTo('tr.e.importer.linux_perf', function() {
17
18  var ColorScheme = tr.b.ColorScheme;
19  var Parser = tr.e.importer.linux_perf.Parser;
20
21  /**
22   * Parses linux sync trace events.
23   * @constructor
24   */
25  function SyncParser(importer) {
26    Parser.call(this, importer);
27
28    importer.registerEventHandler(
29        'sync_timeline',
30        SyncParser.prototype.timelineEvent.bind(this));
31    importer.registerEventHandler(
32        'sync_wait',
33        SyncParser.prototype.syncWaitEvent.bind(this));
34    importer.registerEventHandler(
35        'sync_pt',
36        SyncParser.prototype.syncPtEvent.bind(this));
37    this.model_ = importer.model_;
38  }
39
40  var syncTimelineRE = /name=(\S+) value=(\S*)/;
41  var syncWaitRE = /(\S+) name=(\S+) state=(\d+)/;
42  var syncPtRE = /name=(\S+) value=(\S*)/;
43
44  SyncParser.prototype = {
45    __proto__: Parser.prototype,
46
47    /**
48     * Parses sync events and sets up state in the importer.
49     */
50    timelineEvent: function(eventName, cpuNumber, pid,
51                            ts, eventBase) {
52      var event = syncTimelineRE.exec(eventBase.details);
53      if (!event)
54        return false;
55
56      var thread = this.importer.getOrCreatePseudoThread(event[1]);
57
58      if (thread.lastActiveTs !== undefined) {
59        var duration = ts - thread.lastActiveTs;
60        var value = thread.lastActiveValue;
61        if (value == undefined)
62          value = ' ';
63        var slice = new tr.model.Slice(
64            '', value,
65            ColorScheme.getColorIdForGeneralPurposeString(value),
66            thread.lastActiveTs, {},
67            duration);
68        thread.thread.sliceGroup.pushSlice(slice);
69      }
70      thread.lastActiveTs = ts;
71      thread.lastActiveValue = event[2];
72      return true;
73    },
74
75    syncWaitEvent: function(eventName, cpuNumber, pid, ts,
76                            eventBase) {
77      var event = syncWaitRE.exec(eventBase.details);
78      if (!event)
79        return false;
80
81      if (eventBase.tgid === undefined) {
82        return false;
83      }
84
85      var tgid = parseInt(eventBase.tgid);
86      var thread = this.model_.getOrCreateProcess(tgid)
87        .getOrCreateThread(pid);
88      thread.name = eventBase.threadName;
89      var slices = thread.kernelSliceGroup;
90      if (!slices.isTimestampValidForBeginOrEnd(ts)) {
91        this.model_.importWarning({
92          type: 'parse_error',
93          message: 'Timestamps are moving backward.'
94        });
95        return false;
96      }
97
98      var name = 'fence_wait("' + event[2] + '")';
99      if (event[1] == 'begin') {
100        var slice = slices.beginSlice(null, name, ts, {
101          'Start state': event[3]
102        });
103      } else if (event[1] == 'end') {
104        if (slices.openSliceCount > 0) {
105          slices.endSlice(ts);
106        }
107      } else {
108        return false;
109      }
110
111      return true;
112    },
113
114    syncPtEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
115      var event = syncPtRE.exec(eventBase.details);
116      if (!event)
117        return false;
118
119      return true;
120
121      var thread = this.importer.getOrCreateKernelThread(
122          eventBase[1]).thread;
123      thread.syncWaitSyncPts[event[1]] = event[2];
124      return true;
125    }
126  };
127
128  Parser.register(SyncParser);
129
130  return {
131    SyncParser: SyncParser
132  };
133});
134</script>
135
136