1// 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 metrics 16 17import ( 18 "time" 19 20 "android/soong/ui/metrics/metrics_proto" 21 "android/soong/ui/tracer" 22 "github.com/golang/protobuf/proto" 23) 24 25// for testing purpose only 26var _now = now 27 28type timeEvent struct { 29 desc string 30 name string 31 32 // the time that the event started to occur. 33 start time.Time 34} 35 36type TimeTracer interface { 37 Begin(name, desc string, thread tracer.Thread) 38 End(thread tracer.Thread) soong_metrics_proto.PerfInfo 39} 40 41type timeTracerImpl struct { 42 activeEvents []timeEvent 43} 44 45var _ TimeTracer = &timeTracerImpl{} 46 47func now() time.Time { 48 return time.Now() 49} 50 51func (t *timeTracerImpl) Begin(name, desc string, _ tracer.Thread) { 52 t.activeEvents = append(t.activeEvents, timeEvent{name: name, desc: desc, start: _now()}) 53} 54 55func (t *timeTracerImpl) End(tracer.Thread) soong_metrics_proto.PerfInfo { 56 if len(t.activeEvents) < 1 { 57 panic("Internal error: No pending events for endAt to end!") 58 } 59 lastEvent := t.activeEvents[len(t.activeEvents)-1] 60 t.activeEvents = t.activeEvents[:len(t.activeEvents)-1] 61 realTime := uint64(_now().Sub(lastEvent.start).Nanoseconds()) 62 63 return soong_metrics_proto.PerfInfo{ 64 Desc: proto.String(lastEvent.desc), 65 Name: proto.String(lastEvent.name), 66 StartTime: proto.Uint64(uint64(lastEvent.start.UnixNano())), 67 RealTime: proto.Uint64(realTime), 68 } 69} 70