blob: f973613d47c298967b87f75ea6405b4611fd1760 [file] [log] [blame]
Dan Willemsenb82471a2018-05-17 16:37:09 -07001// Copyright 2018 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 "android/soong/ui/status"
Dan Alberte82234e2023-06-01 23:09:38 +000019 "strings"
Dan Willemsenb82471a2018-05-17 16:37:09 -070020 "time"
21)
22
23func (t *tracerImpl) StatusTracer() status.StatusOutput {
24 return &statusOutput{
25 tracer: t,
26
27 running: map[*status.Action]actionStatus{},
28 }
29}
30
31type actionStatus struct {
32 cpu int
33 start time.Time
34}
35
36type statusOutput struct {
37 tracer *tracerImpl
38
39 cpus []bool
40 running map[*status.Action]actionStatus
41}
42
43func (s *statusOutput) StartAction(action *status.Action, counts status.Counts) {
44 cpu := -1
45 for i, busy := range s.cpus {
46 if !busy {
47 cpu = i
48 s.cpus[i] = true
49 break
50 }
51 }
52
53 if cpu == -1 {
54 cpu = len(s.cpus)
55 s.cpus = append(s.cpus, true)
56 }
57
58 s.running[action] = actionStatus{
59 cpu: cpu,
60 start: time.Now(),
61 }
62}
63
Dan Alberte82234e2023-06-01 23:09:38 +000064func (s *statusOutput) parseTags(rawTags string) map[string]string {
65 if rawTags == "" {
66 return nil
67 }
68
69 tags := map[string]string{}
70 for _, pair := range strings.Split(rawTags, ";") {
71 if pair == "" {
72 // Ignore empty tag pairs. It's hard to generate these cleanly from
73 // make so some tag strings might be something like ";key=value".
74 continue
75 }
76 parts := strings.SplitN(pair, "=", 2)
77 tags[parts[0]] = parts[1]
78 }
79 return tags
80}
81
Dan Willemsenb82471a2018-05-17 16:37:09 -070082func (s *statusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
83 start, ok := s.running[result.Action]
84 if !ok {
85 return
86 }
87 delete(s.running, result.Action)
88 s.cpus[start.cpu] = false
89
90 str := result.Action.Description
91 if len(result.Action.Outputs) > 0 {
92 str = result.Action.Outputs[0]
93 }
94
95 s.tracer.writeEvent(&viewerEvent{
96 Name: str,
97 Phase: "X",
98 Time: uint64(start.start.UnixNano()) / 1000,
99 Dur: uint64(time.Since(start.start).Nanoseconds()) / 1000,
100 Pid: 1,
101 Tid: uint64(start.cpu),
Colin Crossd888b6b2020-10-15 13:46:32 -0700102 Arg: &statsArg{
103 UserTime: result.Stats.UserTime,
104 SystemTime: result.Stats.SystemTime,
105 MaxRssKB: result.Stats.MaxRssKB,
106 MinorPageFaults: result.Stats.MinorPageFaults,
107 MajorPageFaults: result.Stats.MajorPageFaults,
108 IOInputKB: result.Stats.IOInputKB,
109 IOOutputKB: result.Stats.IOOutputKB,
110 VoluntaryContextSwitches: result.Stats.VoluntaryContextSwitches,
111 InvoluntaryContextSwitches: result.Stats.InvoluntaryContextSwitches,
Dan Alberte82234e2023-06-01 23:09:38 +0000112 Tags: s.parseTags(result.Stats.Tags),
Colin Crossd888b6b2020-10-15 13:46:32 -0700113 },
Dan Willemsenb82471a2018-05-17 16:37:09 -0700114 })
115}
116
Colin Crossd888b6b2020-10-15 13:46:32 -0700117type statsArg struct {
Dan Alberte82234e2023-06-01 23:09:38 +0000118 UserTime uint32 `json:"user_time"`
119 SystemTime uint32 `json:"system_time_ms"`
120 MaxRssKB uint64 `json:"max_rss_kb"`
121 MinorPageFaults uint64 `json:"minor_page_faults"`
122 MajorPageFaults uint64 `json:"major_page_faults"`
123 IOInputKB uint64 `json:"io_input_kb"`
124 IOOutputKB uint64 `json:"io_output_kb"`
125 VoluntaryContextSwitches uint64 `json:"voluntary_context_switches"`
126 InvoluntaryContextSwitches uint64 `json:"involuntary_context_switches"`
127 Tags map[string]string `json:"tags"`
Colin Crossd888b6b2020-10-15 13:46:32 -0700128}
129
Dan Willemsenb82471a2018-05-17 16:37:09 -0700130func (s *statusOutput) Flush() {}
131func (s *statusOutput) Message(level status.MsgLevel, message string) {}
Colin Crosse0df1a32019-06-09 19:40:08 -0700132
133func (s *statusOutput) Write(p []byte) (int, error) {
134 // Discard writes
135 return len(p), nil
136}