Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6725955 authored by Mythri Alle's avatar Mythri Alle Committed by Android (Google) Code Review
Browse files

Merge "Add clock-type to choose how timestamps are provided when profiling"

parents 220bae5a 4af4b730
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -928,6 +928,7 @@ public final class ActivityThread extends ClientTransactionHandler
        int samplingInterval;
        boolean autoStopProfiler;
        boolean streamingOutput;
        int mClockType;
        boolean profiling;
        boolean handlingProfiling;
        public void setProfiler(ProfilerInfo profilerInfo) {
@@ -954,6 +955,7 @@ public final class ActivityThread extends ClientTransactionHandler
            samplingInterval = profilerInfo.samplingInterval;
            autoStopProfiler = profilerInfo.autoStopProfiler;
            streamingOutput = profilerInfo.streamingOutput;
            mClockType = profilerInfo.clockType;
        }
        public void startProfiling() {
            if (profileFd == null || profiling) {
@@ -962,8 +964,8 @@ public final class ActivityThread extends ClientTransactionHandler
            try {
                int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8);
                VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
                        bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval,
                        streamingOutput);
                        bufferSize * 1024 * 1024, mClockType, samplingInterval != 0,
                        samplingInterval, streamingOutput);
                profiling = true;
            } catch (RuntimeException e) {
                Slog.w(TAG, "Profiling failed on path " + profileFile, e);
@@ -6688,6 +6690,7 @@ public final class ActivityThread extends ClientTransactionHandler
            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
            mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
            mProfiler.mClockType = data.initProfilerInfo.clockType;
            if (data.initProfilerInfo.attachAgentDuringBind) {
                agent = data.initProfilerInfo.agent;
            }
+46 −3
Original line number Diff line number Diff line
@@ -33,6 +33,17 @@ import java.util.Objects;
 */
public class ProfilerInfo implements Parcelable {

    // CLOCK_TYPE_DEFAULT chooses the default used by ART. ART uses CLOCK_TYPE_DUAL by default (see
    // kDefaultTraceClockSource in art/runtime/runtime_globals.h).
    public static final int CLOCK_TYPE_DEFAULT = 0x000;
    // The values of these constants are chosen such that they correspond to the flags passed to
    // VMDebug.startMethodTracing to choose the corresponding clock type (see
    // core/java/android/app/ActivityThread.java).
    // The flag values are defined in ART (see TraceFlag in art/runtime/trace.h).
    public static final int CLOCK_TYPE_WALL = 0x010;
    public static final int CLOCK_TYPE_THREAD_CPU = 0x100;
    public static final int CLOCK_TYPE_DUAL = 0x110;

    private static final String TAG = "ProfilerInfo";

    /* Name of profile output file. */
@@ -66,13 +77,20 @@ public class ProfilerInfo implements Parcelable {
     */
    public final boolean attachAgentDuringBind;

    /**
     * Indicates the clock source to be used for profiling. The source could be wallclock, thread
     * cpu or both
     */
    public final int clockType;

    public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop,
            boolean streaming, String agent, boolean attachAgentDuringBind) {
            boolean streaming, String agent, boolean attachAgentDuringBind, int clockType) {
        profileFile = filename;
        profileFd = fd;
        samplingInterval = interval;
        autoStopProfiler = autoStop;
        streamingOutput = streaming;
        this.clockType = clockType;
        this.agent = agent;
        this.attachAgentDuringBind = attachAgentDuringBind;
    }
@@ -85,6 +103,25 @@ public class ProfilerInfo implements Parcelable {
        streamingOutput = in.streamingOutput;
        agent = in.agent;
        attachAgentDuringBind = in.attachAgentDuringBind;
        clockType = in.clockType;
    }

    /**
     * Get the value for the clock type corresponding to the option string passed to the activity
     * manager. am profile start / am start-activity start-profiler commands accept clock-type
     * option to choose the source of timestamps when profiling. This function maps the option
     * string to the value of flags that is used when calling VMDebug.startMethodTracing
     */
    public static int getClockTypeFromString(String type) {
        if ("thread-cpu".equals(type)) {
            return CLOCK_TYPE_THREAD_CPU;
        } else if ("wall".equals(type)) {
            return CLOCK_TYPE_WALL;
        } else if ("dual".equals(type)) {
            return CLOCK_TYPE_DUAL;
        } else {
            return CLOCK_TYPE_DEFAULT;
        }
    }

    /**
@@ -93,7 +130,8 @@ public class ProfilerInfo implements Parcelable {
     */
    public ProfilerInfo setAgent(String agent, boolean attachAgentDuringBind) {
        return new ProfilerInfo(this.profileFile, this.profileFd, this.samplingInterval,
                this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind);
                this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind,
                this.clockType);
    }

    /**
@@ -133,6 +171,7 @@ public class ProfilerInfo implements Parcelable {
        out.writeInt(streamingOutput ? 1 : 0);
        out.writeString(agent);
        out.writeBoolean(attachAgentDuringBind);
        out.writeInt(clockType);
    }

    /** @hide */
@@ -146,6 +185,7 @@ public class ProfilerInfo implements Parcelable {
        proto.write(ProfilerInfoProto.AUTO_STOP_PROFILER, autoStopProfiler);
        proto.write(ProfilerInfoProto.STREAMING_OUTPUT, streamingOutput);
        proto.write(ProfilerInfoProto.AGENT, agent);
        proto.write(ProfilerInfoProto.CLOCK_TYPE, clockType);
        proto.end(token);
    }

@@ -170,6 +210,7 @@ public class ProfilerInfo implements Parcelable {
        streamingOutput = in.readInt() != 0;
        agent = in.readString();
        attachAgentDuringBind = in.readBoolean();
        clockType = in.readInt();
    }

    @Override
@@ -186,7 +227,8 @@ public class ProfilerInfo implements Parcelable {
                && autoStopProfiler == other.autoStopProfiler
                && samplingInterval == other.samplingInterval
                && streamingOutput == other.streamingOutput
                && Objects.equals(agent, other.agent);
                && Objects.equals(agent, other.agent)
                && clockType == other.clockType;
    }

    @Override
@@ -197,6 +239,7 @@ public class ProfilerInfo implements Parcelable {
        result = 31 * result + (autoStopProfiler ? 1 : 0);
        result = 31 * result + (streamingOutput ? 1 : 0);
        result = 31 * result + Objects.hashCode(agent);
        result = 31 * result + clockType;
        return result;
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -35,4 +35,5 @@ message ProfilerInfoProto {
    optional bool streaming_output = 5;
    // Denotes an agent (and its parameters) to attach for profiling.
    optional string agent = 6;
    optional int32 clock_type = 7;
}
+23 −38
Original line number Diff line number Diff line
@@ -103,7 +103,6 @@ import android.os.ServiceManager;
import android.os.ShellCommand;
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -192,6 +191,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
    private boolean mStreaming;   // Streaming the profiling output to a file.
    private String mAgent;  // Agent to attach on startup.
    private boolean mAttachAgentDuringBind;  // Whether agent should be attached late.
    private int mClockType; // Whether we need thread cpu / wall clock / both.
    private int mDisplayId;
    private int mTaskDisplayAreaFeatureId;
    private int mWindowingMode;
@@ -480,6 +480,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    mAutoStop = false;
                } else if (opt.equals("--sampling")) {
                    mSamplingInterval = Integer.parseInt(getNextArgRequired());
                } else if (opt.equals("--clock-type")) {
                    String clock_type = getNextArgRequired();
                    mClockType = ProfilerInfo.getClockTypeFromString(clock_type);
                } else if (opt.equals("--streaming")) {
                    mStreaming = true;
                } else if (opt.equals("--attach-agent")) {
@@ -642,7 +645,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    }
                }
                profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
                        mStreaming, mAgent, mAttachAgentDuringBind);
                        mStreaming, mAgent, mAttachAgentDuringBind, mClockType);
            }

            pw.println("Starting: " + intent);
