• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.traceview;
18 
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 
22 class ThreadData implements TimeLineView.Row {
23 
24     private int mId;
25     private String mName;
26     private boolean mIsEmpty;
27 
28     private Call mRootCall;
29     private ArrayList<Call> mStack = new ArrayList<Call>();
30 
31     // This is a hash of all the methods that are currently on the stack.
32     private HashMap<MethodData, Integer> mStackMethods = new HashMap<MethodData, Integer>();
33 
34     boolean mHaveGlobalTime;
35     long mGlobalStartTime;
36     long mGlobalEndTime;
37 
38     boolean mHaveThreadTime;
39     long mThreadStartTime;
40     long mThreadEndTime;
41 
42     long mThreadCurrentTime; // only used while parsing thread-cpu clock
43 
ThreadData(int id, String name, MethodData topLevel)44     ThreadData(int id, String name, MethodData topLevel) {
45         mId = id;
46         mName = String.format("[%d] %s", id, name);
47         mIsEmpty = true;
48         mRootCall = new Call(this, topLevel, null);
49         mRootCall.setName(mName);
50         mStack.add(mRootCall);
51     }
52 
getName()53     public String getName() {
54         return mName;
55     }
56 
getRootCall()57     public Call getRootCall() {
58         return mRootCall;
59     }
60 
61     /**
62      * Returns true if no calls have ever been recorded for this thread.
63      */
isEmpty()64     public boolean isEmpty() {
65         return mIsEmpty;
66     }
67 
enter(MethodData method, ArrayList<TraceAction> trace)68     Call enter(MethodData method, ArrayList<TraceAction> trace) {
69         if (mIsEmpty) {
70             mIsEmpty = false;
71             if (trace != null) {
72                 trace.add(new TraceAction(TraceAction.ACTION_ENTER, mRootCall));
73             }
74         }
75 
76         Call caller = top();
77         Call call = new Call(this, method, caller);
78         mStack.add(call);
79 
80         if (trace != null) {
81             trace.add(new TraceAction(TraceAction.ACTION_ENTER, call));
82         }
83 
84         Integer num = mStackMethods.get(method);
85         if (num == null) {
86             num = 0;
87         } else if (num > 0) {
88             call.setRecursive(true);
89         }
90         mStackMethods.put(method, num + 1);
91 
92         return call;
93     }
94 
exit(MethodData method, ArrayList<TraceAction> trace)95     Call exit(MethodData method, ArrayList<TraceAction> trace) {
96         Call call = top();
97         if (call.mCaller == null) {
98             return null;
99         }
100 
101         if (call.getMethodData() != method) {
102             String error = "Method exit (" + method.getName()
103                     + ") does not match current method (" + call.getMethodData().getName()
104                     + ")";
105             throw new RuntimeException(error);
106         }
107 
108         mStack.remove(mStack.size() - 1);
109 
110         if (trace != null) {
111             trace.add(new TraceAction(TraceAction.ACTION_EXIT, call));
112         }
113 
114         Integer num = mStackMethods.get(method);
115         if (num != null) {
116             if (num == 1) {
117                 mStackMethods.remove(method);
118             } else {
119                 mStackMethods.put(method, num - 1);
120             }
121         }
122 
123         return call;
124     }
125 
top()126     Call top() {
127         return mStack.get(mStack.size() - 1);
128     }
129 
endTrace(ArrayList<TraceAction> trace)130     void endTrace(ArrayList<TraceAction> trace) {
131         for (int i = mStack.size() - 1; i >= 1; i--) {
132             Call call = mStack.get(i);
133             call.mGlobalEndTime = mGlobalEndTime;
134             call.mThreadEndTime = mThreadEndTime;
135             if (trace != null) {
136                 trace.add(new TraceAction(TraceAction.ACTION_INCOMPLETE, call));
137             }
138         }
139         mStack.clear();
140         mStackMethods.clear();
141     }
142 
updateRootCallTimeBounds()143     void updateRootCallTimeBounds() {
144         if (!mIsEmpty) {
145             mRootCall.mGlobalStartTime = mGlobalStartTime;
146             mRootCall.mGlobalEndTime = mGlobalEndTime;
147             mRootCall.mThreadStartTime = mThreadStartTime;
148             mRootCall.mThreadEndTime = mThreadEndTime;
149         }
150     }
151 
152     @Override
toString()153     public String toString() {
154         return mName;
155     }
156 
getId()157     public int getId() {
158         return mId;
159     }
160 
getCpuTime()161     public long getCpuTime() {
162         return mRootCall.mInclusiveCpuTime;
163     }
164 
getRealTime()165     public long getRealTime() {
166         return mRootCall.mInclusiveRealTime;
167     }
168 }
169