From 171603eaa9bbb2b8189f5231338bcd928fde7383 Mon Sep 17 00:00:00 2001 From: Hridya Valsaraju Date: Tue, 7 Mar 2017 20:25:08 -0800 Subject: [PATCH] Move FMQ benchmark/test services to hardware/interfaces Bug: 32284445 Test: Built and ran FMQ benchmarks Change-Id: Ia6bacf21d276b55e4e590dc96f348464f2098992 --- tests/msgq/1.0/default/Android.bp | 48 ++++++ tests/msgq/1.0/default/BenchmarkMsgQ.cpp | 156 ++++++++++++++++++ tests/msgq/1.0/default/BenchmarkMsgQ.h | 100 +++++++++++ tests/msgq/1.0/default/TestMsgQ.cpp | 16 ++ tests/msgq/1.0/default/TestMsgQ.h | 16 ++ .../msgq/1.0/default/mq_benchmark_service.cpp | 28 ++++ tests/msgq/1.0/default/mq_test_service.cpp | 28 ++++ 7 files changed, 392 insertions(+) create mode 100644 tests/msgq/1.0/default/BenchmarkMsgQ.cpp create mode 100644 tests/msgq/1.0/default/BenchmarkMsgQ.h create mode 100644 tests/msgq/1.0/default/mq_benchmark_service.cpp create mode 100644 tests/msgq/1.0/default/mq_test_service.cpp diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp index 692eddacba..16018acee0 100644 --- a/tests/msgq/1.0/default/Android.bp +++ b/tests/msgq/1.0/default/Android.bp @@ -1,3 +1,18 @@ +// +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + cc_library_shared { name: "android.hardware.tests.msgq@1.0-impl", defaults: ["hidl_defaults"], @@ -5,6 +20,7 @@ cc_library_shared { proprietary: true, srcs: [ "TestMsgQ.cpp", + "BenchmarkMsgQ.cpp" ], shared_libs: [ "libbase", @@ -18,3 +34,35 @@ cc_library_shared { "android.hidl.base@1.0", ], } + +cc_test { + name: "android.hardware.tests.msgq@1.0-service-benchmark", + srcs: ["mq_benchmark_service.cpp"], + gtest: false, + + shared_libs: [ + "libbase", + "libcutils", + "libhidlbase", + "libhidltransport", + "liblog", + "libutils", + "android.hardware.tests.msgq@1.0" + ], +} + +cc_test { + name: "android.hardware.tests.msgq@1.0-service-test", + srcs: ["mq_test_service.cpp"], + gtest: false, + + shared_libs: [ + "libbase", + "libcutils", + "libhidlbase", + "libhidltransport", + "liblog", + "libutils", + "android.hardware.tests.msgq@1.0" + ], +} diff --git a/tests/msgq/1.0/default/BenchmarkMsgQ.cpp b/tests/msgq/1.0/default/BenchmarkMsgQ.cpp new file mode 100644 index 0000000000..43e6fcc6f2 --- /dev/null +++ b/tests/msgq/1.0/default/BenchmarkMsgQ.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BenchmarkMsgQ.h" +#include +#include +#include + +namespace android { +namespace hardware { +namespace tests { +namespace msgq { +namespace V1_0 { +namespace implementation { + +// Methods from ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ follow. +Return BenchmarkMsgQ::configureClientInboxSyncReadWrite( + configureClientInboxSyncReadWrite_cb _hidl_cb) { + static constexpr size_t kNumElementsInQueue = 16 * 1024; + mFmqOutbox = new (std::nothrow) android::hardware::MessageQueue(kNumElementsInQueue); + if (mFmqOutbox == nullptr) { + _hidl_cb(false /* ret */, android::hardware::MQDescriptorSync( + std::vector(), + nullptr /* nhandle */, 0 /* size */)); + } else { + _hidl_cb(true /* ret */, *mFmqOutbox->getDesc()); + } + + return Void(); +} + +Return BenchmarkMsgQ::configureClientOutboxSyncReadWrite( + configureClientOutboxSyncReadWrite_cb _hidl_cb) { + static constexpr size_t kNumElementsInQueue = 16 * 1024; + mFmqInbox = new (std::nothrow) android::hardware::MessageQueue(kNumElementsInQueue); + if ((mFmqInbox == nullptr) || (mFmqInbox->isValid() == false)) { + _hidl_cb(false /* ret */, android::hardware::MQDescriptorSync( + std::vector(), + nullptr /* nhandle */, 0 /* size */)); + } else { + _hidl_cb(true /* ret */, *mFmqInbox->getDesc()); + } + + return Void(); +} + +Return BenchmarkMsgQ::requestWrite(int32_t count) { + uint8_t* data = new (std::nothrow) uint8_t[count]; + for (int i = 0; i < count; i++) { + data[i] = i; + } + bool result = mFmqOutbox->write(data, count); + delete[] data; + return result; +} + +Return BenchmarkMsgQ::requestRead(int32_t count) { + uint8_t* data = new (std::nothrow) uint8_t[count]; + bool result = mFmqInbox->read(data, count); + delete[] data; + return result; +} + +Return BenchmarkMsgQ::benchmarkPingPong(uint32_t numIter) { + std::thread(QueuePairReadWrite, mFmqInbox, + mFmqOutbox, numIter) + .detach(); + return Void(); +} + +Return BenchmarkMsgQ::benchmarkServiceWriteClientRead(uint32_t numIter) { + if (mTimeData) delete[] mTimeData; + mTimeData = new (std::nothrow) int64_t[numIter]; + std::thread(QueueWriter, mFmqOutbox, + mTimeData, numIter).detach(); + return Void(); +} + +Return BenchmarkMsgQ::sendTimeData(const hidl_vec& clientRcvTimeArray) { + int64_t accumulatedTime = 0; + + for (uint32_t i = 0; i < clientRcvTimeArray.size(); i++) { + std::chrono::time_point + clientRcvTime((std::chrono::high_resolution_clock::duration( + clientRcvTimeArray[i]))); + std::chrono::time_pointserverSendTime( + (std::chrono::high_resolution_clock::duration(mTimeData[i]))); + accumulatedTime += static_cast( + std::chrono::duration_cast(clientRcvTime - + serverSendTime).count()); + } + + accumulatedTime /= clientRcvTimeArray.size(); + std::cout << "Average service to client write to read delay::" + << accumulatedTime << "ns" << std::endl; + return Void(); +} + +template +void BenchmarkMsgQ::QueueWriter(android::hardware::MessageQueue* mFmqOutbox, + int64_t* mTimeData, + uint32_t numIter) { + uint8_t data[kPacketSize64]; + uint32_t numWrites = 0; + + while (numWrites < numIter) { + do { + mTimeData[numWrites] = + std::chrono::high_resolution_clock::now().time_since_epoch().count(); + } while (mFmqOutbox->write(data, kPacketSize64) == false); + numWrites++; + } +} + +template +void BenchmarkMsgQ::QueuePairReadWrite( + android::hardware::MessageQueue* mFmqInbox, + android::hardware::MessageQueue* mFmqOutbox, + uint32_t numIter) { + uint8_t data[kPacketSize64]; + uint32_t numRoundTrips = 0; + + while (numRoundTrips < numIter) { + while (mFmqInbox->read(data, kPacketSize64) == false) + ; + while (mFmqOutbox->write(data, kPacketSize64) == false) + ; + numRoundTrips++; + } +} + +IBenchmarkMsgQ* HIDL_FETCH_IBenchmarkMsgQ(const char* /* name */) { + return new BenchmarkMsgQ(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace msgq +} // namespace tests +} // namespace hardware +} // namespace android diff --git a/tests/msgq/1.0/default/BenchmarkMsgQ.h b/tests/msgq/1.0/default/BenchmarkMsgQ.h new file mode 100644 index 0000000000..2cbe93c96d --- /dev/null +++ b/tests/msgq/1.0/default/BenchmarkMsgQ.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_TESTS_MSGQ_V1_0_BENCHMARKMSGQ_H +#define ANDROID_HARDWARE_TESTS_MSGQ_V1_0_BENCHMARKMSGQ_H + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace tests { +namespace msgq { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ; +using ::android::hidl::base::V1_0::DebugInfo; +using ::android::hidl::base::V1_0::IBase; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +using android::hardware::kSynchronizedReadWrite; +using android::hardware::MQFlavor; + +struct BenchmarkMsgQ : public IBenchmarkMsgQ { + /* + * The various packet sizes used are as follows. + */ + enum PacketSizes { + kPacketSize64 = 64, + kPacketSize128 = 128, + kPacketSize256 = 256, + kPacketSize512 = 512, + kPacketSize1024 = 1024 + }; + // Methods from ::android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ follow. + Return configureClientInboxSyncReadWrite(configureClientInboxSyncReadWrite_cb _hidl_cb) override; + Return configureClientOutboxSyncReadWrite(configureClientOutboxSyncReadWrite_cb _hidl_cb) override; + Return requestWrite(int32_t count) override; + Return requestRead(int32_t count) override; + Return benchmarkPingPong(uint32_t numIter) override; + Return benchmarkServiceWriteClientRead(uint32_t numIter) override; + Return sendTimeData(const hidl_vec& timeData) override; + + /* + * This method writes numIter packets into the mFmqOutbox queue + * and notes the time before each write in the mTimeData array. It will + * be used to calculate the average server to client write to read delay. + */ + template + static void QueueWriter(android::hardware::MessageQueue* + mFmqOutbox, int64_t* mTimeData, uint32_t numIter); + /* + * The method reads a packet from the inbox queue and writes the same + * into the outbox queue. The client will calculate the average time taken + * for each iteration which consists of two write and two read operations. + */ + template + static void QueuePairReadWrite( + android::hardware::MessageQueue* mFmqInbox, + android::hardware::MessageQueue* mFmqOutbox, + uint32_t numIter); + +private: + android::hardware::MessageQueue* mFmqInbox; + android::hardware::MessageQueue* mFmqOutbox; + int64_t* mTimeData; +}; + +extern "C" IBenchmarkMsgQ* HIDL_FETCH_IBenchmarkMsgQ(const char* name); + +} // namespace implementation +} // namespace V1_0 +} // namespace msgq +} // namespace tests +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TESTS_MSGQ_V1_0_BENCHMARKMSGQ_H diff --git a/tests/msgq/1.0/default/TestMsgQ.cpp b/tests/msgq/1.0/default/TestMsgQ.cpp index 7cc4f5b76c..6fd4fc6bb0 100644 --- a/tests/msgq/1.0/default/TestMsgQ.cpp +++ b/tests/msgq/1.0/default/TestMsgQ.cpp @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "TestMsgQ.h" namespace android { diff --git a/tests/msgq/1.0/default/TestMsgQ.h b/tests/msgq/1.0/default/TestMsgQ.h index 760d931391..86e4ac4029 100644 --- a/tests/msgq/1.0/default/TestMsgQ.h +++ b/tests/msgq/1.0/default/TestMsgQ.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #ifndef ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H #define ANDROID_HARDWARE_TESTS_MSGQ_V1_0_TESTMSGQ_H diff --git a/tests/msgq/1.0/default/mq_benchmark_service.cpp b/tests/msgq/1.0/default/mq_benchmark_service.cpp new file mode 100644 index 0000000000..b9be81bfb8 --- /dev/null +++ b/tests/msgq/1.0/default/mq_benchmark_service.cpp @@ -0,0 +1,28 @@ +/* +* Copyright (C) 2017 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define LOG_TAG "FMQ_Benchmarks" + +#include + +#include + +using android::hardware::tests::msgq::V1_0::IBenchmarkMsgQ; +using android::hardware::defaultPassthroughServiceImplementation; + +int main() { + return defaultPassthroughServiceImplementation(); +} diff --git a/tests/msgq/1.0/default/mq_test_service.cpp b/tests/msgq/1.0/default/mq_test_service.cpp new file mode 100644 index 0000000000..b5cb662549 --- /dev/null +++ b/tests/msgq/1.0/default/mq_test_service.cpp @@ -0,0 +1,28 @@ +/* +* Copyright (C) 2017 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define LOG_TAG "FMQ_UnitTests" + +#include + +#include + +using android::hardware::tests::msgq::V1_0::ITestMsgQ; +using android::hardware::defaultPassthroughServiceImplementation; + +int main() { + return defaultPassthroughServiceImplementation(); +}