xref: /aosp_15_r20/hardware/interfaces/tests/msgq/1.0/default/BenchmarkMsgQ.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #include "BenchmarkMsgQ.h"
18*4d7e907cSAndroid Build Coastguard Worker #include <iostream>
19*4d7e907cSAndroid Build Coastguard Worker #include <thread>
20*4d7e907cSAndroid Build Coastguard Worker #include <fmq/MessageQueue.h>
21*4d7e907cSAndroid Build Coastguard Worker 
22*4d7e907cSAndroid Build Coastguard Worker namespace android {
23*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
24*4d7e907cSAndroid Build Coastguard Worker namespace tests {
25*4d7e907cSAndroid Build Coastguard Worker namespace msgq {
26*4d7e907cSAndroid Build Coastguard Worker namespace V1_0 {
27*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
28*4d7e907cSAndroid Build Coastguard Worker 
29*4d7e907cSAndroid Build Coastguard Worker // Methods from ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ follow.
configureClientInboxSyncReadWrite(configureClientInboxSyncReadWrite_cb _hidl_cb)30*4d7e907cSAndroid Build Coastguard Worker Return<void> BenchmarkMsgQ::configureClientInboxSyncReadWrite(
31*4d7e907cSAndroid Build Coastguard Worker         configureClientInboxSyncReadWrite_cb _hidl_cb) {
32*4d7e907cSAndroid Build Coastguard Worker     static constexpr size_t kNumElementsInQueue = 16 * 1024;
33*4d7e907cSAndroid Build Coastguard Worker     mFmqOutbox = new (std::nothrow) android::hardware::MessageQueue<uint8_t,
34*4d7e907cSAndroid Build Coastguard Worker                kSynchronizedReadWrite>(kNumElementsInQueue);
35*4d7e907cSAndroid Build Coastguard Worker     if (mFmqOutbox == nullptr) {
36*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(false /* ret */, android::hardware::MQDescriptorSync<uint8_t>(
37*4d7e907cSAndroid Build Coastguard Worker                 std::vector<android::hardware::GrantorDescriptor>(),
38*4d7e907cSAndroid Build Coastguard Worker                 nullptr /* nhandle */, 0 /* size */));
39*4d7e907cSAndroid Build Coastguard Worker     } else {
40*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(true /* ret */, *mFmqOutbox->getDesc());
41*4d7e907cSAndroid Build Coastguard Worker     }
42*4d7e907cSAndroid Build Coastguard Worker 
43*4d7e907cSAndroid Build Coastguard Worker     return Void();
44*4d7e907cSAndroid Build Coastguard Worker }
45*4d7e907cSAndroid Build Coastguard Worker 
configureClientOutboxSyncReadWrite(configureClientOutboxSyncReadWrite_cb _hidl_cb)46*4d7e907cSAndroid Build Coastguard Worker Return<void> BenchmarkMsgQ::configureClientOutboxSyncReadWrite(
47*4d7e907cSAndroid Build Coastguard Worker         configureClientOutboxSyncReadWrite_cb _hidl_cb) {
48*4d7e907cSAndroid Build Coastguard Worker     static constexpr size_t kNumElementsInQueue = 16 * 1024;
49*4d7e907cSAndroid Build Coastguard Worker     mFmqInbox = new (std::nothrow) android::hardware::MessageQueue<uint8_t,
50*4d7e907cSAndroid Build Coastguard Worker               kSynchronizedReadWrite>(kNumElementsInQueue);
51*4d7e907cSAndroid Build Coastguard Worker     if ((mFmqInbox == nullptr) || (mFmqInbox->isValid() == false)) {
52*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(false /* ret */, android::hardware::MQDescriptorSync<uint8_t>(
53*4d7e907cSAndroid Build Coastguard Worker                 std::vector<android::hardware::GrantorDescriptor>(),
54*4d7e907cSAndroid Build Coastguard Worker                 nullptr /* nhandle */, 0 /* size */));
55*4d7e907cSAndroid Build Coastguard Worker     } else {
56*4d7e907cSAndroid Build Coastguard Worker         _hidl_cb(true /* ret */, *mFmqInbox->getDesc());
57*4d7e907cSAndroid Build Coastguard Worker     }
58*4d7e907cSAndroid Build Coastguard Worker 
59*4d7e907cSAndroid Build Coastguard Worker     return Void();
60*4d7e907cSAndroid Build Coastguard Worker }
61*4d7e907cSAndroid Build Coastguard Worker 
requestWrite(int32_t count)62*4d7e907cSAndroid Build Coastguard Worker Return<bool> BenchmarkMsgQ::requestWrite(int32_t count) {
63*4d7e907cSAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[count];
64*4d7e907cSAndroid Build Coastguard Worker     for (int i = 0; i < count; i++) {
65*4d7e907cSAndroid Build Coastguard Worker         data[i] = i;
66*4d7e907cSAndroid Build Coastguard Worker     }
67*4d7e907cSAndroid Build Coastguard Worker     bool result = mFmqOutbox->write(data, count);
68*4d7e907cSAndroid Build Coastguard Worker     delete[] data;
69*4d7e907cSAndroid Build Coastguard Worker     return result;
70*4d7e907cSAndroid Build Coastguard Worker }
71*4d7e907cSAndroid Build Coastguard Worker 
requestRead(int32_t count)72*4d7e907cSAndroid Build Coastguard Worker Return<bool> BenchmarkMsgQ::requestRead(int32_t count) {
73*4d7e907cSAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[count];
74*4d7e907cSAndroid Build Coastguard Worker     bool result = mFmqInbox->read(data, count);
75*4d7e907cSAndroid Build Coastguard Worker     delete[] data;
76*4d7e907cSAndroid Build Coastguard Worker     return result;
77*4d7e907cSAndroid Build Coastguard Worker }
78*4d7e907cSAndroid Build Coastguard Worker 
benchmarkPingPong(uint32_t numIter)79*4d7e907cSAndroid Build Coastguard Worker Return<void> BenchmarkMsgQ::benchmarkPingPong(uint32_t numIter) {
80*4d7e907cSAndroid Build Coastguard Worker     std::thread(QueuePairReadWrite<kSynchronizedReadWrite>, mFmqInbox,
81*4d7e907cSAndroid Build Coastguard Worker                 mFmqOutbox, numIter)
82*4d7e907cSAndroid Build Coastguard Worker             .detach();
83*4d7e907cSAndroid Build Coastguard Worker     return Void();
84*4d7e907cSAndroid Build Coastguard Worker }
85*4d7e907cSAndroid Build Coastguard Worker 
benchmarkServiceWriteClientRead(uint32_t numIter)86*4d7e907cSAndroid Build Coastguard Worker Return<void> BenchmarkMsgQ::benchmarkServiceWriteClientRead(uint32_t numIter) {
87*4d7e907cSAndroid Build Coastguard Worker     if (mTimeData) delete[] mTimeData;
88*4d7e907cSAndroid Build Coastguard Worker     mTimeData = new (std::nothrow) int64_t[numIter];
89*4d7e907cSAndroid Build Coastguard Worker     std::thread(QueueWriter<kSynchronizedReadWrite>, mFmqOutbox,
90*4d7e907cSAndroid Build Coastguard Worker                 mTimeData, numIter).detach();
91*4d7e907cSAndroid Build Coastguard Worker     return Void();
92*4d7e907cSAndroid Build Coastguard Worker }
93*4d7e907cSAndroid Build Coastguard Worker 
sendTimeData(const hidl_vec<int64_t> & clientRcvTimeArray)94*4d7e907cSAndroid Build Coastguard Worker Return<void> BenchmarkMsgQ::sendTimeData(const hidl_vec<int64_t>& clientRcvTimeArray) {
95*4d7e907cSAndroid Build Coastguard Worker     int64_t accumulatedTime = 0;
96*4d7e907cSAndroid Build Coastguard Worker 
97*4d7e907cSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < clientRcvTimeArray.size(); i++) {
98*4d7e907cSAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock>
99*4d7e907cSAndroid Build Coastguard Worker                 clientRcvTime((std::chrono::high_resolution_clock::duration(
100*4d7e907cSAndroid Build Coastguard Worker                         clientRcvTimeArray[i])));
101*4d7e907cSAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock>serverSendTime(
102*4d7e907cSAndroid Build Coastguard Worker                 (std::chrono::high_resolution_clock::duration(mTimeData[i])));
103*4d7e907cSAndroid Build Coastguard Worker         accumulatedTime += static_cast<int64_t>(
104*4d7e907cSAndroid Build Coastguard Worker                 std::chrono::duration_cast<std::chrono::nanoseconds>(clientRcvTime -
105*4d7e907cSAndroid Build Coastguard Worker                                                                      serverSendTime).count());
106*4d7e907cSAndroid Build Coastguard Worker     }
107*4d7e907cSAndroid Build Coastguard Worker 
108*4d7e907cSAndroid Build Coastguard Worker     accumulatedTime /= clientRcvTimeArray.size();
109*4d7e907cSAndroid Build Coastguard Worker     std::cout << "Average service to client write to read delay::"
110*4d7e907cSAndroid Build Coastguard Worker          << accumulatedTime << "ns" << std::endl;
111*4d7e907cSAndroid Build Coastguard Worker     return Void();
112*4d7e907cSAndroid Build Coastguard Worker }
113*4d7e907cSAndroid Build Coastguard Worker 
114*4d7e907cSAndroid Build Coastguard Worker template <MQFlavor flavor>
QueueWriter(android::hardware::MessageQueue<uint8_t,flavor> * mFmqOutbox,int64_t * mTimeData,uint32_t numIter)115*4d7e907cSAndroid Build Coastguard Worker void BenchmarkMsgQ::QueueWriter(android::hardware::MessageQueue<uint8_t, flavor>* mFmqOutbox,
116*4d7e907cSAndroid Build Coastguard Worker                                 int64_t* mTimeData,
117*4d7e907cSAndroid Build Coastguard Worker                                 uint32_t numIter) {
118*4d7e907cSAndroid Build Coastguard Worker     uint8_t data[kPacketSize64];
119*4d7e907cSAndroid Build Coastguard Worker     uint32_t numWrites = 0;
120*4d7e907cSAndroid Build Coastguard Worker 
121*4d7e907cSAndroid Build Coastguard Worker     while (numWrites < numIter) {
122*4d7e907cSAndroid Build Coastguard Worker         do {
123*4d7e907cSAndroid Build Coastguard Worker             mTimeData[numWrites] =
124*4d7e907cSAndroid Build Coastguard Worker                     std::chrono::high_resolution_clock::now().time_since_epoch().count();
125*4d7e907cSAndroid Build Coastguard Worker         } while (mFmqOutbox->write(data, kPacketSize64) == false);
126*4d7e907cSAndroid Build Coastguard Worker         numWrites++;
127*4d7e907cSAndroid Build Coastguard Worker     }
128*4d7e907cSAndroid Build Coastguard Worker }
129*4d7e907cSAndroid Build Coastguard Worker 
130*4d7e907cSAndroid Build Coastguard Worker template <MQFlavor flavor>
QueuePairReadWrite(android::hardware::MessageQueue<uint8_t,flavor> * mFmqInbox,android::hardware::MessageQueue<uint8_t,flavor> * mFmqOutbox,uint32_t numIter)131*4d7e907cSAndroid Build Coastguard Worker void BenchmarkMsgQ::QueuePairReadWrite(
132*4d7e907cSAndroid Build Coastguard Worker         android::hardware::MessageQueue<uint8_t, flavor>* mFmqInbox,
133*4d7e907cSAndroid Build Coastguard Worker         android::hardware::MessageQueue<uint8_t, flavor>* mFmqOutbox,
134*4d7e907cSAndroid Build Coastguard Worker         uint32_t numIter) {
135*4d7e907cSAndroid Build Coastguard Worker     uint8_t data[kPacketSize64];
136*4d7e907cSAndroid Build Coastguard Worker     uint32_t numRoundTrips = 0;
137*4d7e907cSAndroid Build Coastguard Worker 
138*4d7e907cSAndroid Build Coastguard Worker     while (numRoundTrips < numIter) {
139*4d7e907cSAndroid Build Coastguard Worker         while (mFmqInbox->read(data, kPacketSize64) == false)
140*4d7e907cSAndroid Build Coastguard Worker             ;
141*4d7e907cSAndroid Build Coastguard Worker         while (mFmqOutbox->write(data, kPacketSize64) == false)
142*4d7e907cSAndroid Build Coastguard Worker             ;
143*4d7e907cSAndroid Build Coastguard Worker         numRoundTrips++;
144*4d7e907cSAndroid Build Coastguard Worker     }
145*4d7e907cSAndroid Build Coastguard Worker }
146*4d7e907cSAndroid Build Coastguard Worker 
HIDL_FETCH_IBenchmarkMsgQ(const char *)147*4d7e907cSAndroid Build Coastguard Worker IBenchmarkMsgQ* HIDL_FETCH_IBenchmarkMsgQ(const char* /* name */) {
148*4d7e907cSAndroid Build Coastguard Worker     return new BenchmarkMsgQ();
149*4d7e907cSAndroid Build Coastguard Worker }
150*4d7e907cSAndroid Build Coastguard Worker 
151*4d7e907cSAndroid Build Coastguard Worker }  // namespace implementation
152*4d7e907cSAndroid Build Coastguard Worker }  // namespace V1_0
153*4d7e907cSAndroid Build Coastguard Worker }  // namespace msgq
154*4d7e907cSAndroid Build Coastguard Worker }  // namespace tests
155*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
156*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
157