xref: /aosp_15_r20/system/libfmq/benchmarks/msgq_benchmark_client.cpp (revision be431cd81a9a2349eaea34eb56fcf6d1608da596)
1*be431cd8SAndroid Build Coastguard Worker /*
2*be431cd8SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*be431cd8SAndroid Build Coastguard Worker *
4*be431cd8SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*be431cd8SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*be431cd8SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*be431cd8SAndroid Build Coastguard Worker *
8*be431cd8SAndroid Build Coastguard Worker *      http://www.apache.org/licenses/LICENSE-2.0
9*be431cd8SAndroid Build Coastguard Worker *
10*be431cd8SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*be431cd8SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*be431cd8SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*be431cd8SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*be431cd8SAndroid Build Coastguard Worker * limitations under the License.
15*be431cd8SAndroid Build Coastguard Worker */
16*be431cd8SAndroid Build Coastguard Worker 
17*be431cd8SAndroid Build Coastguard Worker #include <android-base/logging.h>
18*be431cd8SAndroid Build Coastguard Worker 
19*be431cd8SAndroid Build Coastguard Worker #include <gtest/gtest.h>
20*be431cd8SAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
21*be431cd8SAndroid Build Coastguard Worker #include <chrono>
22*be431cd8SAndroid Build Coastguard Worker #include <iostream>
23*be431cd8SAndroid Build Coastguard Worker 
24*be431cd8SAndroid Build Coastguard Worker #include <android/hardware/tests/msgq/1.0/IBenchmarkMsgQ.h>
25*be431cd8SAndroid Build Coastguard Worker #include <fmq/MessageQueue.h>
26*be431cd8SAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
27*be431cd8SAndroid Build Coastguard Worker 
28*be431cd8SAndroid Build Coastguard Worker // libutils:
29*be431cd8SAndroid Build Coastguard Worker using android::OK;
30*be431cd8SAndroid Build Coastguard Worker using android::sp;
31*be431cd8SAndroid Build Coastguard Worker using android::status_t;
32*be431cd8SAndroid Build Coastguard Worker 
33*be431cd8SAndroid Build Coastguard Worker // generated
34*be431cd8SAndroid Build Coastguard Worker using android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ;
35*be431cd8SAndroid Build Coastguard Worker using std::cerr;
36*be431cd8SAndroid Build Coastguard Worker using std::cout;
37*be431cd8SAndroid Build Coastguard Worker using std::endl;
38*be431cd8SAndroid Build Coastguard Worker 
39*be431cd8SAndroid Build Coastguard Worker // libhidl
40*be431cd8SAndroid Build Coastguard Worker using android::hardware::kSynchronizedReadWrite;
41*be431cd8SAndroid Build Coastguard Worker using android::hardware::MQDescriptorSync;
42*be431cd8SAndroid Build Coastguard Worker using android::hardware::MessageQueue;
43*be431cd8SAndroid Build Coastguard Worker using android::hardware::details::waitForHwService;
44*be431cd8SAndroid Build Coastguard Worker 
45*be431cd8SAndroid Build Coastguard Worker /*
46*be431cd8SAndroid Build Coastguard Worker  * All the benchmark cases will be performed on an FMQ of size kQueueSize.
47*be431cd8SAndroid Build Coastguard Worker  */
48*be431cd8SAndroid Build Coastguard Worker static const int32_t kQueueSize = 1024 * 16;
49*be431cd8SAndroid Build Coastguard Worker 
50*be431cd8SAndroid Build Coastguard Worker /*
51*be431cd8SAndroid Build Coastguard Worker  * The number of iterations for each experiment.
52*be431cd8SAndroid Build Coastguard Worker  */
53*be431cd8SAndroid Build Coastguard Worker static const uint32_t kNumIterations = 1000;
54*be431cd8SAndroid Build Coastguard Worker 
55*be431cd8SAndroid Build Coastguard Worker /*
56*be431cd8SAndroid Build Coastguard Worker  * The various packet sizes used are as follows.
57*be431cd8SAndroid Build Coastguard Worker  */
58*be431cd8SAndroid Build Coastguard Worker enum PacketSizes {
59*be431cd8SAndroid Build Coastguard Worker     kPacketSize64 = 64,
60*be431cd8SAndroid Build Coastguard Worker     kPacketSize128 = 128,
61*be431cd8SAndroid Build Coastguard Worker     kPacketSize256 = 256,
62*be431cd8SAndroid Build Coastguard Worker     kPacketSize512 = 512,
63*be431cd8SAndroid Build Coastguard Worker     kPacketSize1024 = 1024
64*be431cd8SAndroid Build Coastguard Worker };
65*be431cd8SAndroid Build Coastguard Worker 
66*be431cd8SAndroid Build Coastguard Worker class MQTestClient : public ::testing::Test {
67*be431cd8SAndroid Build Coastguard Worker protected:
TearDown()68*be431cd8SAndroid Build Coastguard Worker     virtual void TearDown() {
69*be431cd8SAndroid Build Coastguard Worker         delete mFmqInbox;
70*be431cd8SAndroid Build Coastguard Worker         delete mFmqOutbox;
71*be431cd8SAndroid Build Coastguard Worker     }
72*be431cd8SAndroid Build Coastguard Worker 
SetUp()73*be431cd8SAndroid Build Coastguard Worker     virtual void SetUp() {
74*be431cd8SAndroid Build Coastguard Worker         // waitForHwService is required because IBenchmarkMsgQ is not in manifest.xml.
75*be431cd8SAndroid Build Coastguard Worker         // "Real" HALs shouldn't be doing this.
76*be431cd8SAndroid Build Coastguard Worker         waitForHwService(IBenchmarkMsgQ::descriptor, "default");
77*be431cd8SAndroid Build Coastguard Worker         service = IBenchmarkMsgQ::getService();
78*be431cd8SAndroid Build Coastguard Worker         ASSERT_NE(service, nullptr);
79*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(service->isRemote());
80*be431cd8SAndroid Build Coastguard Worker         /*
81*be431cd8SAndroid Build Coastguard Worker          * Request service to configure the client inbox queue.
82*be431cd8SAndroid Build Coastguard Worker          */
83*be431cd8SAndroid Build Coastguard Worker         service->configureClientInboxSyncReadWrite([this](bool ret,
84*be431cd8SAndroid Build Coastguard Worker                                                           const MQDescriptorSync<uint8_t>& in) {
85*be431cd8SAndroid Build Coastguard Worker           ASSERT_TRUE(ret);
86*be431cd8SAndroid Build Coastguard Worker           mFmqInbox = new (std::nothrow) MessageQueue<uint8_t, kSynchronizedReadWrite>(in);
87*be431cd8SAndroid Build Coastguard Worker         });
88*be431cd8SAndroid Build Coastguard Worker 
89*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(mFmqInbox != nullptr);
90*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(mFmqInbox->isValid());
91*be431cd8SAndroid Build Coastguard Worker         /*
92*be431cd8SAndroid Build Coastguard Worker          * Reqeust service to configure the client outbox queue.
93*be431cd8SAndroid Build Coastguard Worker          */
94*be431cd8SAndroid Build Coastguard Worker         service->configureClientOutboxSyncReadWrite([this](bool ret,
95*be431cd8SAndroid Build Coastguard Worker                                                            const MQDescriptorSync<uint8_t>& out) {
96*be431cd8SAndroid Build Coastguard Worker          ASSERT_TRUE(ret);
97*be431cd8SAndroid Build Coastguard Worker           mFmqOutbox = new (std::nothrow) MessageQueue<uint8_t,
98*be431cd8SAndroid Build Coastguard Worker                              kSynchronizedReadWrite>(out);
99*be431cd8SAndroid Build Coastguard Worker         });
100*be431cd8SAndroid Build Coastguard Worker 
101*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(mFmqOutbox != nullptr);
102*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(mFmqOutbox->isValid());
103*be431cd8SAndroid Build Coastguard Worker     }
104*be431cd8SAndroid Build Coastguard Worker 
105*be431cd8SAndroid Build Coastguard Worker     sp<IBenchmarkMsgQ> service;
106*be431cd8SAndroid Build Coastguard Worker     android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite>* mFmqInbox = nullptr;
107*be431cd8SAndroid Build Coastguard Worker     android::hardware::MessageQueue<uint8_t, kSynchronizedReadWrite>* mFmqOutbox = nullptr;
108*be431cd8SAndroid Build Coastguard Worker };
109*be431cd8SAndroid Build Coastguard Worker 
110*be431cd8SAndroid Build Coastguard Worker /*
111*be431cd8SAndroid Build Coastguard Worker  * Client writes a 64 byte packet into the outbox queue, service reads the
112*be431cd8SAndroid Build Coastguard Worker  * same and
113*be431cd8SAndroid Build Coastguard Worker  * writes the packet into the client's inbox queue. Client reads the packet. The
114*be431cd8SAndroid Build Coastguard Worker  * average time taken for the cycle is measured.
115*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasurePingPongTransfer)116*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasurePingPongTransfer) {
117*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize64];
118*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
119*be431cd8SAndroid Build Coastguard Worker     int64_t accumulatedTime = 0;
120*be431cd8SAndroid Build Coastguard Worker     size_t numRoundTrips = 0;
121*be431cd8SAndroid Build Coastguard Worker 
122*be431cd8SAndroid Build Coastguard Worker     /*
123*be431cd8SAndroid Build Coastguard Worker      * This method requests the service to create a thread which reads
124*be431cd8SAndroid Build Coastguard Worker      * from mFmqOutbox and writes into mFmqInbox.
125*be431cd8SAndroid Build Coastguard Worker      */
126*be431cd8SAndroid Build Coastguard Worker     service->benchmarkPingPong(kNumIterations);
127*be431cd8SAndroid Build Coastguard Worker     std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
128*be431cd8SAndroid Build Coastguard Worker             std::chrono::high_resolution_clock::now();
129*be431cd8SAndroid Build Coastguard Worker     while (numRoundTrips < kNumIterations) {
130*be431cd8SAndroid Build Coastguard Worker         while (mFmqOutbox->write(data, kPacketSize64) == 0) {
131*be431cd8SAndroid Build Coastguard Worker         }
132*be431cd8SAndroid Build Coastguard Worker 
133*be431cd8SAndroid Build Coastguard Worker         while (mFmqInbox->read(data, kPacketSize64) == 0) {
134*be431cd8SAndroid Build Coastguard Worker         }
135*be431cd8SAndroid Build Coastguard Worker 
136*be431cd8SAndroid Build Coastguard Worker         numRoundTrips++;
137*be431cd8SAndroid Build Coastguard Worker     }
138*be431cd8SAndroid Build Coastguard Worker     std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
139*be431cd8SAndroid Build Coastguard Worker             std::chrono::high_resolution_clock::now();
140*be431cd8SAndroid Build Coastguard Worker     accumulatedTime += static_cast<int64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
141*be431cd8SAndroid Build Coastguard Worker             timeEnd - timeStart).count());
142*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= kNumIterations;
143*be431cd8SAndroid Build Coastguard Worker 
144*be431cd8SAndroid Build Coastguard Worker     cout << "Round trip time for " << kPacketSize64 << "bytes: " <<
145*be431cd8SAndroid Build Coastguard Worker          accumulatedTime << "ns" << endl;
146*be431cd8SAndroid Build Coastguard Worker     delete[] data;
147*be431cd8SAndroid Build Coastguard Worker }
148*be431cd8SAndroid Build Coastguard Worker 
149*be431cd8SAndroid Build Coastguard Worker /*
150*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to read 64 bytes from the queue.
151*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureRead64Bytes)152*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureRead64Bytes) {
153*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize64];
154*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
155*be431cd8SAndroid Build Coastguard Worker 
156*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize64;
157*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
158*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
159*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestWrite(kQueueSize);
160*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
161*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
162*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
163*be431cd8SAndroid Build Coastguard Worker         /*
164*be431cd8SAndroid Build Coastguard Worker          * The read() method returns true only if the the correct number of bytes
165*be431cd8SAndroid Build Coastguard Worker          * were succesfully read from the queue.
166*be431cd8SAndroid Build Coastguard Worker          */
167*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
168*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqInbox->read(data, kPacketSize64));
169*be431cd8SAndroid Build Coastguard Worker         }
170*be431cd8SAndroid Build Coastguard Worker 
171*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
172*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
173*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
174*be431cd8SAndroid Build Coastguard Worker     }
175*be431cd8SAndroid Build Coastguard Worker 
176*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
177*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to read" << kPacketSize64
178*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
179*be431cd8SAndroid Build Coastguard Worker     delete[] data;
180*be431cd8SAndroid Build Coastguard Worker }
181*be431cd8SAndroid Build Coastguard Worker 
182*be431cd8SAndroid Build Coastguard Worker /*
183*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to read 128 bytes.
184*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureRead128Bytes)185*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureRead128Bytes) {
186*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize128];
187*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
188*be431cd8SAndroid Build Coastguard Worker 
189*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize128;
190*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
191*be431cd8SAndroid Build Coastguard Worker 
192*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
193*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestWrite(kQueueSize);
194*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
195*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
196*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
197*be431cd8SAndroid Build Coastguard Worker 
198*be431cd8SAndroid Build Coastguard Worker         /*
199*be431cd8SAndroid Build Coastguard Worker          * The read() method returns true only if the the correct number of bytes
200*be431cd8SAndroid Build Coastguard Worker          * were succesfully read from the queue.
201*be431cd8SAndroid Build Coastguard Worker          */
202*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
203*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqInbox->read(data, kPacketSize128));
204*be431cd8SAndroid Build Coastguard Worker         }
205*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
206*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
207*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
208*be431cd8SAndroid Build Coastguard Worker     }
209*be431cd8SAndroid Build Coastguard Worker 
210*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
211*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to read" << kPacketSize128
212*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
213*be431cd8SAndroid Build Coastguard Worker     delete[] data;
214*be431cd8SAndroid Build Coastguard Worker }
215*be431cd8SAndroid Build Coastguard Worker 
216*be431cd8SAndroid Build Coastguard Worker /*
217*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to read 256 bytes from the queue.
218*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureRead256Bytes)219*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureRead256Bytes) {
220*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize256];
221*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
222*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize256;
223*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
224*be431cd8SAndroid Build Coastguard Worker 
225*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
226*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestWrite(kQueueSize);
227*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
228*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
229*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
230*be431cd8SAndroid Build Coastguard Worker         /*
231*be431cd8SAndroid Build Coastguard Worker          * The read() method returns true only if the the correct number of bytes
232*be431cd8SAndroid Build Coastguard Worker          * were succesfully read from the queue.
233*be431cd8SAndroid Build Coastguard Worker          */
234*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
235*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqInbox->read(data, kPacketSize256));
236*be431cd8SAndroid Build Coastguard Worker         }
237*be431cd8SAndroid Build Coastguard Worker 
238*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
239*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
240*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
241*be431cd8SAndroid Build Coastguard Worker     }
242*be431cd8SAndroid Build Coastguard Worker 
243*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
244*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to read" << kPacketSize256
245*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
246*be431cd8SAndroid Build Coastguard Worker     delete[] data;
247*be431cd8SAndroid Build Coastguard Worker }
248*be431cd8SAndroid Build Coastguard Worker 
249*be431cd8SAndroid Build Coastguard Worker /*
250*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to read 512 bytes from the queue.
251*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureRead512Bytes)252*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureRead512Bytes) {
253*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize512];
254*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
255*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize512;
256*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
257*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
258*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestWrite(kQueueSize);
259*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
260*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
261*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
262*be431cd8SAndroid Build Coastguard Worker         /*
263*be431cd8SAndroid Build Coastguard Worker          * The read() method returns true only if the the correct number of bytes
264*be431cd8SAndroid Build Coastguard Worker          * were succesfully read from the queue.
265*be431cd8SAndroid Build Coastguard Worker          */
266*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
267*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqInbox->read(data, kPacketSize512));
268*be431cd8SAndroid Build Coastguard Worker         }
269*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
270*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
271*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
272*be431cd8SAndroid Build Coastguard Worker     }
273*be431cd8SAndroid Build Coastguard Worker 
274*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
275*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to read" << kPacketSize512
276*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
277*be431cd8SAndroid Build Coastguard Worker     delete[] data;
278*be431cd8SAndroid Build Coastguard Worker }
279*be431cd8SAndroid Build Coastguard Worker 
280*be431cd8SAndroid Build Coastguard Worker /*
281*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to write 64 bytes into the queue.
282*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureWrite64Bytes)283*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureWrite64Bytes) {
284*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize64];
285*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
286*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize64;
287*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
288*be431cd8SAndroid Build Coastguard Worker 
289*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
290*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
291*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
292*be431cd8SAndroid Build Coastguard Worker         /*
293*be431cd8SAndroid Build Coastguard Worker          * Write until the queue is full and request service to empty the queue.
294*be431cd8SAndroid Build Coastguard Worker          */
295*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
296*be431cd8SAndroid Build Coastguard Worker             bool result = mFmqOutbox->write(data, kPacketSize64);
297*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(result);
298*be431cd8SAndroid Build Coastguard Worker         }
299*be431cd8SAndroid Build Coastguard Worker 
300*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
301*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
302*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
303*be431cd8SAndroid Build Coastguard Worker 
304*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestRead(kQueueSize);
305*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
306*be431cd8SAndroid Build Coastguard Worker     }
307*be431cd8SAndroid Build Coastguard Worker 
308*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
309*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to write " << kPacketSize64
310*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
311*be431cd8SAndroid Build Coastguard Worker     delete[] data;
312*be431cd8SAndroid Build Coastguard Worker }
313*be431cd8SAndroid Build Coastguard Worker 
314*be431cd8SAndroid Build Coastguard Worker /*
315*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to write 128 bytes into the queue.
316*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureWrite128Bytes)317*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureWrite128Bytes) {
318*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize128];
319*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
320*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize128;
321*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
322*be431cd8SAndroid Build Coastguard Worker 
323*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
324*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
325*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
326*be431cd8SAndroid Build Coastguard Worker         /*
327*be431cd8SAndroid Build Coastguard Worker          * Write until the queue is full and request service to empty the queue.
328*be431cd8SAndroid Build Coastguard Worker          */
329*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
330*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqOutbox->write(data, kPacketSize128));
331*be431cd8SAndroid Build Coastguard Worker         }
332*be431cd8SAndroid Build Coastguard Worker 
333*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
334*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
335*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
336*be431cd8SAndroid Build Coastguard Worker 
337*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestRead(kQueueSize);
338*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
339*be431cd8SAndroid Build Coastguard Worker     }
340*be431cd8SAndroid Build Coastguard Worker 
341*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
342*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to write " << kPacketSize128
343*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
344*be431cd8SAndroid Build Coastguard Worker     delete[] data;
345*be431cd8SAndroid Build Coastguard Worker }
346*be431cd8SAndroid Build Coastguard Worker 
347*be431cd8SAndroid Build Coastguard Worker /*
348*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to write 256 bytes into the queue.
349*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureWrite256Bytes)350*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureWrite256Bytes) {
351*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize256];
352*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
353*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize256;
354*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
355*be431cd8SAndroid Build Coastguard Worker 
356*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
357*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
358*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
359*be431cd8SAndroid Build Coastguard Worker         /*
360*be431cd8SAndroid Build Coastguard Worker          * Write until the queue is full and request service to empty the queue.
361*be431cd8SAndroid Build Coastguard Worker          */
362*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
363*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqOutbox->write(data, kPacketSize256));
364*be431cd8SAndroid Build Coastguard Worker         }
365*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
366*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
367*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
368*be431cd8SAndroid Build Coastguard Worker 
369*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestRead(kQueueSize);
370*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
371*be431cd8SAndroid Build Coastguard Worker     }
372*be431cd8SAndroid Build Coastguard Worker 
373*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
374*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to write " << kPacketSize256
375*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
376*be431cd8SAndroid Build Coastguard Worker     delete[] data;
377*be431cd8SAndroid Build Coastguard Worker }
378*be431cd8SAndroid Build Coastguard Worker 
379*be431cd8SAndroid Build Coastguard Worker /*
380*be431cd8SAndroid Build Coastguard Worker  * Measure the average time taken to write 512 bytes into the queue.
381*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureWrite512Bytes)382*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureWrite512Bytes) {
383*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize512];
384*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
385*be431cd8SAndroid Build Coastguard Worker     uint32_t numLoops = kQueueSize / kPacketSize512;
386*be431cd8SAndroid Build Coastguard Worker     uint64_t accumulatedTime = 0;
387*be431cd8SAndroid Build Coastguard Worker 
388*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
389*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeStart =
390*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
391*be431cd8SAndroid Build Coastguard Worker 
392*be431cd8SAndroid Build Coastguard Worker         /*
393*be431cd8SAndroid Build Coastguard Worker          * Write until the queue is full and request service to empty the queue.
394*be431cd8SAndroid Build Coastguard Worker          * The write() method returns true only if the specified number of bytes
395*be431cd8SAndroid Build Coastguard Worker          * were succesfully written.
396*be431cd8SAndroid Build Coastguard Worker          */
397*be431cd8SAndroid Build Coastguard Worker         for (uint32_t j = 0; j < numLoops; j++) {
398*be431cd8SAndroid Build Coastguard Worker             ASSERT_TRUE(mFmqOutbox->write(data, kPacketSize512));
399*be431cd8SAndroid Build Coastguard Worker         }
400*be431cd8SAndroid Build Coastguard Worker 
401*be431cd8SAndroid Build Coastguard Worker         std::chrono::time_point<std::chrono::high_resolution_clock> timeEnd =
402*be431cd8SAndroid Build Coastguard Worker                 std::chrono::high_resolution_clock::now();
403*be431cd8SAndroid Build Coastguard Worker         accumulatedTime += (timeEnd - timeStart).count();
404*be431cd8SAndroid Build Coastguard Worker 
405*be431cd8SAndroid Build Coastguard Worker         bool ret = service->requestRead(kQueueSize);
406*be431cd8SAndroid Build Coastguard Worker         ASSERT_TRUE(ret);
407*be431cd8SAndroid Build Coastguard Worker     }
408*be431cd8SAndroid Build Coastguard Worker 
409*be431cd8SAndroid Build Coastguard Worker     accumulatedTime /= (numLoops * kNumIterations);
410*be431cd8SAndroid Build Coastguard Worker     cout << "Average time to write " << kPacketSize512
411*be431cd8SAndroid Build Coastguard Worker          << "bytes: " << accumulatedTime << "ns" << endl;
412*be431cd8SAndroid Build Coastguard Worker     delete[] data;
413*be431cd8SAndroid Build Coastguard Worker }
414*be431cd8SAndroid Build Coastguard Worker 
415*be431cd8SAndroid Build Coastguard Worker /*
416*be431cd8SAndroid Build Coastguard Worker  * Service continuously writes a packet of 64 bytes into the client's inbox
417*be431cd8SAndroid Build Coastguard Worker  * queue
418*be431cd8SAndroid Build Coastguard Worker  * of size 16K. Client keeps reading from the inbox queue. The average write to
419*be431cd8SAndroid Build Coastguard Worker  * read delay is calculated.
420*be431cd8SAndroid Build Coastguard Worker  */
TEST_F(MQTestClient,BenchMarkMeasureServiceWriteClientRead)421*be431cd8SAndroid Build Coastguard Worker TEST_F(MQTestClient, BenchMarkMeasureServiceWriteClientRead) {
422*be431cd8SAndroid Build Coastguard Worker     uint8_t* data = new (std::nothrow) uint8_t[kPacketSize64];
423*be431cd8SAndroid Build Coastguard Worker     ASSERT_TRUE(data != nullptr);
424*be431cd8SAndroid Build Coastguard Worker     /*
425*be431cd8SAndroid Build Coastguard Worker      * This method causes the service to create a thread which writes
426*be431cd8SAndroid Build Coastguard Worker      * into the mFmqInbox queue kNumIterations packets.
427*be431cd8SAndroid Build Coastguard Worker      */
428*be431cd8SAndroid Build Coastguard Worker     service->benchmarkServiceWriteClientRead(kNumIterations);
429*be431cd8SAndroid Build Coastguard Worker     android::hardware::hidl_vec<int64_t> clientRcvTimeArray;
430*be431cd8SAndroid Build Coastguard Worker     clientRcvTimeArray.resize(kNumIterations);
431*be431cd8SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumIterations; i++) {
432*be431cd8SAndroid Build Coastguard Worker         do {
433*be431cd8SAndroid Build Coastguard Worker             clientRcvTimeArray[i] =
434*be431cd8SAndroid Build Coastguard Worker                     std::chrono::high_resolution_clock::now().time_since_epoch().count();
435*be431cd8SAndroid Build Coastguard Worker         } while (mFmqInbox->read(data, kPacketSize64) == 0);
436*be431cd8SAndroid Build Coastguard Worker     }
437*be431cd8SAndroid Build Coastguard Worker     service->sendTimeData(clientRcvTimeArray);
438*be431cd8SAndroid Build Coastguard Worker     delete[] data;
439*be431cd8SAndroid Build Coastguard Worker }
440