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

Commit 96872593 authored by Frederick Mayle's avatar Frederick Mayle
Browse files

binder: optimize OnewayCallQueueing

    time out/host/linux-x86/nativetest64/binderRpcTestNoKernel/binderRpcTestNoKernel --gtest_filter="*OnewayCallQueueing*"

    before: 1:20.09 total
    after: 49.387 total

All of the time is spent in saturateThreadPool now.

Bug: 271860373
Test: see above
Change-Id: Id41ff1d6e77070c39c656c07be87028011c6e663
parent 04d05a69
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -80,4 +80,8 @@ interface IBinderRpcTest {
    // get queued.
    oneway void blockingSendFdOneway(in ParcelFileDescriptor fd);
    ParcelFileDescriptor blockingRecvFd();

    // Same as blockingSendFdOneway, but with integers.
    oneway void blockingSendIntOneway(int n);
    int blockingRecvInt();
}
+9 −17
Original line number Diff line number Diff line
@@ -584,30 +584,22 @@ TEST_P(BinderRpc, OnewayCallQueueing) {
        GTEST_SKIP() << "This test requires multiple threads";
    }

    constexpr size_t kNumSleeps = 10;
    constexpr size_t kNumQueued = 10;
    constexpr size_t kNumExtraServerThreads = 4;
    constexpr size_t kSleepMs = 50;

    // make sure calls to the same object happen on the same thread
    auto proc = createRpcTestSocketServerProcess({.numThreads = 1 + kNumExtraServerThreads});

    EXPECT_OK(proc.rootIface->lock());

    size_t epochMsBefore = epochMillis();

    // all these *Async commands should be queued on the server sequentially,
    // all these *Oneway commands should be queued on the server sequentially,
    // even though there are multiple threads.
    for (size_t i = 0; i + 1 < kNumSleeps; i++) {
        proc.rootIface->sleepMsAsync(kSleepMs);
    for (size_t i = 0; i + 1 < kNumQueued; i++) {
        proc.rootIface->blockingSendIntOneway(i);
    }
    for (size_t i = 0; i + 1 < kNumQueued; i++) {
        int n;
        proc.rootIface->blockingRecvInt(&n);
        EXPECT_EQ(n, i);
    }
    EXPECT_OK(proc.rootIface->unlockInMsAsync(kSleepMs));

    // this can only return once the final async call has unlocked
    EXPECT_OK(proc.rootIface->lockUnlock());

    size_t epochMsAfter = epochMillis();

    EXPECT_GE(epochMsAfter, epochMsBefore + kSleepMs * kNumSleeps);

    saturateThreadPool(1 + kNumExtraServerThreads, proc.rootIface);
}
+6 −0
Original line number Diff line number Diff line
@@ -445,6 +445,12 @@ public:
    Status blockingRecvFd(android::os::ParcelFileDescriptor* /*fd*/) override {
        return Status::fromStatusT(UNKNOWN_TRANSACTION);
    }

    Status blockingSendIntOneway(int /*n*/) override {
        return Status::fromStatusT(UNKNOWN_TRANSACTION);
    }

    Status blockingRecvInt(int* /*n*/) override { return Status::fromStatusT(UNKNOWN_TRANSACTION); }
};

} // namespace android
+12 −0
Original line number Diff line number Diff line
@@ -83,6 +83,18 @@ public:
        fd->reset(mFdChannel.read());
        return Status::ok();
    }

    HandoffChannel<int> mIntChannel;

    Status blockingSendIntOneway(int n) override {
        mIntChannel.write(n);
        return Status::ok();
    }

    Status blockingRecvInt(int* n) override {
        *n = mIntChannel.read();
        return Status::ok();
    }
};

int main(int argc, char* argv[]) {