• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "clock_test.h"
10 #include "clock_if.h"
11 #include "hdf_base.h"
12 #include "hdf_io_service_if.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15 #include "securec.h"
16 #include "osal_thread.h"
17 #include "osal_time.h"
18 
19 #define DEFAULT_RATE                 10000
20 #define CLOCK_TEST_STACK_SIZE        (1024 * 64)
21 #define CLOCK_TEST_SLEEP_TIME        100
22 #define CLOCK_TEST_WAIT_TIMEOUT      20
23 #define HDF_LOG_TAG clock_test_c
24 DevHandle parent = NULL;
25 
ClockTestGetConfig(struct ClockTestConfig * config)26 static int32_t ClockTestGetConfig(struct ClockTestConfig *config)
27 {
28     int32_t ret;
29     struct HdfSBuf *reply = NULL;
30     struct HdfIoService *service = NULL;
31     const void *buf = NULL;
32     uint32_t len;
33 
34     HDF_LOGD("ClockTestGetConfig: enter!");
35     service = HdfIoServiceBind("CLOCK_TEST");
36     if (service == NULL) {
37         HDF_LOGE("ClockTestGetConfig: service is null!");
38         return HDF_ERR_NOT_SUPPORT;
39     }
40 
41     do {
42         reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
43         if (reply == NULL) {
44             HDF_LOGE("ClockTestGetConfig: fail to obtain reply!");
45             ret = HDF_ERR_MALLOC_FAIL;
46             break;
47         }
48 
49         ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
50         if (ret != HDF_SUCCESS) {
51             HDF_LOGE("ClockTestGetConfig: remote dispatch fail!");
52             break;
53         }
54 
55         if (!HdfSbufReadBuffer(reply, &buf, &len)) {
56             HDF_LOGE("ClockTestGetConfig: read buf fail!");
57             ret = HDF_ERR_IO;
58             break;
59         }
60 
61         if (len != sizeof(*config)) {
62             HDF_LOGE("ClockTestGetConfig: config size:%zu, read size:%u!", sizeof(*config), len);
63             ret = HDF_ERR_IO;
64             break;
65         }
66 
67         if (memcpy_s(config, sizeof(*config), buf, sizeof(*config)) != EOK) {
68             HDF_LOGE("ClockTestGetConfig: memcpy buf fail!");
69             ret = HDF_ERR_IO;
70             break;
71         }
72         HDF_LOGD("ClockTestGetConfig: exit!");
73         ret = HDF_SUCCESS;
74     } while (0);
75     HdfSbufRecycle(reply);
76     HdfIoServiceRecycle(service);
77     return ret;
78 }
79 
ClockTesterGet(void)80 static struct ClockTester *ClockTesterGet(void)
81 {
82     int32_t ret;
83     static struct ClockTester tester;
84     static bool hasInit = false;
85 
86     HDF_LOGE("ClockTesterGet: enter!");
87     if (hasInit) {
88         return &tester;
89     }
90     ret = ClockTestGetConfig(&tester.config);
91     if (ret != HDF_SUCCESS) {
92         HDF_LOGE("ClockTesterGet: read config fail, ret: %d!", ret);
93         return NULL;
94     }
95     tester.handle = ClockOpen(tester.config.deviceIndex);
96     if (tester.handle == NULL) {
97         HDF_LOGE("ClockTesterGet: open clock device:%u fail!", tester.config.deviceIndex);
98         return NULL;
99     }
100     hasInit = true;
101     HDF_LOGI("ClockTesterGet: done!");
102     return &tester;
103 }
104 
ClockTestEnable(void)105 static int32_t ClockTestEnable(void)
106 {
107     struct ClockTester *tester = NULL;
108     int32_t ret;
109 
110     HDF_LOGI("ClockTestEnable: enter!");
111     tester = ClockTesterGet();
112     if (tester == NULL) {
113         HDF_LOGE("ClockTestEnable: get tester fail!");
114         return HDF_ERR_INVALID_OBJECT;
115     }
116 
117     ret = ClockEnable(tester->handle);
118 
119     HDF_LOGI("ClockTestEnable: clock device num is %u!", tester->config.deviceIndex);
120     HDF_LOGI("ClockTestEnable: done!");
121     return ret;
122 }
123 
ClockTestThreadFunc(void * param)124 static int ClockTestThreadFunc(void *param)
125 {
126     struct ClockTester *tester = NULL;
127     int32_t ret;
128 
129     HDF_LOGI("ClockTestThreadFunc: enter!");
130     tester = ClockTesterGet();
131     if (tester == NULL) {
132         HDF_LOGE("ClockTestThreadFunc: get tester fail!");
133         *((int32_t *)param) = 1;
134         return HDF_ERR_INVALID_OBJECT;
135     }
136 
137     ret = ClockEnable(tester->handle);
138     if (ret != HDF_SUCCESS) {
139         HDF_LOGE("ClockTestThreadFunc: clock read fail, ret: %d!", ret);
140         *((int32_t *)param) = 1;
141         return HDF_ERR_IO;
142     }
143 
144     *((int32_t *)param) = 1;
145     HDF_LOGI("ClockTestThreadFunc: done!");
146     return HDF_SUCCESS;
147 }
148 
ClockTestStartThread(struct OsalThread * thread1,struct OsalThread * thread2,const int32_t * count1,const int32_t * count2)149 static int32_t ClockTestStartThread(struct OsalThread *thread1, struct OsalThread *thread2, const int32_t *count1,
150                                     const int32_t *count2)
151 {
152     int32_t ret;
153     uint32_t time = 0;
154     struct OsalThreadParam cfg1;
155     struct OsalThreadParam cfg2;
156 
157     if (memset_s(&cfg1, sizeof(cfg1), 0, sizeof(cfg1)) != EOK ||
158         memset_s(&cfg2, sizeof(cfg2), 0, sizeof(cfg2)) != EOK) {
159         HDF_LOGE("ClockTestStartThread: memset_s fail!");
160         return HDF_ERR_IO;
161     }
162 
163     cfg1.name = "ClockTestThread-1";
164     cfg2.name = "ClockTestThread-2";
165     cfg1.priority = cfg2.priority = OSAL_THREAD_PRI_DEFAULT;
166     cfg1.stackSize = cfg2.stackSize = CLOCK_TEST_STACK_SIZE;
167 
168     ret = OsalThreadStart(thread1, &cfg1);
169     if (ret != HDF_SUCCESS) {
170         HDF_LOGE("ClockTestStartThread: start test thread1 fail, ret: %d!", ret);
171         return ret;
172     }
173 
174     ret = OsalThreadStart(thread2, &cfg2);
175     if (ret != HDF_SUCCESS) {
176         HDF_LOGE("ClockTestStartThread: start test thread2 fail, ret: %d!", ret);
177     }
178 
179     while (*count1 == 0 || *count2 == 0) {
180         HDF_LOGD("ClockTestStartThread: waitting testing thread finish...");
181         OsalMSleep(CLOCK_TEST_SLEEP_TIME);
182         time++;
183         if (time > CLOCK_TEST_WAIT_TIMEOUT) {
184             break;
185         }
186     }
187     return ret;
188 }
189 
ClockTestDisable(void)190 static int32_t ClockTestDisable(void)
191 {
192     struct ClockTester *tester = NULL;
193     int32_t ret;
194 
195     HDF_LOGI("ClockTestDisable: enter!");
196     tester = ClockTesterGet();
197     if (tester == NULL) {
198         HDF_LOGE("ClockTestDisable: get tester fail!");
199         return HDF_ERR_INVALID_OBJECT;
200     }
201 
202     ret = ClockDisable(tester->handle);
203 
204     HDF_LOGI("ClockTestDisable: done!");
205     return ret;
206 }
207 
ClockTestSetrate(void)208 static int32_t ClockTestSetrate(void)
209 {
210     struct ClockTester *tester = NULL;
211     int32_t ret;
212 
213     HDF_LOGI("ClockTestSetrate: enter!");
214     tester = ClockTesterGet();
215     if (tester == NULL) {
216         HDF_LOGE("ClockTestSetrate: get tester fail!");
217         return HDF_ERR_INVALID_OBJECT;
218     }
219 
220     ret = ClockSetRate(tester->handle, DEFAULT_RATE);
221 
222     HDF_LOGI("ClockTestSetrate: done!");
223     return ret;
224 }
225 
ClockTestGetrate(void)226 static int32_t ClockTestGetrate(void)
227 {
228     struct ClockTester *tester = NULL;
229     int32_t ret;
230     uint32_t rate;
231 
232     HDF_LOGI("ClockTestGetrate: enter!");
233     tester = ClockTesterGet();
234     if (tester == NULL) {
235         HDF_LOGE("ClockTestGetrate: get tester fail!");
236         return HDF_ERR_INVALID_OBJECT;
237     }
238 
239     ret = ClockGetRate(tester->handle, &rate);
240 
241     HDF_LOGI("ClockTestGetrate: done!");
242     return ret;
243 }
244 
ClockTestGetparent(void)245 static int32_t ClockTestGetparent(void)
246 {
247     struct ClockTester *tester = NULL;
248 
249     HDF_LOGI("ClockTestGetparent: enter!");
250     tester = ClockTesterGet();
251     if (tester == NULL) {
252         HDF_LOGE("ClockTestGetparent: get tester fail!");
253         return HDF_ERR_INVALID_OBJECT;
254     }
255 
256     parent = ClockGetParent(tester->handle);
257 
258     HDF_LOGI("ClockTestGetparent: done!");
259     return HDF_SUCCESS;
260 }
261 
ClockTestSetparent(void)262 static int32_t ClockTestSetparent(void)
263 {
264     struct ClockTester *tester = NULL;
265     int32_t ret;
266 
267     HDF_LOGI("ClockTestSetparent: enter!");
268     tester = ClockTesterGet();
269     if (tester == NULL) {
270         HDF_LOGE("ClockTestSetparent: get tester fail!");
271         return HDF_ERR_INVALID_OBJECT;
272     }
273 
274     ret = ClockSetParent(tester->handle, parent);
275 
276     HDF_LOGI("ClockTestSetparent: done!");
277     return ret;
278 }
279 
ClockTestMultiThread(void)280 static int32_t ClockTestMultiThread(void)
281 {
282     int32_t ret;
283     struct OsalThread thread1;
284     struct OsalThread thread2;
285     int32_t count1 = 0;
286     int32_t count2 = 0;
287 
288     ret = OsalThreadCreate(&thread1, (OsalThreadEntry)ClockTestThreadFunc, (void *)&count1);
289     if (ret != HDF_SUCCESS) {
290         HDF_LOGE("ClockTestMultiThread: create test thread1 fail, ret: %d!", ret);
291         return ret;
292     }
293 
294     ret = OsalThreadCreate(&thread2, (OsalThreadEntry)ClockTestThreadFunc, (void *)&count2);
295     if (ret != HDF_SUCCESS) {
296         (void)OsalThreadDestroy(&thread1);
297         HDF_LOGE("ClockTestMultiThread: create test thread2 fail, ret: %d!", ret);
298         return ret;
299     }
300 
301     ret = ClockTestStartThread(&thread1, &thread2, &count1, &count2);
302     if (ret != HDF_SUCCESS) {
303         HDF_LOGE("ClockTestStartThread: test start thread fail, ret: %d!", ret);
304     }
305 
306     (void)OsalThreadDestroy(&thread1);
307     (void)OsalThreadDestroy(&thread2);
308     return HDF_SUCCESS;
309 }
310 
ClockTestReliability(void)311 static int32_t ClockTestReliability(void)
312 {
313     uint32_t rate;
314     HDF_LOGI("ClockTestReliability: enter!");
315     // invalid handle
316     ClockEnable(NULL);
317     // invalid handle
318     ClockDisable(NULL);
319     // invalid handle
320     ClockSetRate(NULL, DEFAULT_RATE);
321     // invalid handle
322     ClockGetRate(NULL, &rate);
323     // invalid handle
324     ClockGetParent(NULL);
325     // invalid handle
326     ClockSetParent(NULL, NULL);
327     HDF_LOGI("ClockTestReliability: done!");
328     return HDF_SUCCESS;
329 }
330 
ClockIfPerformanceTest(void)331 static int32_t ClockIfPerformanceTest(void)
332 {
333 #ifdef __LITEOS__
334     // liteos the accuracy of the obtained time is too large and inaccurate.
335     return HDF_SUCCESS;
336 #endif
337     struct ClockTester *tester = NULL;
338     uint64_t startMs;
339     uint64_t endMs;
340     uint64_t useTime; // ms
341     int32_t ret;
342 
343     tester = ClockTesterGet();
344     if (tester == NULL || tester->handle == NULL) {
345         HDF_LOGE("ClockIfPerformanceTest: get tester fail!");
346         return HDF_ERR_INVALID_OBJECT;
347     }
348 
349     startMs = OsalGetSysTimeMs();
350     ret = ClockEnable(tester->handle);
351     if (ret == HDF_SUCCESS) {
352         endMs = OsalGetSysTimeMs();
353         useTime = endMs - startMs;
354         HDF_LOGI("ClockIfPerformanceTest: ----->interface performance test:[start - end] < 1ms[%s]\r\n",
355                  useTime < 1 ? "yes" : "no");
356         return HDF_SUCCESS;
357     }
358     return HDF_SUCCESS;
359 }
360 
361 struct ClockTestEntry {
362     int cmd;
363     int32_t (*func)(void);
364     const char *name;
365 };
366 
367 static struct ClockTestEntry g_entry[] = {
368     {CLOCK_TEST_CMD_ENABLE, ClockTestEnable, "ClockTestEnable"},
369     {CLOCK_TEST_CMD_DISABLE, ClockTestDisable, "ClockTestDisable"},
370     {CLOCK_TEST_CMD_SET_RATE, ClockTestSetrate, "ClockTestSetrate"},
371     {CLOCK_TEST_CMD_GET_RATE, ClockTestGetrate, "ClockTestGetrate"},
372     {CLOCK_TEST_CMD_GET_PARENT, ClockTestGetparent, "ClockTestGetparent"},
373     {CLOCK_TEST_CMD_SET_PARENT, ClockTestSetparent, "ClockTestSetparent"},
374     {CLOCK_TEST_CMD_MULTI_THREAD, ClockTestMultiThread, "ClockTestMultiThread"},
375     {CLOCK_TEST_CMD_RELIABILITY, ClockTestReliability, "ClockTestReliability"},
376     {CLOCK_IF_PERFORMANCE_TEST, ClockIfPerformanceTest, "ClockIfPerformanceTest"},
377 };
378 
ClockTestExecute(int cmd)379 int32_t ClockTestExecute(int cmd)
380 {
381     uint32_t i;
382     int32_t ret = HDF_ERR_NOT_SUPPORT;
383 
384     if (cmd > CLOCK_TEST_CMD_MAX) {
385         HDF_LOGE("ClockTestExecute: invalid cmd:%d!", cmd);
386         ret = HDF_ERR_NOT_SUPPORT;
387         HDF_LOGE("[ClockTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
388         return ret;
389     }
390 
391     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
392         if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
393             continue;
394         }
395         ret = g_entry[i].func();
396         break;
397     }
398 
399     HDF_LOGE("[ClockTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
400     return ret;
401 }
402