1// Copyright 2017 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)
24
25type eventEntry struct {
26	Name  string
27	Begin uint64
28	End   uint64
29}
30
31func (t *tracerImpl) importEvents(entries []*eventEntry) {
32	sort.Slice(entries, func(i, j int) bool {
33		return entries[i].Begin < entries[j].Begin
34	})
35
36	cpus := []uint64{}
37	for _, entry := range entries {
38		tid := -1
39		for cpu, endTime := range cpus {
40			if endTime <= entry.Begin {
41				tid = cpu
42				cpus[cpu] = entry.End
43				break
44			}
45		}
46		if tid == -1 {
47			tid = len(cpus)
48			cpus = append(cpus, entry.End)
49		}
50
51		t.writeEvent(&viewerEvent{
52			Name:  entry.Name,
53			Phase: "X",
54			Time:  entry.Begin,
55			Dur:   entry.End - entry.Begin,
56			Pid:   1,
57			Tid:   uint64(tid),
58		})
59	}
60}
61
62func (t *tracerImpl) ImportMicrofactoryLog(filename string) {
63	if _, err := os.Stat(filename); err != nil {
64		return
65	}
66
67	f, err := os.Open(filename)
68	if err != nil {
69		t.log.Verboseln("Error opening microfactory trace:", err)
70		return
71	}
72	defer f.Close()
73
74	entries := []*eventEntry{}
75	begin := map[string][]uint64{}
76	s := bufio.NewScanner(f)
77	for s.Scan() {
78		fields := strings.SplitN(s.Text(), " ", 3)
79		if len(fields) != 3 {
80			t.log.Verboseln("Unknown line in microfactory trace:", s.Text())
81			continue
82		}
83		timestamp, err := strconv.ParseUint(fields[0], 10, 64)
84		if err != nil {
85			t.log.Verboseln("Failed to parse timestamp in microfactory trace:", err)
86		}
87
88		if fields[1] == "B" {
89			begin[fields[2]] = append(begin[fields[2]], timestamp)
90		} else if beginTimestamps, ok := begin[fields[2]]; ok {
91			entries = append(entries, &eventEntry{
92				Name:  fields[2],
93				Begin: beginTimestamps[len(beginTimestamps)-1],
94				End:   timestamp,
95			})
96			begin[fields[2]] = beginTimestamps[:len(beginTimestamps)-1]
97		}
98	}
99
100	t.importEvents(entries)
101}
102