• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 <errno.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 
22 #include <string>
23 
24 #include <android-base/test_utils.h>
25 
26 using namespace std::literals;
27 
28 #if defined(__BIONIC__)
29 
30 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
31 #include <sys/_system_properties.h>
32 
33 #include <benchmark/benchmark.h>
34 #include <system_properties/system_properties.h>
35 #include "util.h"
36 
37 struct LocalPropertyTestState {
LocalPropertyTestStateLocalPropertyTestState38   explicit LocalPropertyTestState(int nprops)
39       : nprops(nprops), valid(false), system_properties_(false) {
40     static const char prop_name_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
41 
42     valid = system_properties_.AreaInit(dir_.path, nullptr);
43     if (!valid) {
44       return;
45     }
46 
47     names = new char* [nprops];
48     name_lens = new int[nprops];
49     values = new char* [nprops];
50     value_lens = new int[nprops];
51 
52     srandom(nprops);
53 
54     for (int i = 0; i < nprops; i++) {
55       // Make sure the name has at least 10 characters to make
56       // it very unlikely to generate the same random name.
57       name_lens[i] = (random() % (PROP_NAME_MAX - 10)) + 10;
58       names[i] = new char[PROP_NAME_MAX + 1];
59       size_t prop_name_len = sizeof(prop_name_chars) - 1;
60       for (int j = 0; j < name_lens[i]; j++) {
61         if (j == 0 || names[i][j-1] == '.' || j == name_lens[i] - 1) {
62           // Certain values are not allowed:
63           // - Don't start name with '.'
64           // - Don't allow '.' to appear twice in a row
65           // - Don't allow the name to end with '.'
66           // This assumes that '.' is the last character in the
67           // array so that decrementing the length by one removes
68           // the value from the possible values.
69           prop_name_len--;
70         }
71         names[i][j] = prop_name_chars[random() % prop_name_len];
72       }
73       names[i][name_lens[i]] = 0;
74 
75       // Make sure the value contains at least 1 character.
76       value_lens[i] = (random() % (PROP_VALUE_MAX - 1)) + 1;
77       values[i] = new char[PROP_VALUE_MAX];
78       for (int j = 0; j < value_lens[i]; j++) {
79         values[i][j] = prop_name_chars[random() % (sizeof(prop_name_chars) - 1)];
80       }
81 
82       if (system_properties_.Add(names[i], name_lens[i], values[i], value_lens[i]) < 0) {
83         printf("Failed to add a property, terminating...\n");
84         printf("%s = %.*s\n", names[i], value_lens[i], values[i]);
85         exit(1);
86       }
87     }
88 
89     valid = true;
90   }
91 
system_propertiesLocalPropertyTestState92   SystemProperties& system_properties() {
93     return system_properties_;
94   }
95 
~LocalPropertyTestStateLocalPropertyTestState96   ~LocalPropertyTestState() {
97     if (!valid) {
98       return;
99     }
100 
101     system_properties_.contexts_->FreeAndUnmap();
102 
103     for (int i = 0; i < nprops; i++) {
104       delete names[i];
105       delete values[i];
106     }
107     delete[] names;
108     delete[] name_lens;
109     delete[] values;
110     delete[] value_lens;
111   }
112 
113  public:
114   const int nprops;
115   char** names;
116   int* name_lens;
117   char** values;
118   int* value_lens;
119   bool valid;
120 
121  private:
122   SystemProperties system_properties_;
123   TemporaryDir dir_;
124 };
125 
BM_property_get(benchmark::State & state)126 static void BM_property_get(benchmark::State& state) {
127   const size_t nprops = state.range(0);
128 
129   LocalPropertyTestState pa(nprops);
130   if (!pa.valid) return;
131 
132   while (state.KeepRunning()) {
133     char value[PROP_VALUE_MAX];
134     pa.system_properties().Get(pa.names[random() % nprops], value);
135   }
136 }
137 BIONIC_BENCHMARK_WITH_ARG(BM_property_get, "NUM_PROPS");
138 
BM_property_find(benchmark::State & state)139 static void BM_property_find(benchmark::State& state) {
140   const size_t nprops = state.range(0);
141 
142   LocalPropertyTestState pa(nprops);
143   if (!pa.valid) return;
144 
145   while (state.KeepRunning()) {
146     pa.system_properties().Find(pa.names[random() % nprops]);
147   }
148 }
149 BIONIC_BENCHMARK_WITH_ARG(BM_property_find, "NUM_PROPS");
150 
BM_property_read(benchmark::State & state)151 static void BM_property_read(benchmark::State& state) {
152   const size_t nprops = state.range(0);
153 
154   LocalPropertyTestState pa(nprops);
155   if (!pa.valid) return;
156 
157   const prop_info** pinfo = new const prop_info*[nprops];
158   char propvalue[PROP_VALUE_MAX];
159 
160   for (size_t i = 0; i < nprops; ++i) {
161     pinfo[i] = pa.system_properties().Find(pa.names[random() % nprops]);
162   }
163 
164   size_t i = 0;
165   while (state.KeepRunning()) {
166     pa.system_properties().Read(pinfo[i], 0, propvalue);
167     i = (i + 1) % nprops;
168   }
169 
170   delete[] pinfo;
171 }
172 BIONIC_BENCHMARK_WITH_ARG(BM_property_read, "NUM_PROPS");
173 
BM_property_serial(benchmark::State & state)174 static void BM_property_serial(benchmark::State& state) {
175   const size_t nprops = state.range(0);
176 
177   LocalPropertyTestState pa(nprops);
178   if (!pa.valid) return;
179 
180   const prop_info** pinfo = new const prop_info*[nprops];
181   for (size_t i = 0; i < nprops; ++i) {
182     pinfo[i] = pa.system_properties().Find(pa.names[random() % nprops]);
183   }
184 
185   size_t i = 0;
186   while (state.KeepRunning()) {
187     pa.system_properties().Serial(pinfo[i]);
188     i = (i + 1) % nprops;
189   }
190 
191   delete[] pinfo;
192 }
193 BIONIC_BENCHMARK_WITH_ARG(BM_property_serial, "NUM_PROPS");
194 
195 #endif  // __BIONIC__
196