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

Commit 8358a314 authored by Zimuzo Ezeozue's avatar Zimuzo Ezeozue
Browse files

Instrument MesssageQueue with the Perfetto SDK

1. Instrument MQ depth
2. Flows between messages

Added PerfettoTrace methods to be pre-compiled since
it can impact MessageQueue perf.

Test: atest PerfettoTraceTest
Change-Id: Id2046767c4ad15ede677bbea0e43b6005b6cc6d0
Bug: 303199244
Flag: android.os.perfetto_sdk_tracing_v2
parent f89bf767
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -45,3 +45,24 @@ HSPLandroid/os/MessageQueue$OnFileDescriptorEventListener;->*
HSPLandroid/os/MessageQueue$StackNodeType;->*
HSPLandroid/os/MessageQueue$StateNode;->*
HSPLandroid/os/MessageQueue$TimedParkStateNode;->*
HSPLandroid/os/PerfettoTrace$Category;->*
HSPLandroid/os/PerfettoTrace;->*
HSPLandroid/os/PerfettoTrackEventExtra;->*
HSPLandroid/os/PerfettoTrackEventExtra$BuilderImpl;->*
HSPLandroid/os/PerfettoTrackEventExtra$NoOpBuilder;->*
HSPLandroid/os/PerfettoTrackEventExtra$ArgBool;->*
HSPLandroid/os/PerfettoTrackEventExtra$ArgInt64;->*
HSPLandroid/os/PerfettoTrackEventExtra$ArgDouble;->*
HSPLandroid/os/PerfettoTrackEventExtra$ArgString;->*
HSPLandroid/os/PerfettoTrackEventExtra$CounterInt64;->*
HSPLandroid/os/PerfettoTrackEventExtra$CounterDouble;->*
HSPLandroid/os/PerfettoTrackEventExtra$CounterTrack;->*
HSPLandroid/os/PerfettoTrackEventExtra$NamedTrack;->*
HSPLandroid/os/PerfettoTrackEventExtra$Flow;->*
HSPLandroid/os/PerfettoTrackEventExtra$Proto;->*
HSPLandroid/os/PerfettoTrackEventExtra$FieldInt64;->*
HSPLandroid/os/PerfettoTrackEventExtra$FieldDouble;->*
HSPLandroid/os/PerfettoTrackEventExtra$FieldString;->*
HSPLandroid/os/PerfettoTrackEventExtra$FieldNested;->*
HSPLandroid/os/PerfettoTrackEventExtra$Pool;->*
HSPLandroid/os/PerfettoTrackEventExtra$RingBuffer;->*
+60 −2
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@ import android.annotation.TestApi;
import android.app.ActivityThread;
import android.app.Instrumentation;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Process;
import android.os.UserHandle;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.ravenwood.annotation.RavenwoodRedirectionClass;
@@ -94,6 +92,13 @@ public final class MessageQueue {
    // queue for async messages when inserting a message at the tail.
    private int mAsyncMessageCount;

    /**
     * @hide
     */
    private final AtomicLong mMessageCount = new AtomicLong();
    private final Thread mThread;
    private final long mTid;

    /**
     * Select between two implementations of message queue. The legacy implementation is used
     * by default as it provides maximum compatibility with applications and tests that
@@ -128,6 +133,8 @@ public final class MessageQueue {
        mUseConcurrent = sIsProcessAllowedToUseConcurrent && !isInstrumenting();
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
        mThread = Thread.currentThread();
        mTid = Process.myTid();
    }

    private static void initIsProcessAllowedToUseConcurrent() {
@@ -218,6 +225,32 @@ public final class MessageQueue {
        }
    }

    private void decAndTraceMessageCount() {
        mMessageCount.decrementAndGet();
        traceMessageCount();
    }

    private void incAndTraceMessageCount(Message msg, long when) {
        mMessageCount.incrementAndGet();
        msg.mSendingThreadName = Thread.currentThread().getName();
        msg.mEventId.set(PerfettoTrace.getFlowId());

        traceMessageCount();
        PerfettoTrace.instant(PerfettoTrace.MQ_CATEGORY, "message_queue_send")
                .addFlow(msg.mEventId.get())
                .addArg("receiving_thread", mThread.getName())
                .addArg("delay", when - SystemClock.uptimeMillis())
                .addArg("what", msg.what)
                .emit();
    }

    /** @hide */
    private void traceMessageCount() {
        PerfettoTrace.counter(PerfettoTrace.MQ_CATEGORY, mMessageCount.get())
                .usingThreadCounterTrack(mTid, mThread.getName())
                .emit();
    }

    // Disposes of the underlying message queue.
    // Must only be called on the looper thread or the finalizer.
    private void dispose() {
@@ -800,6 +833,7 @@ public final class MessageQueue {
            Message msg = nextMessage(false, false);
            if (msg != null) {
                msg.markInUse();
                decAndTraceMessageCount();
                return msg;
            }

@@ -909,6 +943,7 @@ public final class MessageQueue {
                        if (msg.isAsynchronous()) {
                            mAsyncMessageCount--;
                        }
                        decAndTraceMessageCount();
                        if (TRACE) {
                            Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
                        }
@@ -1075,6 +1110,7 @@ public final class MessageQueue {

            msg.markInUse();
            msg.arg1 = token;
            incAndTraceMessageCount(msg, when);

            if (!enqueueMessageUnchecked(msg, when)) {
                Log.wtf(TAG_C, "Unexpected error while adding sync barrier!");
@@ -1090,6 +1126,7 @@ public final class MessageQueue {
            msg.markInUse();
            msg.when = when;
            msg.arg1 = token;
            incAndTraceMessageCount(msg, when);

            if (Flags.messageQueueTailTracking() && mLast != null && mLast.when <= when) {
                /* Message goes to tail of list */
@@ -1196,6 +1233,7 @@ public final class MessageQueue {
                needWake = mMessages == null || mMessages.target != null;
            }
            p.recycleUnchecked();
            decAndTraceMessageCount();

            // If the loop is quitting then it is already awake.
            // We can assume mPtr != 0 when mQuitting is false.
@@ -1252,6 +1290,8 @@ public final class MessageQueue {

            msg.markInUse();
            msg.when = when;
            incAndTraceMessageCount(msg, when);

            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
@@ -1391,6 +1431,7 @@ public final class MessageQueue {
                if (msg.isAsynchronous()) {
                    mAsyncMessageCount--;
                }
                decAndTraceMessageCount();
                if (TRACE) {
                    Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
                }
@@ -1642,6 +1683,7 @@ public final class MessageQueue {
                    mAsyncMessageCount--;
                }
                p.recycleUnchecked();
                decAndTraceMessageCount();
                p = n;
            }

@@ -1660,6 +1702,7 @@ public final class MessageQueue {
                            mAsyncMessageCount--;
                        }
                        n.recycleUnchecked();
                        decAndTraceMessageCount();
                        p.next = nn;
                        if (p.next == null) {
                            mLast = p;
@@ -1718,6 +1761,7 @@ public final class MessageQueue {
                            mAsyncMessageCount--;
                        }
                        n.recycleUnchecked();
                        decAndTraceMessageCount();
                        p.next = nn;
                        if (p.next == null) {
                            mLast = p;
@@ -1759,6 +1803,7 @@ public final class MessageQueue {
                    mAsyncMessageCount--;
                }
                p.recycleUnchecked();
                decAndTraceMessageCount();
                p = n;
            }

@@ -1777,6 +1822,7 @@ public final class MessageQueue {
                            mAsyncMessageCount--;
                        }
                        n.recycleUnchecked();
                        decAndTraceMessageCount();
                        p.next = nn;
                        if (p.next == null) {
                            mLast = p;
@@ -1832,6 +1878,7 @@ public final class MessageQueue {
                    mAsyncMessageCount--;
                }
                p.recycleUnchecked();
                decAndTraceMessageCount();
                p = n;
            }

@@ -1850,6 +1897,7 @@ public final class MessageQueue {
                            mAsyncMessageCount--;
                        }
                        n.recycleUnchecked();
                        decAndTraceMessageCount();
                        p.next = nn;
                        if (p.next == null) {
                            mLast = p;
@@ -1904,6 +1952,7 @@ public final class MessageQueue {
                    mAsyncMessageCount--;
                }
                p.recycleUnchecked();
                decAndTraceMessageCount();
                p = n;
            }

@@ -1921,6 +1970,7 @@ public final class MessageQueue {
                            mAsyncMessageCount--;
                        }
                        n.recycleUnchecked();
                        decAndTraceMessageCount();
                        p.next = nn;
                        if (p.next == null) {
                            mLast = p;
@@ -1976,6 +2026,7 @@ public final class MessageQueue {
                    mAsyncMessageCount--;
                }
                p.recycleUnchecked();
                decAndTraceMessageCount();
                p = n;
            }

@@ -1993,6 +2044,7 @@ public final class MessageQueue {
                            mAsyncMessageCount--;
                        }
                        n.recycleUnchecked();
                        decAndTraceMessageCount();
                        p.next = nn;
                        if (p.next == null) {
                            mLast = p;
@@ -2027,6 +2079,8 @@ public final class MessageQueue {
        mMessages = null;
        mLast = null;
        mAsyncMessageCount = 0;
        mMessageCount.set(0);
        traceMessageCount();
    }

    private void removeAllFutureMessagesLocked() {
@@ -2057,6 +2111,7 @@ public final class MessageQueue {
                        mAsyncMessageCount--;
                    }
                    p.recycleUnchecked();
                    decAndTraceMessageCount();
                } while (n != null);
            }
        }
@@ -2701,6 +2756,7 @@ public final class MessageQueue {
        MessageNode node = new MessageNode(msg, seq);
        msg.when = when;
        msg.markInUse();
        incAndTraceMessageCount(msg, when);

        if (DEBUG) {
            Log.d(TAG_C, "Insert message what: " + msg.what + " when: " + msg.when + " seq: "
@@ -2828,6 +2884,7 @@ public final class MessageQueue {
                if (removeMatches) {
                    if (p.removeFromStack()) {
                        p.mMessage.recycleUnchecked();
                        decAndTraceMessageCount();
                        if (mMessageCounts.incrementCancelled()) {
                            nativeWake(mPtr);
                        }
@@ -2870,6 +2927,7 @@ public final class MessageQueue {
                    found = true;
                    if (queue.remove(msg)) {
                        msg.mMessage.recycleUnchecked();
                        decAndTraceMessageCount();
                    }
                } else {
                    return true;
+7 −1
Original line number Diff line number Diff line
@@ -199,7 +199,12 @@ public final class Looper {
            return false;
        }

        // This must be in a local variable, in case a UI event sets the logger
        PerfettoTrace.begin(PerfettoTrace.MQ_CATEGORY, "message_queue_receive")
                .addArg("sending_thread", msg.mSendingThreadName)
                .addTerminatingFlow(msg.mEventId.get())
                .emit();

        // This must be in a local variabe, in case a UI event sets the logger
        final Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " "
@@ -289,6 +294,7 @@ public final class Looper {
                    + msg.callback + " what=" + msg.what);
        }

        PerfettoTrace.end(PerfettoTrace.MQ_CATEGORY).emit();
        msg.recycleUnchecked();

        return true;
+16 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;

import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * Defines a message containing a description and arbitrary data object that can be
@@ -36,6 +38,13 @@ import com.android.internal.annotations.VisibleForTesting;
 */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class Message implements Parcelable {
    /**
     * For tracing
     *
     * @hide Only for use within the system server.
     */
    public final AtomicInteger mEventId = new AtomicInteger();

    /**
     * User-defined message code so that the recipient can identify
     * what this message is about. Each {@link Handler} has its own name-space
@@ -101,6 +110,13 @@ public final class Message implements Parcelable {
     */
    public int workSourceUid = UID_NONE;

    /**
     * Sending thread
     *
     * @hide
     */
    public String mSendingThreadName;

    /** If set message is in use.
     * This flag is set when the message is enqueued and remains set while it
     * is delivered and afterwards when it is recycled.  The flag is only cleared
+9 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ public final class PerfettoTrace {
     */
    private static final AtomicInteger sFlowEventId = new AtomicInteger();

    public static final PerfettoTrace.Category MQ_CATEGORY = new PerfettoTrace.Category("mq");

    /**
     * Perfetto category a trace event belongs to.
     * Registering a category is not sufficient to capture events within the category, it must
@@ -370,4 +372,11 @@ public final class PerfettoTrace {
    public static void register(boolean isBackendInProcess) {
        native_register(isBackendInProcess);
    }

    /**
     * Registers categories with Perfetto.
     */
    public static void registerCategories() {
        MQ_CATEGORY.register();
    }
}
Loading