• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 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 "hdf_message_test.h"
10 #include "message/message_types.h"
11 #include "message/message_router.h"
12 #include "message/sidecar.h"
13 #include "hdf_log.h"
14 #include "hdf_sbuf.h"
15 #include "osal_time.h"
16 
17 const uint32_t SEND_MESSAGE_COUNT = 40000;
18 const uint32_t SYNC_MESSAGE_TIMEOUT = 2;
19 const uint32_t ASYNC_MESSAGE_TIMEOUT = 8;
20 #define COMMON_SEM_TIMEOUT 300
21 
22 enum ServiceList {
23     SERVICE_ID_A = 10,
24     SERVICE_ID_B
25 };
26 
27 const uint8_t CUSTOM_DISPATCHER_ID = 1;
28 const uint8_t SINGLE_NODE_TEST_CUSTOM_DISPATCHER_PRIORITYLEVEL = 4;
29 const uint32_t SINGLE_NODE_TEST_CUSTOM_DISPATCHER_QUEUESIZE = 10000;
30 
31 const uint16_t SMALL_LOAD_WAIT_TIME = 500;
32 
33 
34 #define CMD_LIST_MAX_SIZE 32
35 uint8_t g_cmdList[CMD_LIST_MAX_SIZE];
36 uint8_t g_cmdListCount = 0;
37 
ClearRecvQueue(void)38 void ClearRecvQueue(void)
39 {
40     g_cmdListCount = 0;
41 }
42 
GetCMDByIndex(uint8_t index)43 uint8_t GetCMDByIndex(uint8_t index)
44 {
45     return g_cmdList[index];
46 }
47 
GetRecvQueueSize(void)48 size_t GetRecvQueueSize(void)
49 {
50     return g_cmdListCount;
51 }
52 
FuncNoLoad(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)53 static ErrorCode FuncNoLoad(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
54 {
55     (void)reqData;
56     (void)rspData;
57     (void)context;
58     return ME_SUCCESS;
59 }
60 
FuncSmallLoad(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)61 static ErrorCode FuncSmallLoad(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
62 {
63     if (context == NULL) {
64         HDF_LOGE("%s:FuncSmallLoad context NULL!", __func__);
65         return HDF_FAILURE;
66     }
67     (void)reqData;
68     (void)rspData;
69     HDF_LOGI("Handle message %d\n", context->commandId);
70 
71     OsalMSleep(SMALL_LOAD_WAIT_TIME);
72     if (g_cmdListCount >= CMD_LIST_MAX_SIZE) {
73         HDF_LOGE("%s:Too much cmd!", __func__);
74         return HDF_FAILURE;
75     }
76     g_cmdList[g_cmdListCount++] = context->commandId;
77     HDF_LOGI("Finish handle message %d\n", context->commandId);
78     return ME_SUCCESS;
79 }
80 
81 static struct MessageDef g_testServiceACmds[] = {
82     DUEMessage(0, FuncNoLoad, 1)
83 };
84 
85 ServiceDefine(TestServiceA, SERVICE_ID_A, g_testServiceACmds);
86 
87 static struct MessageDef g_testServiceBCmds[] = {
88     DUEMessage(0, FuncNoLoad, 2), // commandId = 0
89     DUEMessage(1, FuncSmallLoad, 0),
90     DUEMessage(2, FuncSmallLoad, 1),
91     DUEMessage(3, FuncSmallLoad, 2),
92     DUEMessage(4, FuncSmallLoad, 3),
93 };
94 
95 ServiceDefine(TestServiceB, SERVICE_ID_B, g_testServiceBCmds);
96 
97 Service *g_serviceA = NULL;
98 Service *g_serviceB = NULL;
99 bool g_dispatcherInited = false;
100 
StartEnv(void)101 static int32_t StartEnv(void)
102 {
103     int32_t errCode;
104     if (!g_dispatcherInited) {
105         DispatcherConfig config = {
106             .dispatcherId = CUSTOM_DISPATCHER_ID,
107             .priorityLevelCount = SINGLE_NODE_TEST_CUSTOM_DISPATCHER_PRIORITYLEVEL,
108             .queueSize = SINGLE_NODE_TEST_CUSTOM_DISPATCHER_QUEUESIZE
109         };
110         MSG_RETURN_IF_FUNCTION_FAILED(errCode, AddDispatcher(&config));
111         g_dispatcherInited = true;
112     }
113     if (g_serviceA == NULL) {
114         ServiceCfg cfgA = {
115             .dispatcherId = DEFAULT_DISPATCHER_ID
116         };
117         g_serviceA = CreateService(TestServiceA, &cfgA);
118         MSG_RETURN_IF(g_serviceA == NULL);
119     }
120 
121     if (g_serviceB == NULL) {
122         ServiceCfg cfgB = {
123             .dispatcherId = CUSTOM_DISPATCHER_ID
124         };
125         g_serviceB = CreateService(TestServiceB, &cfgB);
126         MSG_RETURN_IF(g_serviceB == NULL);
127     }
128     return HDF_SUCCESS;
129 }
130 
StopEnv(void)131 static int32_t StopEnv(void)
132 {
133     if (g_serviceA != NULL) {
134         if (g_serviceA->Destroy != NULL) {
135             g_serviceA->Destroy(g_serviceA);
136         }
137         g_serviceA = NULL;
138     }
139 
140     if (g_serviceB != NULL) {
141         if (g_serviceB->Destroy != NULL) {
142             g_serviceB->Destroy(g_serviceB);
143         }
144         g_serviceB = NULL;
145     }
146     return HDF_SUCCESS;
147 }
148 
149 // Repeated register
MessageSingleNodeTest001(void)150 int32_t MessageSingleNodeTest001(void)
151 {
152     ErrorCode errCode = HDF_SUCCESS;
153     ErrorCode errShutdown = HDF_SUCCESS;
154     Service *service = NULL;
155 
156     do {
157         ServiceCfg cfgB = {
158             .dispatcherId = CUSTOM_DISPATCHER_ID
159         };
160 
161         MSG_RETURN_IF_FUNCTION_FAILED(errCode, StartEnv());
162 
163         service = CreateService(TestServiceB, &cfgB);
164         MSG_BREAK_IF(errCode, service != NULL);
165     } while (false);
166 
167     MSG_RETURN_IF_FUNCTION_FAILED(errShutdown, StopEnv());
168     if (service != NULL) {
169         if (service->Destroy != NULL) {
170             service->Destroy(service);
171         }
172         service = NULL;
173     }
174     return errCode;
175 }
176 
177 // Sync message test
MessageSingleNodeTest002(void)178 int32_t MessageSingleNodeTest002(void)
179 {
180     ErrorCode errCode = HDF_SUCCESS;
181     ErrorCode errShutdown = HDF_SUCCESS;
182     struct HdfSBuf *rspData = NULL;
183 
184     do {
185         MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
186 
187         MSG_BREAK_IF(errCode, g_serviceA == NULL);
188 
189         rspData = HdfSbufObtainDefaultSize();
190 
191         MSG_BREAK_IF_FUNCTION_FAILED(errCode, g_serviceA->SendSyncMessage(g_serviceA, SERVICE_ID_B, 0, NULL, rspData));
192     } while (false);
193 
194     if (rspData != NULL) {
195         HdfSbufRecycle(rspData);
196         rspData = NULL;
197     }
198 
199     MSG_RETURN_IF_FUNCTION_FAILED(errShutdown, StopEnv());
200 
201     return errCode;
202 }
203 
204 
205 // Sync Perf test
MessageSingleNodeTest003(void)206 int32_t MessageSingleNodeTest003(void)
207 {
208     ErrorCode errCode = HDF_SUCCESS;
209     ErrorCode errShutdown = HDF_SUCCESS;
210     uint32_t i;
211     struct HdfSBuf *rspData = NULL;
212     struct HdfSBuf *sendData = NULL;
213     do {
214         OsalTimespec startTime;
215         OsalTimespec endTime;
216         OsalTimespec diffTime;
217         MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
218         MSG_BREAK_IF(errCode, g_serviceA == NULL);
219         rspData = HdfSbufObtainDefaultSize();
220         sendData = HdfSbufObtainDefaultSize();
221 
222         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&startTime));
223         for (i = 0; i < SEND_MESSAGE_COUNT; i++) {
224             MSG_BREAK_IF_FUNCTION_FAILED(errCode,
225                 g_serviceA->SendSyncMessage(g_serviceA, SERVICE_ID_B, 0, sendData, rspData));
226         }
227         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&endTime));
228 
229         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalDiffTime(&startTime, &endTime, &diffTime));
230 
231         HDF_LOGI("Process time %llu \n", diffTime.sec);
232         MSG_BREAK_IF(errCode, diffTime.sec > SYNC_MESSAGE_TIMEOUT);
233     } while (false);
234 
235     if (rspData != NULL) {
236         HdfSbufRecycle(rspData);
237         rspData = NULL;
238     }
239 
240     if (sendData != NULL) {
241         HdfSbufRecycle(sendData);
242         sendData = NULL;
243     }
244 
245     MSG_RETURN_IF_FUNCTION_FAILED(errShutdown, StopEnv());
246 
247     return errCode;
248 }
249 
250 OSAL_DECLARE_SEMAPHORE(g_callBackSem);
251 
SendMessageTestCallBack(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData,ErrorCode rspCode)252 static void SendMessageTestCallBack(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData,
253     ErrorCode rspCode)
254 {
255     if (context == NULL) {
256         HDF_LOGE("%s:SendMessageTestCallBack context NULL!", __func__);
257         return;
258     }
259     (void)reqData;
260     (void)rspData;
261     (void)rspCode;
262     OsalSemPost(&g_callBackSem);
263     HDF_LOGI("Receive response for CMD %d.\n", context->commandId);
264 }
265 
MessageSingleNodeTest004(void)266 int32_t MessageSingleNodeTest004(void)
267 {
268     ErrorCode errCode = HDF_SUCCESS;
269     ErrorCode errShutdown = HDF_SUCCESS;
270 
271     do {
272         MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
273         MSG_BREAK_IF(errCode, g_serviceA == NULL);
274 
275         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemInit(&g_callBackSem, 0));
276 
277         MSG_BREAK_IF_FUNCTION_FAILED(errCode,
278             g_serviceA->SendAsyncMessage(g_serviceA, SERVICE_ID_B, 0, NULL, SendMessageTestCallBack));
279 
280         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemWait(&g_callBackSem, COMMON_SEM_TIMEOUT));
281     } while (false);
282     errShutdown = OsalSemDestroy(&g_callBackSem);
283     errShutdown = errShutdown | StopEnv();
284     if (errShutdown != HDF_SUCCESS) {
285         HDF_LOGE("%s:Destroy message semaphore failed! errShutdown=%d", __func__, errShutdown);
286     }
287 
288     return errCode;
289 }
290 
SendMessagePerfTestCallBack(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData,ErrorCode rspCode)291 static void SendMessagePerfTestCallBack(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData,
292     ErrorCode rspCode)
293 {
294     (void)context;
295     (void)reqData;
296     (void)rspData;
297     (void)rspCode;
298 
299     ErrorCode errCode = OsalSemPost(&g_callBackSem);
300     if (HDF_SUCCESS != errCode) {
301         HDF_LOGE("%s:Post sem failed!ret=%d", __func__, errCode);
302     }
303 }
304 
305 const uint32_t PERF_TEST_COUNT = 10000;
306 
MessageSingleNodeTest005(void)307 int32_t MessageSingleNodeTest005(void)
308 {
309     ErrorCode errCode = HDF_SUCCESS;
310     ErrorCode errShutdown = HDF_SUCCESS;
311     uint32_t i;
312 
313     do {
314         OsalTimespec startTime;
315         OsalTimespec endTime;
316         OsalTimespec diffTime;
317         MSG_BREAK_IF_FUNCTION_FAILED(errCode, StartEnv());
318         MSG_BREAK_IF(errCode, g_serviceA == NULL);
319 
320         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemInit(&g_callBackSem, 0));
321 
322         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&startTime));
323 
324         for (i = 0; i < PERF_TEST_COUNT; i++) {
325             MSG_BREAK_IF_FUNCTION_FAILED(errCode,
326                 g_serviceA->SendAsyncMessage(g_serviceA, SERVICE_ID_B, 0, NULL, SendMessagePerfTestCallBack));
327         }
328 
329         for (i = 0; i < PERF_TEST_COUNT; i++) {
330             MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalSemWait(&g_callBackSem, COMMON_SEM_TIMEOUT));
331         }
332 
333         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalGetTime(&endTime));
334 
335         MSG_BREAK_IF_FUNCTION_FAILED(errCode, OsalDiffTime(&startTime, &endTime, &diffTime));
336 
337         HDF_LOGW("Process time %llu \n", diffTime.sec);
338         MSG_BREAK_IF(errCode, diffTime.sec > ASYNC_MESSAGE_TIMEOUT);
339     } while (false);
340     errShutdown = OsalSemDestroy(&g_callBackSem);
341     errShutdown = errShutdown | StopEnv();
342     if (errShutdown != HDF_SUCCESS) {
343         HDF_LOGE("%s:Destroy message semaphore failed! errShutdown=%d", __func__, errShutdown);
344     }
345 
346     return errCode;
347 }
348