blob: a8b4e62f42bcd594557708e9b2d9cc233b8a8113 [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"
19 "time"
20)
21
22func (t *tracerImpl) StatusTracer() status.StatusOutput {
23 return &statusOutput{
24 tracer: t,
25
26 running: map[*status.Action]actionStatus{},
27 }
28}
29
30type actionStatus struct {
31 cpu int
32 start time.Time
33}
34
35type statusOutput struct {
36 tracer *tracerImpl
37
38 cpus []bool
39 running map[*status.Action]actionStatus
40}
41
42func (s *statusOutput) StartAction(action *status.Action, counts status.Counts) {
43 cpu := -1
44 for i, busy := range s.cpus {
45 if !busy {
46 cpu = i
47 s.cpus[i] = true
48 break
49 }
50 }
51
52 if cpu == -1 {
53 cpu = len(s.cpus)
54 s.cpus = append(s.cpus, true)
55 }
56
57 s.running[action] = actionStatus{
58 cpu: cpu,
59 start: time.Now(),
60 }
61}
62
63func (s *statusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
64 start, ok := s.running[result.Action]
65 if !ok {
66 return
67 }
68 delete(s.running, result.Action)
69 s.cpus[start.cpu] = false
70
71 str := result.Action.Description
72 if len(result.Action.Outputs) > 0 {
73 str = result.Action.Outputs[0]
74 }
75
76 s.tracer.writeEvent(&viewerEvent{
77 Name: str,
78 Phase: "X",
79 Time: uint64(start.start.UnixNano()) / 1000,
80 Dur: uint64(time.Since(start.start).Nanoseconds()) / 1000,
81 Pid: 1,
82 Tid: uint64(start.cpu),
Colin Crossd888b6b2020-10-15 13:46:32 -070083 Arg: &statsArg{
84 UserTime: result.Stats.UserTime,
85 SystemTime: result.Stats.SystemTime,
86 MaxRssKB: result.Stats.MaxRssKB,
87 MinorPageFaults: result.Stats.MinorPageFaults,
88 MajorPageFaults: result.Stats.MajorPageFaults,
89 IOInputKB: result.Stats.IOInputKB,
90 IOOutputKB: result.Stats.IOOutputKB,
91 VoluntaryContextSwitches: result.Stats.VoluntaryContextSwitches,
92 InvoluntaryContextSwitches: result.Stats.InvoluntaryContextSwitches,
93 },
Dan Willemsenb82471a2018-05-17 16:37:09 -070094 })
95}
96
Colin Crossd888b6b2020-10-15 13:46:32 -070097type statsArg struct {
98 UserTime uint32 `json:"user_time"`
99 SystemTime uint32 `json:"system_time_ms"`
100 MaxRssKB uint64 `json:"max_rss_kb"`
101 MinorPageFaults uint64 `json:"minor_page_faults"`
102 MajorPageFaults uint64 `json:"major_page_faults"`
103 IOInputKB uint64 `json:"io_input_kb"`
104 IOOutputKB uint64 `json:"io_output_kb"`
105 VoluntaryContextSwitches uint64 `json:"voluntary_context_switches"`
106 InvoluntaryContextSwitches uint64 `json:"involuntary_context_switches"`
107}
108
Dan Willemsenb82471a2018-05-17 16:37:09 -0700109func (s *statusOutput) Flush() {}
110func (s *statusOutput) Message(level status.MsgLevel, message string) {}
Colin Crosse0df1a32019-06-09 19:40:08 -0700111
112func (s *statusOutput) Write(p []byte) (int, error) {
113 // Discard writes
114 return len(p), nil
115}