blob: 1980559c3bf92ade3e1e92ca35c894540ee6bdaa [file] [log] [blame]
Dan Willemsend9f6fa22016-08-21 15:17:17 -07001// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package tracer
16
17import (
18 "bufio"
19 "os"
20 "sort"
21 "strconv"
22 "strings"
23 "time"
24)
25
Dan Willemsencae59bc2017-07-13 14:27:31 -070026type eventEntry struct {
Dan Willemsend9f6fa22016-08-21 15:17:17 -070027 Name string
Dan Willemsencae59bc2017-07-13 14:27:31 -070028 Begin uint64
29 End uint64
Dan Willemsend9f6fa22016-08-21 15:17:17 -070030}
Dan Willemsend9f6fa22016-08-21 15:17:17 -070031
Dan Willemsencae59bc2017-07-13 14:27:31 -070032func (t *tracerImpl) importEvents(entries []*eventEntry) {
33 sort.Slice(entries, func(i, j int) bool {
34 return entries[i].Begin < entries[j].Begin
35 })
36
37 cpus := []uint64{}
38 for _, entry := range entries {
39 tid := -1
40 for cpu, endTime := range cpus {
41 if endTime <= entry.Begin {
42 tid = cpu
43 cpus[cpu] = entry.End
44 break
45 }
46 }
47 if tid == -1 {
48 tid = len(cpus)
49 cpus = append(cpus, entry.End)
50 }
51
52 t.writeEvent(&viewerEvent{
53 Name: entry.Name,
54 Phase: "X",
55 Time: entry.Begin,
56 Dur: entry.End - entry.Begin,
57 Pid: 1,
58 Tid: uint64(tid),
59 })
60 }
61}
Dan Willemsend9f6fa22016-08-21 15:17:17 -070062
63// ImportNinjaLog reads a .ninja_log file from ninja and writes the events out
64// to the trace.
65//
66// startOffset is when the ninja process started, and is used to position the
67// relative times from the ninja log into the trace. It's also used to skip
68// reading the ninja log if nothing was run.
69func (t *tracerImpl) ImportNinjaLog(thread Thread, filename string, startOffset time.Time) {
70 t.Begin("ninja log import", thread)
71 defer t.End(thread)
72
73 if stat, err := os.Stat(filename); err != nil {
74 t.log.Println("Missing ninja log:", err)
75 return
76 } else if stat.ModTime().Before(startOffset) {
77 t.log.Verboseln("Ninja log not modified, not importing any entries.")
78 return
79 }
80
81 f, err := os.Open(filename)
82 if err != nil {
83 t.log.Println("Error opening ninja log:", err)
84 return
85 }
86 defer f.Close()
87
88 s := bufio.NewScanner(f)
89 header := true
Dan Willemsencae59bc2017-07-13 14:27:31 -070090 entries := []*eventEntry{}
Dan Willemsend9f6fa22016-08-21 15:17:17 -070091 prevEnd := 0
Dan Willemsencae59bc2017-07-13 14:27:31 -070092 offset := uint64(startOffset.UnixNano()) / 1000
Dan Willemsend9f6fa22016-08-21 15:17:17 -070093 for s.Scan() {
94 if header {
95 hdr := s.Text()
96 if hdr != "# ninja log v5" {
97 t.log.Printf("Unknown ninja log header: %q", hdr)
98 return
99 }
100 header = false
101 continue
102 }
103
104 fields := strings.Split(s.Text(), "\t")
105 begin, err := strconv.Atoi(fields[0])
106 if err != nil {
107 t.log.Printf("Unable to parse ninja entry %q: %v", s.Text(), err)
108 return
109 }
110 end, err := strconv.Atoi(fields[1])
111 if err != nil {
112 t.log.Printf("Unable to parse ninja entry %q: %v", s.Text(), err)
113 return
114 }
115 if end < prevEnd {
116 entries = nil
117 }
118 prevEnd = end
Dan Willemsencae59bc2017-07-13 14:27:31 -0700119 entries = append(entries, &eventEntry{
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700120 Name: fields[3],
Dan Willemsencae59bc2017-07-13 14:27:31 -0700121 Begin: offset + uint64(begin)*1000,
122 End: offset + uint64(end)*1000,
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700123 })
124 }
125 if err := s.Err(); err != nil {
126 t.log.Println("Unable to parse ninja log:", err)
127 return
128 }
129
Dan Willemsencae59bc2017-07-13 14:27:31 -0700130 t.importEvents(entries)
Dan Willemsend9f6fa22016-08-21 15:17:17 -0700131}