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