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

Commit a7f98d7a authored by Shai Barack's avatar Shai Barack
Browse files

Extract MessageQueue enqueue order to Comparator

This is a step towards storing Message directly in the queue
rather than storing MessageNode, in order to peel an indirection layer
and improve queue performance.

Bug: 415954362
Flag: build.RELEASE_PACKAGE_MESSAGEQUEUE_IMPLEMENTATION
Change-Id: I6f0959d020b8d74fedbb98f77b77a930d3092130
parent f5307871
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ HSPLandroid/graphics/Color;->luminance()F
# to include all hot MessageQueue methods, and the inner classes are profiled
# as well.
HSPLandroid/os/MessageQueue;->*
HSPLandroid/os/MessageQueue$EnqueueOrder;->*
HSPLandroid/os/MessageQueue$FileDescriptorRecord;->*
HSPLandroid/os/MessageQueue$IdleHandler;->*
HSPLandroid/os/MessageQueue$MessageCompare;->*
+1 −0
Original line number Diff line number Diff line
@@ -6602,6 +6602,7 @@ android.os.Looper
android.os.MemoryFile
android.os.Message$1
android.os.Message
android.os.MessageQueue$EnqueueOrder
android.os.MessageQueue$FileDescriptorRecord
android.os.MessageQueue$IdleHandler
android.os.MessageQueue$MatchAllFutureMessages
+1 −0
Original line number Diff line number Diff line
@@ -6607,6 +6607,7 @@ android.os.Looper
android.os.MemoryFile
android.os.Message$1
android.os.Message
android.os.MessageQueue$EnqueueOrder
android.os.MessageQueue$FileDescriptorRecord
android.os.MessageQueue$IdleHandler
android.os.MessageQueue$MatchAllFutureMessages
+38 −23
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentSkipListSet;
@@ -277,6 +278,32 @@ public final class MessageQueue {
        }
    }

    static final class EnqueueOrder implements Comparator<MessageNode> {
        @Override
        public int compare(MessageNode n1, MessageNode n2) {
            return compareMessages(n1.mMessage, n2.mMessage);
        }
    }

    private static final EnqueueOrder sEnqueueOrder = new EnqueueOrder();

    static int compareMessages(@NonNull Message m1, @NonNull Message m2) {
        // Primary queue order is by when.
        // Messages with an earlier when should come first in the queue.
        final long whenDiff = m1.when - m2.when;
        if (whenDiff > 0) return 1;
        if (whenDiff < 0) return -1;

        // Secondary queue order is by insert sequence.
        // If two messages were inserted with the same `when`, the one inserted
        // first should come first in the queue.
        final long insertSeqDiff = m1.insertSeq - m2.insertSeq;
        if (insertSeqDiff > 0) return 1;
        if (insertSeqDiff < 0) return -1;

        return 0;
    }

    static final class MatchDeliverableMessages extends MessageCompare {
        @Override
        public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
@@ -727,7 +754,7 @@ public final class MessageQueue {
                    Log.d(TAG_C, "Next found node"
                            + " what: " + msg.what
                            + " when: " + msg.when
                            + " seq: " + msgNode.mInsertSeq
                            + " seq: " + msgNode.mMessage.insertSeq
                            + " barrier: " + msgNode.isBarrier()
                            + " now: " + now);
                }
@@ -736,7 +763,7 @@ public final class MessageQueue {
                    Log.d(TAG_C, "Next found async node"
                            + " what: " + msg.what
                            + " when: " + msg.when
                            + " seq: " + asyncMsgNode.mInsertSeq
                            + " seq: " + asyncMsgNode.mMessage.insertSeq
                            + " barrier: " + asyncMsgNode.isBarrier()
                            + " now: " + now);
                }
@@ -786,7 +813,7 @@ public final class MessageQueue {
                    Log.d(TAG_C, "Will deliver node"
                            + " what: " + msg.what
                            + " when: " + msg.when
                            + " seq: " + found.mInsertSeq
                            + " seq: " + found.mMessage.insertSeq
                            + " barrier: " + found.isBarrier()
                            + " async: " + found.isAsync()
                            + " now: " + now);
@@ -798,7 +825,7 @@ public final class MessageQueue {
                    Log.d(TAG_C, "Next node"
                            + " what: " + msg.what
                            + " when: " + msg.when
                            + " seq: " + next.mInsertSeq
                            + " seq: " + next.mMessage.insertSeq
                            + " barrier: " + next.isBarrier()
                            + " async: " + next.isAsync()
                            + " now: " + now);
@@ -2183,7 +2210,7 @@ public final class MessageQueue {
            Log.d(TAG_C,
                    "** MessageNode what: " + msgNode.mMessage.what
                    + " when " + msgNode.mMessage.when
                    + " seq: " + msgNode.mInsertSeq);
                    + " seq: " + msgNode.mMessage.insertSeq);
        }
    }

@@ -2422,7 +2449,7 @@ public final class MessageQueue {

    private MessageNode pickEarliestNode(MessageNode nodeA, MessageNode nodeB) {
        if (nodeA != null && nodeB != null) {
            if (nodeA.compareTo(nodeB) < 0) {
            if (compareMessages(nodeA.mMessage, nodeB.mMessage) < 0) {
                return nodeA;
            }
            return nodeB;
@@ -2580,12 +2607,11 @@ public final class MessageQueue {
        }
    }

    static final class MessageNode extends StackNode implements Comparable<MessageNode> {
    static final class MessageNode extends StackNode {
        private final Message mMessage;
        volatile StackNode mNext;
        StateNode mBottomOfStack;
        boolean mWokeUp;
        final long mInsertSeq;
        private static final VarHandle sRemovedFromStack;
        private volatile boolean mRemovedFromStackValue;
        static {
@@ -2602,7 +2628,7 @@ public final class MessageQueue {
        MessageNode(@NonNull Message message, long insertSeq) {
            super(STACK_NODE_MESSAGE);
            mMessage = message;
            mInsertSeq = insertSeq;
            message.insertSeq = insertSeq;
        }

        long getWhen() {
@@ -2620,17 +2646,6 @@ public final class MessageQueue {
        boolean isBarrier() {
            return mMessage.target == null;
        }

        @Override
        public int compareTo(@NonNull MessageNode messageNode) {
            Message other = messageNode.mMessage;

            int compared = Long.compare(mMessage.when, other.when);
            if (compared == 0) {
                compared = Long.compare(mInsertSeq, messageNode.mInsertSeq);
            }
            return compared;
        }
    }

    static class StateNode extends StackNode {
@@ -2656,9 +2671,9 @@ public final class MessageQueue {

    private volatile StackNode mStateValue = sStackStateParked;
    private final ConcurrentSkipListSet<MessageNode> mPriorityQueue =
            new ConcurrentSkipListSet<MessageNode>();
            new ConcurrentSkipListSet<MessageNode>(sEnqueueOrder);
    private final ConcurrentSkipListSet<MessageNode> mAsyncPriorityQueue =
            new ConcurrentSkipListSet<MessageNode>();
            new ConcurrentSkipListSet<MessageNode>(sEnqueueOrder);

    /*
     * This helps us ensure that messages with the same timestamp are inserted in FIFO order.
@@ -2913,7 +2928,7 @@ public final class MessageQueue {
            Log.d(TAG_C, "Insert message"
                    + " what: " + msg.what
                    + " when: " + msg.when
                    + " seq: " + node.mInsertSeq
                    + " seq: " + node.mMessage.insertSeq
                    + " barrier: " + node.isBarrier()
                    + " async: " + node.isAsync()
                    + " now: " + SystemClock.uptimeMillis());
+1 −3
Original line number Diff line number Diff line
@@ -145,9 +145,7 @@ public final class Message implements Parcelable {
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public long when;

    /** @hide */
    @SuppressWarnings("unused")
    public long mInsertSeq;
    /*package*/ long insertSeq;

    /*package*/ Bundle data;