1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <benchmark/benchmark.h>
17 #include "singleton.h"
18 #include <algorithm>
19 #include <iostream>
20 #include <fstream>
21 #include "benchmark_log.h"
22 #include "benchmark_assert.h"
23 using namespace std;
24 
25 namespace OHOS {
26 namespace {
27 
28 static constexpr long DELAYEDSINGLETON_SP1_USE_COUNT = 2;
29 static constexpr long DELAYEDSINGLETON_SP2_USE_COUNT = 3;
30 
31 class BenchmarkSingletonTest : public benchmark::Fixture {
32 public:
SetUp(const::benchmark::State & state)33     void SetUp(const ::benchmark::State& state) override
34     {
35     }
36 
TearDown(const::benchmark::State & state)37     void TearDown(const ::benchmark::State& state) override
38     {
39     }
40 
BenchmarkSingletonTest()41     BenchmarkSingletonTest()
42     {
43         Iterations(iterations);
44         Repetitions(repetitions);
45         ReportAggregatesOnly();
46     }
47 
48     ~BenchmarkSingletonTest() override = default;
49 
50 protected:
51     const int32_t repetitions = 3;
52     const int32_t iterations = 1000;
53 };
54 
55 class DelayedSingletonDeclearTest {
56     DECLARE_DELAYED_SINGLETON(DelayedSingletonDeclearTest);
57 public:
GetObjAddr()58     void* GetObjAddr()
59     {
60         BENCHMARK_LOGD("SingletonTest DelayedSingletonDeclearTest void* GetObjAddr is called.");
61         return static_cast<void*>(this);
62     }
63 };
64 
~DelayedSingletonDeclearTest()65 DelayedSingletonDeclearTest::~DelayedSingletonDeclearTest() {};
DelayedSingletonDeclearTest()66 DelayedSingletonDeclearTest::DelayedSingletonDeclearTest() {};
67 
68 class SingletonDeclearTest {
69     DECLARE_SINGLETON(SingletonDeclearTest);
70 public:
GetObjAddr()71     void* GetObjAddr()
72     {
73         BENCHMARK_LOGD("SingletonTest SingletonDeclearTest void* GetObjAddr is called.");
74         return static_cast<void*>(this);
75     }
76 };
77 
~SingletonDeclearTest()78 SingletonDeclearTest::~SingletonDeclearTest() {};
SingletonDeclearTest()79 SingletonDeclearTest::SingletonDeclearTest() {};
80 
81 class SingletonTest : public Singleton<SingletonTest> {
82 public:
GetObjAddr()83     void* GetObjAddr()
84     {
85         BENCHMARK_LOGD("SingletonTest SingletonTest void* GetObjAddr is called.");
86         return static_cast<void*>(this);
87     }
88 };
89 
90 class DelayedSingletonTest : public DelayedSingleton<DelayedSingletonTest> {
91 public:
GetObjAddr()92     void* GetObjAddr()
93     {
94         BENCHMARK_LOGD("SingletonTest DelayedSingletonTest void* GetObjAddr is called.");
95         return static_cast<void*>(this);
96     }
97 };
98 
99 
100 class DelayedRefSingletonDeclearTest {
101     DECLARE_DELAYED_REF_SINGLETON(DelayedRefSingletonDeclearTest);
102 public:
GetObjAddr()103     void* GetObjAddr()
104     {
105         BENCHMARK_LOGD("SingletonTest DelayedRefSingletonDeclearTest void* GetObjAddr is called.");
106         return static_cast<void*>(this);
107     }
108 };
109 
DelayedRefSingletonDeclearTest()110 DelayedRefSingletonDeclearTest::DelayedRefSingletonDeclearTest() {};
~DelayedRefSingletonDeclearTest()111 DelayedRefSingletonDeclearTest::~DelayedRefSingletonDeclearTest() {};
112 
113 class DelayedRefSingletonTest : public DelayedRefSingleton<DelayedRefSingletonTest> {
114 public:
GetObjAddr()115     void* GetObjAddr()
116     {
117         BENCHMARK_LOGD("SingletonTest DelayedRefSingletonTest void* GetObjAddr is called.");
118         return static_cast<void*>(this);
119     }
120 };
121 
BENCHMARK_F(BenchmarkSingletonTest,test_DelayedSingletonDeclearTest)122 BENCHMARK_F(BenchmarkSingletonTest, test_DelayedSingletonDeclearTest)(benchmark::State& state)
123 {
124     BENCHMARK_LOGD("SingletonTest test_DelayedSingletonDeclearTest start.");
125     while (state.KeepRunning()) {
126         shared_ptr<DelayedSingletonDeclearTest> sp1 = DelayedSingleton<DelayedSingletonDeclearTest>::GetInstance();
127         AssertEqual(sp1.use_count(), DELAYEDSINGLETON_SP1_USE_COUNT,
128             "sp1.use_count() did not equal DELAYEDSINGLETON_SP1_USE_COUNT as expected.", state);
129 
130         shared_ptr<DelayedSingletonDeclearTest> sp2 = DelayedSingleton<DelayedSingletonDeclearTest>::GetInstance();
131         AssertEqual(sp1->GetObjAddr(), sp2->GetObjAddr(),
132             "sp1->GetObjAddr() did not equal sp2->GetObjAddr() as expected.", state);
133         AssertEqual(sp1.get(), sp2.get(), "sp1.get() did not equal sp2.get() as expected.", state);
134         AssertEqual(sp2.use_count(), DELAYEDSINGLETON_SP2_USE_COUNT,
135             "sp2.use_count() did not equal DELAYEDSINGLETON_SP2_USE_COUNT as expected.", state);
136     }
137     BENCHMARK_LOGD("SingletonTest test_DelayedSingletonDeclearTest end.");
138 }
139 
BENCHMARK_F(BenchmarkSingletonTest,test_SingletonDeclearTest)140 BENCHMARK_F(BenchmarkSingletonTest, test_SingletonDeclearTest)(benchmark::State& state)
141 {
142     BENCHMARK_LOGD("SingletonTest test_SingletonDeclearTest start.");
143     while (state.KeepRunning()) {
144         SingletonDeclearTest &st1 = Singleton<SingletonDeclearTest>::GetInstance();
145         SingletonDeclearTest &st2 = Singleton<SingletonDeclearTest>::GetInstance();
146         AssertEqual(st1.GetObjAddr(), st2.GetObjAddr(),
147             "st1.GetObjAddr() did not equal st2.GetObjAddr() as expected.", state);
148     }
149     BENCHMARK_LOGD("SingletonTest test_SingletonDeclearTest end.");
150 }
151 
BENCHMARK_F(BenchmarkSingletonTest,test_SingletonTest)152 BENCHMARK_F(BenchmarkSingletonTest, test_SingletonTest)(benchmark::State& state)
153 {
154     BENCHMARK_LOGD("SingletonTest test_SingletonTest start.");
155     while (state.KeepRunning()) {
156         SingletonTest &st1 = SingletonTest::GetInstance();
157         SingletonTest &st2 = SingletonTest::GetInstance();
158         AssertEqual(st1.GetObjAddr(), st2.GetObjAddr(),
159             "st1.GetObjAddr() did not equal st2.GetObjAddr() as expected.", state);
160     }
161     BENCHMARK_LOGD("SingletonTest test_SingletonTest end.");
162 }
163 
BENCHMARK_F(BenchmarkSingletonTest,test_DelayedSingletonTest)164 BENCHMARK_F(BenchmarkSingletonTest, test_DelayedSingletonTest)(benchmark::State& state)
165 {
166     BENCHMARK_LOGD("SingletonTest test_DelayedSingletonTest start.");
167     while (state.KeepRunning()) {
168         shared_ptr<DelayedSingletonTest> sp1 = DelayedSingletonTest::GetInstance();
169         AssertEqual(sp1.use_count(), DELAYEDSINGLETON_SP1_USE_COUNT,
170             "sp1.use_count() did not equal DELAYEDSINGLETON_SP1_USE_COUNT as expected.", state);
171 
172         shared_ptr<DelayedSingletonTest> sp2 = DelayedSingletonTest::GetInstance();
173         AssertEqual(sp1->GetObjAddr(), sp2->GetObjAddr(),
174             "sp1->GetObjAddr() did not equal sp2->GetObjAddr() as expected.", state);
175         AssertEqual(sp1.get(), sp2.get(), "sp1.get() did not equal sp2.get() as expected.", state);
176         AssertEqual(sp2.use_count(), DELAYEDSINGLETON_SP2_USE_COUNT,
177             "sp2.use_count() did not equal DELAYEDSINGLETON_SP2_USE_COUNT as expected.", state);
178     }
179     BENCHMARK_LOGD("SingletonTest test_DelayedSingletonTest end.");
180 }
181 
BENCHMARK_F(BenchmarkSingletonTest,test_DelayedRefSingletonTest)182 BENCHMARK_F(BenchmarkSingletonTest, test_DelayedRefSingletonTest)(benchmark::State& state)
183 {
184     BENCHMARK_LOGD("SingletonTest test_DelayedRefSingletonTest start.");
185     while (state.KeepRunning()) {
186         DelayedRefSingletonTest& p1 = DelayedRefSingletonTest::GetInstance();
187         DelayedRefSingletonTest& p2 = DelayedRefSingletonTest::GetInstance();
188         AssertEqual(p1.GetObjAddr(), p2.GetObjAddr(),
189             "p1.GetObjAddr() did not equal p2.GetObjAddr() as expected.", state);
190     }
191     BENCHMARK_LOGD("SingletonTest test_DelayedRefSingletonTest end.");
192 }
193 
BENCHMARK_F(BenchmarkSingletonTest,test_DelayedRefSingletonDeclearTest)194 BENCHMARK_F(BenchmarkSingletonTest, test_DelayedRefSingletonDeclearTest)(benchmark::State& state)
195 {
196     BENCHMARK_LOGD("SingletonTest test_DelayedRefSingletonDeclearTest start.");
197     while (state.KeepRunning()) {
198         DelayedRefSingletonDeclearTest& p1 = DelayedRefSingleton<DelayedRefSingletonDeclearTest>::GetInstance();
199         DelayedRefSingletonDeclearTest& p2 = DelayedRefSingleton<DelayedRefSingletonDeclearTest>::GetInstance();
200         AssertEqual(p1.GetObjAddr(), p2.GetObjAddr(),
201             "p1.GetObjAddr() did not equal p2.GetObjAddr() as expected.", state);
202     }
203     BENCHMARK_LOGD("SingletonTest test_DelayedRefSingletonDeclearTest end.");
204 }
205 
206 /**
207  * @tc.name: test_DelayedSingletonDestroyTest
208  * @tc.desc: test Singleton Destroy Instance
209  * @tc.type: FUNC
210  */
BENCHMARK_F(BenchmarkSingletonTest,test_DelayedSingletonDestroyTest)211 BENCHMARK_F(BenchmarkSingletonTest, test_DelayedSingletonDestroyTest)(benchmark::State& state)
212 {
213     BENCHMARK_LOGD("SingletonTest test_DelayedSingletonDestroyTest start.");
214     while (state.KeepRunning()) {
215         shared_ptr<DelayedSingletonTest> sp1 = DelayedSingleton<DelayedSingletonTest>::GetInstance();
216         AssertUnequal(sp1, nullptr, "sp1 equal nullptr as expected.", state);
217 
218         sp1.reset();
219         DelayedSingleton<DelayedSingletonTest>::DestroyInstance();
220         AssertEqual(sp1, nullptr, "sp1 not equal nullptr as expected.", state);
221     }
222     BENCHMARK_LOGD("SingletonTest test_DelayedSingletonDestroyTest end.");
223 }
224 }  // namespace
225 }  // namespace OHOS
226 // Run the benchmark
227 BENCHMARK_MAIN();