2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 import java.util.List;
18 import java.util.ArrayList;
19 import java.util.LinkedList;
21 import java.util.HashMap;
22 import java.io.Serializable;
27 class Proc implements Serializable {
29 private static final long serialVersionUID = 0;
31 /** Parent process. */
38 * Name of this process. We may not have the correct name at first, i.e.
39 * some classes could have been loaded before the process name was set.
43 /** Child processes. */
44 final List<Proc> children = new ArrayList<Proc>();
46 /** Maps thread ID to operation stack. */
47 transient final Map<Integer, LinkedList<Operation>> stacks
48 = new HashMap<Integer, LinkedList<Operation>>();
50 /** Number of operations. */
53 /** Sequential list of operations that happened in this process. */
54 final List<Operation> operations = new ArrayList<Operation>();
56 /** List of past process names. */
57 final List<String> nameHistory = new ArrayList<String>();
59 /** Constructs a new process. */
60 Proc(Proc parent, int id) {
65 /** Sets name of this process. */
66 void setName(String name) {
67 if (!name.equals(this.name)) {
68 if (this.name != null) {
69 nameHistory.add(this.name);
76 * Returns true if this process comes from the zygote.
78 public boolean fromZygote() {
79 return parent != null && parent.name.equals("zygote")
80 && !name.equals("com.android.development");
84 * Starts an operation.
86 * @param threadId thread the operation started in
87 * @param loadedClass class operation happened to
88 * @param time the operation started
90 void startOperation(int threadId, LoadedClass loadedClass, long time,
91 Operation.Type type) {
92 Operation o = new Operation(
93 this, loadedClass, time, operationCount++, type);
96 LinkedList<Operation> stack = stacks.get(threadId);
98 stack = new LinkedList<Operation>();
99 stacks.put(threadId, stack);
102 if (!stack.isEmpty()) {
103 stack.getLast().subops.add(o);
112 * @param threadId thread the operation ended in
113 * @param loadedClass class operation happened to
114 * @param time the operation ended
116 Operation endOperation(int threadId, String className,
117 LoadedClass loadedClass, long time) {
118 LinkedList<Operation> stack = stacks.get(threadId);
120 if (stack == null || stack.isEmpty()) {
121 didNotStart(className);
125 Operation o = stack.getLast();
126 if (loadedClass != o.loadedClass) {
127 didNotStart(className);
133 o.endTimeNanos = time;
138 * Prints an error indicating that we saw the end of an operation but not
139 * the start. A bug in the logging framework which results in dropped logs
142 private static void didNotStart(String name) {
143 System.err.println("Warning: An operation ended on " + name
144 + " but it never started!");
148 * Prints this process tree to stdout.
155 * Prints a child proc to standard out.
157 private void print(String prefix) {
158 System.out.println(prefix + "id=" + id + ", name=" + name);
159 for (Proc child : children) {
160 child.print(prefix + " ");
165 public String toString() {