blob: 88b1be05db31309c5321e6184922af1229b67042 [file] [log] [blame]
Pavel Maltseve2603e32016-10-25 16:03:23 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <thread>
18
19#include <gtest/gtest.h>
20
21#include <vehicle_hal_manager/VehicleObjectPool.h>
22#include <utils/SystemClock.h>
23
24namespace android {
25namespace hardware {
26namespace vehicle {
27namespace V2_0 {
28
29namespace {
30
31class VehicleObjectPoolTest : public ::testing::Test {
32protected:
33 void SetUp() override {
34 stats = PoolStats::instance();
35 resetStats();
36 valuePool.reset(new VehiclePropValuePool);
37 }
38
39 void TearDown() override {
40 // At the end, all created objects should be either recycled or deleted.
41 // Some objects could be recycled multiple times, that's why it's <=
42 ASSERT_EQ(stats->Obtained, stats->Recycled);
43 ASSERT_LE(stats->Created, stats->Recycled);
44 }
45private:
46 void resetStats() {
47 stats->Obtained = 0;
48 stats->Created = 0;
49 stats->Recycled = 0;
50 }
51
52public:
53 PoolStats* stats;
54 std::unique_ptr<VehiclePropValuePool> valuePool;
55};
56
57TEST_F(VehicleObjectPoolTest, valuePoolBasicCorrectness) {
58 void* raw = valuePool->obtain(VehiclePropertyType::INT32).get();
59 // At this point, v1 should be recycled and the only object in the pool.
60 ASSERT_EQ(raw, valuePool->obtain(VehiclePropertyType::INT32).get());
61 // Obtaining value of another type - should return a new object
62 ASSERT_NE(raw, valuePool->obtain(VehiclePropertyType::FLOAT).get());
63
64 ASSERT_EQ(3u, stats->Obtained);
65 ASSERT_EQ(2u, stats->Created);
66}
67
68TEST_F(VehicleObjectPoolTest, valuePoolStrings) {
69 valuePool->obtain(VehiclePropertyType::STRING);
70 auto vs = valuePool->obtain(VehiclePropertyType::STRING);
71 vs->value.stringValue = "Hello";
72 void* raw = vs.get();
73 vs.reset(); // delete the pointer
74
75 auto vs2 = valuePool->obtain(VehiclePropertyType::STRING);
76 ASSERT_EQ(0u, vs2->value.stringValue.size());
77 ASSERT_NE(raw, valuePool->obtain(VehiclePropertyType::STRING).get());
78
79 ASSERT_EQ(0u, stats->Obtained);
80}
81
82TEST_F(VehicleObjectPoolTest, valuePoolMultithreadedBenchmark) {
83 // In this test we have T threads that concurrently in C cycles
84 // obtain and release O VehiclePropValue objects of FLOAT / INT32 types.
85
86 const auto T = 2;
87 const auto C = 500;
88 const auto O = 100;
89
90 auto poolPtr = valuePool.get();
91
92 std::vector<std::thread> threads;
93 auto start = elapsedRealtimeNano();
94 for (int i = 0; i < T; i++) {
95 threads.push_back(std::thread([&poolPtr] () {
96 for (int j = 0; j < C; j++) {
97 std::vector<recyclable_ptr<VehiclePropValue>> vec;
98 for (int k = 0; k < O; k++) {
99 vec.push_back(
100 poolPtr->obtain(k % 2 == 0
101 ? VehiclePropertyType::FLOAT
102 : VehiclePropertyType::INT32));
103 }
104 }
105 }));
106 }
107
108 for (auto& t : threads) {
109 t.join();
110 }
111 auto finish = elapsedRealtimeNano();
112
113 ASSERT_EQ(T * C * O, stats->Obtained);
114 ASSERT_EQ(T * C * O, stats->Recycled);
115 // Created less than obtained.
116 ASSERT_GE(T * O, stats->Created);
117
118 auto elapsedMs = (finish - start) / 1000000;
119 ASSERT_GE(1000, elapsedMs); // Less a second to access 100K objects.
120 // Typically it takes about 0.1s on Nexus6P.
121}
122
123} // namespace anonymous
124
125} // namespace V2_0
126} // namespace vehicle
127} // namespace hardware
128} // namespace android