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 "benchmark_fwk.h"
18 #include "init_param.h"
19 #include "param_init.h"
20 #include "parameter.h"
21 #include "sys_param.h"
22 
23 using namespace std;
24 using namespace init_benchmark_test;
25 namespace {
26 static int g_maxCount = 512;
27 }
28 
TestRandom(void)29 static inline int TestRandom(void)
30 {
31     return random();
32 }
33 
34 namespace init_benchmark_param {
35 struct LocalParameterTestState {
LocalParameterTestStateinit_benchmark_param::LocalParameterTestState36     explicit LocalParameterTestState(int nprops) noexcept : nprops(nprops), valid(false)
37     {
38         static const char paramNameChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
39         if (g_maxCount < nprops) {
40             fprintf(stderr, "Invalid nprops %d\n", nprops);
41             return;
42         }
43         names = new char *[nprops];
44         nameLens = new int[nprops];
45         values = new char *[nprops];
46         valueLens = new int[nprops];
47 
48         srandom(nprops);
49         int count = 0;
50         for (int i = 0; i < nprops; i++) {
51             // Make sure the name has at least 10 characters to make
52             // it very unlikely to generate the same TestRandom name.
53             nameLens[i] = (TestRandom() % (PARAM_NAME_LEN_MAX - 10)) + 10; // 10 name len
54             names[i] = new char[PARAM_NAME_LEN_MAX + 1];
55             size_t paramNameLen = sizeof(paramNameChars) - 1;
56             for (int j = 0; j < nameLens[i]; j++) {
57                 if (j == 0 || names[i][j - 1] == '.' || j == nameLens[i] - 1) {
58                     // Certain values are not allowed:
59                     // - Don't start name with '.'
60                     // - Don't allow '.' to appear twice in a row
61                     // - Don't allow the name to end with '.'
62                     // This assumes that '.' is the last character in the
63                     // array so that decrementing the length by one removes
64                     // the value from the possible values.
65                     paramNameLen--;
66                 }
67                 names[i][j] = paramNameChars[TestRandom() % paramNameLen];
68             }
69             names[i][nameLens[i]] = 0;
70 
71             // Make sure the value contains at least 1 character.
72             valueLens[i] = (TestRandom() % (PARAM_VALUE_LEN_MAX - 1)) + 1;
73             values[i] = new char[PARAM_VALUE_LEN_MAX];
74             for (int j = 0; j < valueLens[i]; j++) {
75                 values[i][j] = paramNameChars[TestRandom() % (sizeof(paramNameChars) - 1)];
76             }
77 
78             if (SystemSetParameter(names[i], values[i]) != 0) {
79                 count++;
80             }
81         }
82         if (count > 0) {
83             fprintf(stderr, "Failed to add a property, count %d\n", count);
84         }
85         valid = true;
86     }
87 
88     LocalParameterTestState(const LocalParameterTestState&) = delete;
89     LocalParameterTestState & operator=(const LocalParameterTestState&) = delete;
90 
~LocalParameterTestStateinit_benchmark_param::LocalParameterTestState91     ~LocalParameterTestState() noexcept
92     {
93         for (int i = 0; i < nprops; i++) {
94             delete names[i];
95             delete values[i];
96         }
97         delete[] names;
98         delete[] nameLens;
99         delete[] values;
100         delete[] valueLens;
101     }
102 
103 public:
104     const int nprops;
105     char **names;
106     int *nameLens;
107     char **values;
108     int *valueLens;
109     bool valid;
110 };
111 }
112 
113 static init_benchmark_param::LocalParameterTestState *g_localParamTester = nullptr;
114 
CreateLocalParameterTest(int max)115 void CreateLocalParameterTest(int max)
116 {
117     g_maxCount = max > 0 ? max : g_maxCount;
118     g_localParamTester = new init_benchmark_param::LocalParameterTestState(g_maxCount);
119     if (g_localParamTester == nullptr) {
120         exit(0);
121     }
122 }
123 
124 /**
125  * @brief for parameter get
126  *
127  * @param state
128  */
BMCachedParameterGet(benchmark::State & state)129 static void BMCachedParameterGet(benchmark::State &state)
130 {
131     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
132         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
133         return;
134     }
135 
136     CachedHandle handle = CachedParameterCreate(g_localParamTester->names[TestRandom() % g_maxCount], "4444444");
137     for (auto _ : state) {
138         benchmark::DoNotOptimize(CachedParameterGet(handle));
139     }
140     state.SetItemsProcessed(state.iterations());
141 }
142 
143 /**
144  * @brief for parameter get, static handle
145  *
146  * @param state
147  */
BMCachedParameterGetChangedStatic(benchmark::State & state)148 static void BMCachedParameterGetChangedStatic(benchmark::State &state)
149 {
150     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
151         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
152         return;
153     }
154 
155     for (auto _ : state) {
156         static CachedHandle handle = CachedParameterCreate(
157             g_localParamTester->names[TestRandom() % g_maxCount], "xxxxxx");
158         int changed = 0;
159         benchmark::DoNotOptimize(CachedParameterGetChanged(handle, &changed));
160     }
161     state.SetItemsProcessed(state.iterations());
162 }
163 
164 /**
165  * @brief for parameter get, global handle
166  *
167  * @param state
168  */
BMCachedParameterGetChangedGlobal(benchmark::State & state)169 static void BMCachedParameterGetChangedGlobal(benchmark::State &state)
170 {
171     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
172         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
173         return;
174     }
175 
176     CachedHandle handle = CachedParameterCreate(g_localParamTester->names[TestRandom() % g_maxCount], "xxxxxxxxx");
177     for (auto _ : state) {
178         int changed = 0;
179         benchmark::DoNotOptimize(CachedParameterGetChanged(handle, &changed));
180     }
181     state.SetItemsProcessed(state.iterations());
182 }
183 
184 /**
185  * @brief for parameter get, global handle
186  *
187  * @param state
188  */
BMCachedParameterGetChangedGlobal2(benchmark::State & state)189 static void BMCachedParameterGetChangedGlobal2(benchmark::State &state)
190 {
191     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
192         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
193         return;
194     }
195 
196     CachedHandle handle = nullptr;
197     for (auto _ : state) {
198         if (handle == nullptr) {
199             handle = CachedParameterCreate(g_localParamTester->names[TestRandom() % g_maxCount], "xxxxxxxxx");
200         }
201         int changed = 0;
202         benchmark::DoNotOptimize(CachedParameterGetChanged(handle, &changed));
203     }
204     state.SetItemsProcessed(state.iterations());
205 }
206 
207 /**
208  * @brief for get
209  * data exist
210  *
211  * @param state
212  */
BMSystemReadParam(benchmark::State & state)213 static void BMSystemReadParam(benchmark::State &state)
214 {
215     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
216         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
217         return;
218     }
219     {
220         char value[PARAM_VALUE_LEN_MAX] = {0};
221         uint32_t len = PARAM_VALUE_LEN_MAX;
222         SystemReadParam(g_localParamTester->names[TestRandom() % g_maxCount], value, &len);
223     }
224     for (auto _ : state) {
225         char value[PARAM_VALUE_LEN_MAX] = {0};
226         uint32_t len = PARAM_VALUE_LEN_MAX;
227         SystemReadParam(g_localParamTester->names[TestRandom() % g_maxCount], value, &len);
228     }
229     state.SetItemsProcessed(state.iterations());
230 }
231 
232 /**
233  * @brief for get
234  * data not exist
235  *
236  * @param state
237  */
BMSystemReadParam_none(benchmark::State & state)238 static void BMSystemReadParam_none(benchmark::State &state)
239 {
240     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
241         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
242         return;
243     }
244     {
245         char value[PARAM_VALUE_LEN_MAX] = {0};
246         uint32_t len = PARAM_VALUE_LEN_MAX;
247         SystemReadParam("test.aaa.aaa.aaa", value, &len);
248     }
249     for (auto _ : state) {
250         char value[PARAM_VALUE_LEN_MAX] = {0};
251         uint32_t len = PARAM_VALUE_LEN_MAX;
252         SystemReadParam("test.aaa.aaa.aaa", value, &len);
253     }
254     state.SetItemsProcessed(state.iterations());
255 }
256 
257 /**
258  * @brief for find
259  *
260  * @param state
261  */
BMSystemFindParameter(benchmark::State & state)262 static void BMSystemFindParameter(benchmark::State &state)
263 {
264     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
265         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
266         return;
267     }
268 
269     for (auto _ : state) {
270         ParamHandle handle = 0;
271         SystemFindParameter(g_localParamTester->names[TestRandom() % g_maxCount], &handle);
272     }
273     state.SetItemsProcessed(state.iterations());
274 }
275 
276 /**
277  * @brief for find, and read value
278  *
279  * @param state
280  */
BMSystemGetParameterValue(benchmark::State & state)281 static void BMSystemGetParameterValue(benchmark::State &state)
282 {
283     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
284         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
285         return;
286     }
287 
288     ParamHandle *handle = new ParamHandle[g_maxCount];
289     for (int i = 0; i < g_maxCount; ++i) {
290         SystemFindParameter(g_localParamTester->names[TestRandom() % g_maxCount], &handle[i]);
291     }
292 
293     int i = 0;
294     char value[PARAM_VALUE_LEN_MAX];
295     for (auto _ : state) {
296         uint32_t len = PARAM_VALUE_LEN_MAX;
297         SystemGetParameterValue(handle[i], value, &len);
298         i = (i + 1) % g_maxCount;
299     }
300     state.SetItemsProcessed(state.iterations());
301     delete[] handle;
302 }
303 
304 /**
305  * @brief for find, and read commit id
306  *
307  * @param state
308  */
BMSystemGetParameterCommitId(benchmark::State & state)309 static void BMSystemGetParameterCommitId(benchmark::State &state)
310 {
311     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
312         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
313         return;
314     }
315 
316     ParamHandle *handle = new ParamHandle[g_maxCount];
317     for (int i = 0; i < g_maxCount; ++i) {
318         SystemFindParameter(g_localParamTester->names[TestRandom() % g_maxCount], &handle[i]);
319     }
320 
321     int i = 0;
322     for (auto _ : state) {
323         uint32_t commitId = 0;
324         SystemGetParameterCommitId(handle[i], &commitId);
325         i = (i + 1) % g_maxCount;
326     }
327     state.SetItemsProcessed(state.iterations());
328     delete[] handle;
329 }
330 
BMTestRandom(benchmark::State & state)331 static void BMTestRandom(benchmark::State &state)
332 {
333     if (g_localParamTester == nullptr || !g_localParamTester->valid) {
334         fprintf(stderr, "Invalid nprops %d \n", g_maxCount);
335         return;
336     }
337 
338     for (auto _ : state) {
339         benchmark::DoNotOptimize(TestRandom());
340     }
341     state.SetItemsProcessed(state.iterations());
342 }
343 
344 INIT_BENCHMARK(BMCachedParameterGet);
345 INIT_BENCHMARK(BMCachedParameterGetChangedStatic);
346 INIT_BENCHMARK(BMCachedParameterGetChangedGlobal);
347 INIT_BENCHMARK(BMCachedParameterGetChangedGlobal2);
348 
349 INIT_BENCHMARK(BMSystemReadParam);
350 INIT_BENCHMARK(BMSystemReadParam_none);
351 INIT_BENCHMARK(BMSystemFindParameter);
352 INIT_BENCHMARK(BMSystemGetParameterValue);
353 INIT_BENCHMARK(BMSystemGetParameterCommitId);
354 INIT_BENCHMARK(BMTestRandom);
355