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 }