@@ -972,26 +975,17 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    static void removeWallOption() {
        String props = SystemProperties.get("dalvik.vm.extra-opts");
        if (props != null && props.contains("-Xprofile:wallclock")) {
            props = props.replace("-Xprofile:wallclock", "");
            props = props.trim();
            SystemProperties.set("dalvik.vm.extra-opts", props);
        }
    }

    // NOTE: current profiles can only be started on default display (even on automotive builds with
    // passenger displays), so there's no need to pass a display-id
    private int runProfile(PrintWriter pw) throws RemoteException {
        final PrintWriter err = getErrPrintWriter();
        String profileFile = null;
        boolean start = false;
        boolean wall = false;
        int userId = UserHandle.USER_CURRENT;
        int profileType = 0;
        mSamplingInterval = 0;
        mStreaming = false;
        mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT;

        String process = null;

@@ -1003,8 +997,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
            while ((opt=getNextOption()) != null) {
                if (opt.equals("--user")) {
                    userId = UserHandle.parseUserArg(getNextArgRequired());
                } else if (opt.equals("--wall")) {
                    wall = true;
                } else if (opt.equals("--clock-type")) {
                    String clock_type = getNextArgRequired();
                    mClockType = ProfilerInfo.getClockTypeFromString(clock_type);
                } else if (opt.equals("--streaming")) {
                    mStreaming = true;
                } else if (opt.equals("--sampling")) {
@@ -1052,30 +1047,13 @@ final class ActivityManagerShellCommand extends ShellCommand {
                return -1;
            }
            profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
                    null, false);
                    null, false, mClockType);
        }

        try {
            if (wall) {
                // XXX doesn't work -- this needs to be set before booting.
                String props = SystemProperties.get("dalvik.vm.extra-opts");
                if (props == null || !props.contains("-Xprofile:wallclock")) {
                    props = props + " -Xprofile:wallclock";
                    //SystemProperties.set("dalvik.vm.extra-opts", props);
                }
            } else if (start) {
                //removeWallOption();
            }
        if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
                wall = false;
            err.println("PROFILE FAILED on process " + process);
            return -1;
        }
        } finally {
            if (!wall) {
                //removeWallOption();
            }
        }
        return 0;
    }

