• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2018 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package trebuchet.importers.ftrace.events
18 
19 import trebuchet.importers.ftrace.FtraceImporterState
20 import trebuchet.util.BufferReader
21 
22 class BeginSliceEvent(val tgid: Int, val title: String) : FtraceEventDetails {
23     override fun import(event: FtraceEvent, state: FtraceImporterState) {
24         state.threadFor(event.pid, tgid, event.task).slicesBuilder.beginSlice {
25             it.startTime = event.timestamp
26             it.name = title
27         }
28     }
29 }
30 
31 class EndSliceEvent : FtraceEventDetails {
importnull32     override fun import(event: FtraceEvent, state: FtraceImporterState) {
33         state.threadFor(event.pid, event.tgid, event.task).slicesBuilder.endSlice {
34             it.endTime = event.timestamp
35         }
36     }
37 }
38 
39 class CounterSliceEvent(val tgid: Int, val name: String, val value: Long) : FtraceEventDetails {
importnull40     override fun import(event: FtraceEvent, state: FtraceImporterState) {
41         state.threadFor(event.pid, tgid, event.task).process
42                 .addCounterSample(name, event.timestamp, value)
43     }
44 
45 }
46 
47 class StartAsyncSliceEvent(val tgid: Int, val name: String, val cookie: Int) : FtraceEventDetails {
importnull48     override fun import(event: FtraceEvent, state: FtraceImporterState) {
49         state.processFor(tgid, event.task).asyncSlicesBuilder
50             .openAsyncSlice(event.pid, name, cookie, event.timestamp)
51     }
52 }
53 
54 class FinishAsyncSliceEvent(val tgid: Int, val name: String, val cookie: Int) : FtraceEventDetails {
importnull55     override fun import(event: FtraceEvent, state: FtraceImporterState) {
56         state.processFor(tgid, event.task).asyncSlicesBuilder
57             .closeAsyncSlice(event.pid, name, cookie, event.timestamp)
58     }
59 }
60 
BufferReadernull61 private fun BufferReader.readBeginSlice(): BeginSliceEvent {
62     // Begin format: B|<tgid>|<title>
63     skipCount(2)
64     val tgid = readInt()
65     skip()
66     val name = stringTo { end() }
67     return BeginSliceEvent(tgid, name)
68 }
69 
readCounternull70 private fun BufferReader.readCounter(): CounterSliceEvent {
71     // Counter format: C|<tgid>|<name>|<value>
72     skipCount(2)
73     val tgid = readInt()
74     skip()
75     val name = stringTo { skipUntil { it == '|'.toByte() } }
76     skip()
77     val value = readLong()
78     return CounterSliceEvent(tgid, name, value)
79 }
80 
BufferReadernull81 private fun BufferReader.readOpenAsyncSlice(): StartAsyncSliceEvent {
82     // Async start format: S|<tgid>|<title>|<cookie>
83     skipCount(2)
84     val tgid = readInt()
85     skip()
86     val name = stringTo { skipUntil {  it == '|'.toByte() } }
87     skip()
88     val cookie = readInt()
89     return StartAsyncSliceEvent(tgid, name, cookie)
90 }
91 
BufferReadernull92 private fun BufferReader.readCloseAsyncSlice(): FinishAsyncSliceEvent {
93     // Async start format: F|<tgid>|<title>|<cookie>
94     skipCount(2)
95     val tgid = readInt()
96     skip()
97     val name = stringTo { skipUntil {  it == '|'.toByte() } }
98     skip()
99     val cookie = readInt()
100     return FinishAsyncSliceEvent(tgid, name, cookie)
101 }
102 
103 class ParentTSEvent(val parentTimestamp: Double) : FtraceEventDetails {
importnull104     override fun import(event: FtraceEvent, state: FtraceImporterState) {
105         state.modelFragment.parentTimestamp = parentTimestamp
106     }
107 }
108 
109 class RealtimeTSEvent(val realtimeTimestamp: Long) : FtraceEventDetails {
importnull110     override fun import(event: FtraceEvent, state: FtraceImporterState) {
111         state.modelFragment.realtimeTimestamp = realtimeTimestamp
112     }
113 }
114 
115 object TraceMarkerEvent {
116     const val Begin = 'B'.toByte()
117     const val End = 'E'.toByte()
118     const val Counter = 'C'.toByte()
119     const val Start = 'S'.toByte()
120     const val Finish = 'F'.toByte()
121 
sharedStatenull122     val register: EventRegistryEntry = { sharedState ->
123 
124         val parentTsMatcher = sharedState.addPattern(
125                 "trace_event_clock_sync: parent_ts=(.*)")
126         val realtimeTsMatcher = sharedState.addPattern(
127                 "trace_event_clock_sync: realtime_ts=(.*)")
128 
129         fun BufferReader.readClockSyncMarker(state: EventParserState): FtraceEventDetails? {
130             // First check if the line we are importing is the parent timestamp line.
131             tryMatch(state.matchers[parentTsMatcher]) {
132                 return ParentTSEvent(double(1))
133             }
134             // Test if the line we are testing has the realtime timestamp.
135             tryMatch(state.matchers[realtimeTsMatcher]) {
136                 return RealtimeTSEvent(long(1))
137             }
138             return null
139         }
140 
141         sharedState.onParseDetails("tracing_mark_write") { state, details ->
142             state.readDetails(details) {
143                 when (peek()) {
144                     Begin -> readBeginSlice()
145                     End -> EndSliceEvent()
146                     Counter -> readCounter()
147                     Start -> readOpenAsyncSlice()
148                     Finish -> readCloseAsyncSlice()
149                     else -> readClockSyncMarker(state)
150                 }
151             }
152         }
153     }
154 }