@@ -3948,9 +3926,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("  help");
            pw.println("      Print this help text.");
            pw.println("  start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
            pw.println("          [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
            pw.println("          [--track-allocation] [--user <USER_ID> | current] [--suspend]");
            pw.println("          <INTENT>");
            pw.println("          [--sampling INTERVAL] [--clock-type <TYPE>] [--streaming]");
            pw.println("          [-R COUNT] [-S] [--track-allocation]");
            pw.println("          [--user <USER_ID> | current] [--suspend] <INTENT>");
            pw.println("      Start an Activity.  Options are:");
            pw.println("      -D: enable debugging");
            pw.println("      --suspend: debugged app suspend threads at startup (only with -D)");
@@ -3959,6 +3937,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("      --start-profiler <FILE>: start profiler and send results to <FILE>");
            pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
            pw.println("          between samples (use with --start-profiler)");
            pw.println("      --clock-type <TYPE>: type can be wall / thread-cpu / dual. Specify");
            pw.println("          the clock that is used to report the timestamps when profiling");
            pw.println("          The default value is dual. (use with --start-profiler)");
            pw.println("      --streaming: stream the profiling output to the specified file");
            pw.println("          (use with --start-profiler)");
            pw.println("      -P <FILE>: like above, but profiling stops when app goes idle");
@@ -4037,12 +4018,16 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("      stop: stop tracing IPC transactions and dump the results to file.");
            pw.println("      --dump-file <FILE>: Specify the file the trace should be dumped to.");
            pw.println("  profile start [--user <USER_ID> current]");
            pw.println("          [--clock-type <TYPE>]");
            pw.println("          [--sampling INTERVAL | --streaming] <PROCESS> <FILE>");
            pw.println("      Start profiler on a process.  The given <PROCESS> argument");
            pw.println("        may be either a process name or pid.  Options are:");
            pw.println("      --user <USER_ID> | current: When supplying a process name,");
            pw.println("          specify user of process to profile; uses current user if not");
            pw.println("          specified.");
            pw.println("      --clock-type <TYPE>: use the specified clock to report timestamps.");
            pw.println("          The type can be one of wall | thread-cpu | dual. The default");
            pw.println("          value is dual.");
            pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
            pw.println("          between samples.");
            pw.println("      --streaming: stream the profiling output to the specified file.");
+5 −3
Original line number Diff line number Diff line
@@ -2055,7 +2055,7 @@ public class AppProfiler {
                }
            } else if (instr != null && instr.mProfileFile != null) {
                profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false,
                        null, false);
                        null, false, 0);
            }
            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
                // We need to do a debuggable check here. See setAgentApp for why the check is
@@ -2065,7 +2065,7 @@ public class AppProfiler {
                    // Do not overwrite already requested agent.
                    if (profilerInfo == null) {
                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
                                mAppAgentMap.get(processName), true);
                                mAppAgentMap.get(processName), true, 0);
                    } else if (profilerInfo.agent == null) {
                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
                    }
@@ -2197,7 +2197,9 @@ public class AppProfiler {
                            + " mAutoStopProfiler="
                            + mProfileData.getProfilerInfo().autoStopProfiler
                            + " mStreamingOutput="
                            + mProfileData.getProfilerInfo().streamingOutput);
                            + mProfileData.getProfilerInfo().streamingOutput
                            + " mClockType="
                            + mProfileData.getProfilerInfo().clockType);
                    pw.println("  mProfileType=" + mProfileType);
                }
            }