2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <asm/unistd.h>
25 #include <native_service/frameworkunified_types.h>
27 #include <vehicle_service/positioning_base_library.h>
28 #include "_pbInternalProc.h"
29 #include <other_service/VP_GetEnv.h>
30 #include "WPF_STD_private.h"
35 /*---------------------------------------------------------------------------------*
37 *---------------------------------------------------------------------------------*/
39 #define POS_BASE_OTHER_PROC_ID "POS_BASE_OTHER_PROC_ID"
41 #define MAX_OTHER_PROC_NUM (32) /** Maximum number of the management information to translate the process name to PNO */
42 #define MAX_NUM_CTRL_TID (16) /** Maximum number of tje TID management for thread in Process */
44 #define OTHER_PNO_BASE (0x9000) /** Base number of local process */
46 #define THREAD_NAME_LEN_MAX (32)
48 #define FULL_OTHER_PROC_NUM (MAX_OTHER_PROC_NUM - 4) /** Threshold of the management information to translate the process name to PNO (no free) */
49 #define WARN_OTHER_PROC_NUM (MAX_OTHER_PROC_NUM - 10) /** Threshold of the management information to translate the process name to PNO (warning) */
51 typedef void* (*_CWORD64_PROCMNG_START_ROUTINE)(void*);
53 /*---------------------------------------------------------------------------------*
55 *---------------------------------------------------------------------------------*/
57 @brief Process identification information
60 PNO pno; /**< Process number */
61 char name[THREAD_NAME_LEN_MAX]; /**< Process name */
65 @brief Process information
68 PROC_ID id[MAX_OTHER_PROC_NUM]; /**< Process identification information */
69 uint32_t use_cnt; /**< Used number */
70 uint32_t rsv_cnt; /**< Reserved number */
73 /*---------------------------------------------------------------------------------*
75 *---------------------------------------------------------------------------------*/
76 static HANDLE g_h_app[MAX_NUM_CTRL_TID]; /** Application handle */
77 static HANDLE g_h_mtx; /** Shared-information-locking Mutex handle */
78 static HANDLE g_h_shm; /** Shared memory handle */ // Coverity CID: 18787 compliant
80 static PROC_INFO* g_p_proc_id_tbl; /** Process Name-PNO Translation Table */
82 /*---------------------------------------------------------------------------------*
83 * Internal Function Prototype *
84 *---------------------------------------------------------------------------------*/
85 /* Process number to PNO translation table manipulation functions */
86 static void OtherSetPnoOfCnvTbl(u_int32 idx, PNO pno);
87 static void OtherSetNameOfCnvTbl(u_int32 idx, PCSTR name);
88 static PNO OtherGetPnoOfCnvTbl(u_int32 idx);
89 static PCSTR OtherGetNameOfCnvTbl(u_int32 idx);
90 static u_int32 OtherSearchPnoOfCnvTbl(PNO pno);
91 static u_int32 OtherSearchNameOfCnvTbl(PCSTR name);
92 static void OtherIncUseCntOfCnvTbl(void);
93 static void OtherIncRsvCntOfCnvTbl(void);
94 static void OtherDecRsvCntOfCnvTbl(void);
96 static void OtherCreateMutex(void);
97 static void OtherDeleteMutex(void);
98 static void OtherLockMutex(void);
99 static void OtherUnlockMutex(void);
103 * Initialize other funtion
105 * @return RET_NORMAL Normal completion
107 RET_API ErrTrapInit(void) {
108 RET_API ret_api = RET_NORMAL;
112 pp_tbl = &g_p_proc_id_tbl; /* Set a pointer to a table to translate the process name to PNO */
114 OtherCreateMutex(); /* Create Mutex for accessing shared info */
115 OtherLockMutex(); /* Acquire Mutex for accessing shared info */
117 /* Open shared memory for a table to translate the process name to PNO */
118 g_h_shm = OpenSharedMemory(const_cast<char*>(POS_BASE_OTHER_PROC_ID), sizeof(PROC_INFO));
120 /* If called for the first time within all processes, an error occurs and the following processing is performed. */
121 if (g_h_shm == NULL) { // LCOV_EXCL_BR_LINE 200: can not be not NULL
122 /* Create shared memory for a table to translate the name to PNO */
123 g_h_shm = CreateSharedMemory(const_cast<char*>(POS_BASE_OTHER_PROC_ID), sizeof(PROC_INFO));
124 /* In case of an error */
125 if (g_h_shm == NULL) { // LCOV_EXCL_BR_LINE 200: can not be NULL
126 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_pb_CreateShareData ERROR " \
127 "[g_h_shm:%p]", g_h_shm);
128 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
129 _pb_Exit(); // // LCOV_EXCL_LINE 200: can not be NULL
130 /* don't arrive here. */
134 OtherUnlockMutex(); /* Release Mutex for accessing shared info */
136 /* Set the acquired shared memory address as a pointer for a table to translate the process name to PNO */
137 *pp_tbl = reinterpret_cast<PROC_INFO*>(GetSharedMemoryPtr(g_h_shm));
139 /* Table initialization */
140 for (idx = 0; idx < MAX_OTHER_PROC_NUM; idx++) {
141 /* Set PNO into the table to translate the process name to PNO (Overwrite from the second process onwards) */
142 OtherSetPnoOfCnvTbl(idx, static_cast<PNO>(OTHER_PNO_BASE + idx));
150 * Terminate other function
152 void ErrTrapTerm(void) { // LCOV_EXCL_START 8:dead code
153 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
154 CloseSharedMemory(g_h_shm);
164 * @param[in] lp_thread_attributes Not used
165 * @param[in] dw_stack_size Initial stack size
166 * @param[in] lp_start_address Address of the effective function of the thread
167 * @param[in] lp_parameter Thread arguments
168 * @param[in] dw_creation_flags Not used
169 * @param[in] lp_thread_id Thread identifier
171 * @param[in] priority Thread priority
173 * @return Non-zero:Normal status, 0:When an error occurs
175 HANDLE _pb_CreateThread(LPSECURITY_ATTRIBUTES lp_thread_attributes, DWORD dw_stack_size, LPTHREAD_START_ROUTINE lp_start_address, LPVOID lp_parameter, DWORD dw_creation_flags, LPDWORD lp_thread_id, PNO pno, int32 priority) { // LCOV_EXCL_START 8:dead code // NOLINT(whitespace/line_length)
176 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
177 pthread_attr_t st_thread_attr;
178 pthread_t ul_thread_id = 0;
179 sched_param st_thread_param = {0};
180 HANDLE handle = NULL;
185 if (lp_thread_id == NULL) {
188 /* Initializing Attributes */
189 lret = pthread_attr_init(&st_thread_attr);
191 /* When the attribute initialization is successful */
193 /* Do not inherit parent scheduling policies */
194 lret = pthread_attr_setinheritsched(&st_thread_attr, PTHREAD_EXPLICIT_SCHED);
197 /* If you successfully configure policy inheritance */
199 /* Scheduling settings */
200 lret = pthread_attr_setschedpolicy(&st_thread_attr, SCHED_RR);
203 /* Successful Scheduling settings */
205 /* Create a thread with the lowest priority so that the spawned thread */
206 /* do not run until they are ready for processing */
207 st_thread_param.sched_priority = 1;
208 lret = pthread_attr_setschedparam(&st_thread_attr, &st_thread_param);
211 /* If the priority setting is successful */
213 lret = pthread_create(&ul_thread_id,
215 (_CWORD64_PROCMNG_START_ROUTINE)lp_start_address,
219 /* Successful pthread_create */
225 /* When priority setting is successful */
227 /* Return value setting */
228 handle = (HANDLE)ul_thread_id;
229 *lp_thread_id = ul_thread_id;
231 /* Error log output */
232 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lret ERROR [lret:%d]", lret);
245 uint32_t PbGetTid(void) {
248 ul_tid = (uint32_t)syscall(__NR_gettid);
255 * Get the local thread ID
257 * Local thread ID = [0, 1, 2, ...]<br>
258 * The local thread ID is unique in the process, and dynamically assigned in the order in which <br>
259 * this API was called during the process execution. <br>
261 * @return Local thread ID
263 uint32_t PbGetLocalTid(void) {
264 static uint32_t g_tid[MAX_NUM_CTRL_TID] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
265 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
266 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
267 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
268 }; /** In-process thread ID management table */
272 uint32_t ul_local_tid = 0xFFFFFFFF;
276 OtherLockMutex(); /* Get Mutex for accessing shared info */
278 for (ul_idx = 0; ul_idx < MAX_NUM_CTRL_TID; ul_idx++) {
279 if (g_tid[ul_idx] == ul_tid) {
280 ul_local_tid = ul_idx;
284 if (ul_local_tid == 0xFFFFFFFF) {
285 for (ul_idx = 0; ul_idx < MAX_NUM_CTRL_TID; ul_idx++) {
286 if (g_tid[ul_idx] == 0xFFFFFFFF) {
287 g_tid[ul_idx] = ul_tid;
288 ul_local_tid = ul_idx;
294 if (ul_local_tid == 0xFFFFFFFF) {
296 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Local Tid buffer is overfull!!");
299 /* don't arrive here. */
303 OtherUnlockMutex(); /* Release Mutex for accessing shared info */
311 * Get Application Handle
313 * Get the application handle of the invoking thread.
315 * @return Non-zero:Normal status, 0:When an error occurs
317 HANDLE _pb_GetAppHandle(void) { // NOLINT(readability/nolint) WPF_SYSAPI.h API
318 const uint32_t offset = PbGetLocalTid();
320 return g_h_app[offset];
326 * Set Application Handle
328 * Set the application handle of the invoking thread.
330 * @param[in] name Process name
332 void _pb_SetAppHandle(HANDLE h_app) { // NOLINT(readability/nolint) WPF_SYSAPI.h API
333 const uint32_t offset = PbGetLocalTid();
335 OtherLockMutex(); /* Get Mutex for accessing shared info */
337 g_h_app[offset] = h_app;
339 OtherUnlockMutex(); /* Release Mutex for accessing shared info */
347 * Convert process name to pno
349 * Translate process name to PNO.<br>
350 * If the process name specified in the argument is the first name to <br>
351 * be translated by this API, a new PNO is assigned and returned. <br>
352 * If NULL is specified, 0 is returned.
354 * @param[in] name Process name
356 * @return Process number
358 PNO _pb_CnvName2Pno(PCSTR name) { // NOLINT(readability/nolint) WPF_SYSAPI.h API
368 if (len >= THREAD_NAME_LEN_MAX) {
369 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Argument ERROR!! " \
370 "Length of thread name is too long(>=%d). [len:%zu]", THREAD_NAME_LEN_MAX, len);
374 idx = OtherSearchNameOfCnvTbl(name);
376 if (idx != MAX_OTHER_PROC_NUM) {
377 pno = OtherGetPnoOfCnvTbl(idx);
379 idx = OtherSearchNameOfCnvTbl("");
380 OtherSetNameOfCnvTbl(idx, name);
381 /* Increment using-counter */
382 OtherIncUseCntOfCnvTbl();
383 pno = OtherGetPnoOfCnvTbl(idx);
395 * Convert pno to process name
397 * Translate PNO to the process name.
398 * Return the process name set by _pb_CnvName2Pno to the PNO argument.
399 * If a non-PNO value is given by _pb_CnvName2Pno is specified,
402 * @param[in] pno Process number
404 * @return Process name
406 PCSTR _pb_CnvPno2Name(PNO pno) { // NOLINT(readability/nolint) WPF_SYSAPI.h API
412 idx = OtherSearchPnoOfCnvTbl(pno);
414 if (idx != MAX_OTHER_PROC_NUM) {
415 name = OtherGetNameOfCnvTbl(idx);
426 * Get environment variables
428 * @param[in] Environment variable name
429 * @param[in] Pointer to environment variable value
431 void GetEnv(const char* p_env_str, char* p_env_buff) { // LCOV_EXCL_START 8:dead code
432 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
433 VP_GetEnv(p_env_str, p_env_buff);
435 FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "VP_GetEnv:%s=%s", p_env_str, p_env_buff);
441 /*---------------------------------------------------------------------------------*
443 *---------------------------------------------------------------------------------*/
446 * PNO setting(The table to translate the process name to PNO)
448 * If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
450 * @param[in] u_int32 idx Table accessor
451 * @param[in] PNO pno Process number
455 static void OtherSetPnoOfCnvTbl(u_int32 idx, PNO pno) {
457 if (idx >= MAX_OTHER_PROC_NUM) { // LCOV_EXCL_BR_LINE 6: idx cannot greater
459 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Argment ERROR [idx:%d, pno:%d]", idx, pno);
460 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
461 _pb_Exit(); // LCOV_EXCL_LINE 6: idx cannot greater
462 /* don't arrive here. */
465 g_p_proc_id_tbl->id[idx].pno = pno;
472 * Set process name (The table to translate the process name to PNO)
474 * If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
476 * @param[in] u_int32 idx Table accessor
477 * @param[in] PCSTR name Process name
481 static void OtherSetNameOfCnvTbl(u_int32 idx, PCSTR name) {
483 if (idx >= MAX_OTHER_PROC_NUM) { // LCOV_EXCL_BR_LINE 6: idx cannot greater
485 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Argment ERROR [idx:%d, name:%s]", idx, name);
486 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
487 _pb_Exit(); // LCOV_EXCL_LINE 6: idx cannot greater
488 /* don't arrive here. */
490 _tcscpy(g_p_proc_id_tbl->id[idx].name, name);
498 * Get PNO (The table to translate the process name to PNO)
500 * If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
502 * @param[in] u_int32 idx Table accessor
506 static PNO OtherGetPnoOfCnvTbl(u_int32 idx) {
508 if (idx >= MAX_OTHER_PROC_NUM) { // LCOV_EXCL_BR_LINE 6: idx cannot greater
510 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Argment ERROR [idx:%d]", idx);
511 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
512 _pb_Exit(); // LCOV_EXCL_LINE 6: idx cannot greater
513 /* don't arrive here. */
516 return g_p_proc_id_tbl->id[idx].pno;
521 * Get process name (The table to translate the process name to PNO)
523 * If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
525 * @param[in] u_int32 idx Table accessor
529 static PCSTR OtherGetNameOfCnvTbl(u_int32 idx) {
531 if (idx >= MAX_OTHER_PROC_NUM) { // LCOV_EXCL_BR_LINE 6: idx cannot greater
533 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Argment ERROR [idx:%d]", idx);
534 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
535 _pb_Exit(); // LCOV_EXCL_LINE 6: idx cannot greater
536 /* don't arrive here. */
539 return g_p_proc_id_tbl->id[idx].name;
544 * Retrieve PNO (The table to translate the process name to PNO)
546 * If the PNO specified in the argument exists in the table, return the index for access.
547 * If not exists, return the maximum number of local PNO controls (MAX_OTHER_PROC_NUM).
549 * @param[in] PNO pno Process number
551 * @return u_int32 Table accessor
553 static u_int32 OtherSearchPnoOfCnvTbl(PNO pno) {
557 for (idx = 0; idx < MAX_OTHER_PROC_NUM; idx++) {
558 lPno = OtherGetPnoOfCnvTbl(idx);
570 * Retrieve process name (The table to translate the process name to PNO)
572 * If the process specified by the argument exists in the table, return the index for access.
573 * If not exists, return the maximum number of local PNO controls (MAX_OTHER_PROC_NUM).
575 * @param[in] PCSTR name Process name
577 * @return u_int32 Table accessor
579 static u_int32 OtherSearchNameOfCnvTbl(PCSTR name) {
583 for (idx = 0; idx < MAX_OTHER_PROC_NUM; idx++) {
584 ret = _tcscmp(g_p_proc_id_tbl->id[idx].name, name);
586 /* If there is a match */
598 * Create Mutex for accessing shared info
604 static void OtherCreateMutex(void) {
605 g_h_mtx = _pb_CreateMutex(NULL, 0, "Other_Mutex");
606 if (g_h_mtx == NULL) {
607 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_pb_CreateMutex ERROR [g_h_mtx:%p]", g_h_mtx);
609 /* don't arrive here. */
617 * Delete Mutex for accessing shared info
623 static void OtherDeleteMutex(void) { // LCOV_EXCL_START 8:dead code
624 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
626 ret = PbDeleteMutex(g_h_mtx);
627 if (ret != WAIT_OBJECT_0) {
628 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "PbDeleteMutex ERROR " \
629 "[ret:%lu, g_h_mtx:%p]", ret, g_h_mtx);
631 /* don't arrive here. */
640 * Get Mutex for accessing shared info
646 static void OtherLockMutex(void) {
648 ret = PbMutexLock(g_h_mtx, INFINITE);
649 if (ret != WAIT_OBJECT_0) {
650 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "PbMutexLock ERROR " \
651 "[ret:%lu, g_h_mtx:%p]", ret, g_h_mtx);
653 /* don't arrive here. */
661 * Open Mutex for Accessing Shared Info
667 static void OtherUnlockMutex(void) {
669 ret = PbMutexUnlock(g_h_mtx);
671 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "PbMutexUnlock ERROR " \
672 "[ret:%d, g_h_mtx:%p]", ret, g_h_mtx);
674 /* don't arrive here. */
682 * Get dump information
684 * @param[out] pBuf Dump info
686 void _pb_GetDebugOtherMngTbl(void* pBuf) {
687 static uint8_t buf[DEBUG_DUMP_MAX_SIZE];
688 static uint8_t bufTmp[64];
692 memset(&buf[0], 0x00, sizeof(buf));
693 snprintf(reinterpret_cast<char *>(&buf[0]), sizeof(buf), "Other");
694 if (g_p_proc_id_tbl == NULL) { // LCOV_EXCL_BR_LINE 200: g_p_proc_id_tbl can not be NULL
695 // LCOV_EXCL_START 200: g_p_proc_id_tbl can not be NULL
696 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
697 strncat(reinterpret_cast<char *>(&buf[0]), "\n NULL", strlen("\n NULL"));
700 for (i = 0; i < MAX_OTHER_PROC_NUM; i++) {
701 memset(&bufTmp[0], 0x00, sizeof(bufTmp));
702 snprintf(reinterpret_cast<char *>(&bufTmp[0]), sizeof(bufTmp),
703 "\n [%02d] pno:0x%04x, name:%s",
705 g_p_proc_id_tbl->id[i].pno,
706 g_p_proc_id_tbl->id[i].name);
707 strncat(reinterpret_cast<char *>(&buf[0]), reinterpret_cast<char *>(&bufTmp[0]), \
708 strlen(reinterpret_cast<char *>(&bufTmp[0])));
711 memcpy(pBuf, &buf[0], sizeof(buf));
717 * Increment the usage counter of the table to translate process name to PNO
721 static void OtherIncUseCntOfCnvTbl(void) {
722 g_p_proc_id_tbl->use_cnt++;
728 * Increment the counter to reserve the table to translate the process name to PNO
732 static void OtherIncRsvCntOfCnvTbl(void) {
733 g_p_proc_id_tbl->rsv_cnt++;
739 * Decrement the counter to reserve the table to translate the process name to PNO
743 static void OtherDecRsvCntOfCnvTbl(void) {
744 g_p_proc_id_tbl->rsv_cnt--;
750 * Determine resources ready (The table to translate the process name to PNO)
755 * @retval TRUE : Normal
756 * @retval FALSE : Error (Resource shortage)
758 BOOL _pb_GetOtherResource(void) {
764 /* Increment reserved counter */
765 OtherIncRsvCntOfCnvTbl();
767 cnt = g_p_proc_id_tbl->use_cnt + g_p_proc_id_tbl->rsv_cnt;
768 if (cnt >= FULL_OTHER_PROC_NUM) {
770 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Lack of resources " \
771 "[FATAL][use_cnt:%d rsv_cnt:%d]", g_p_proc_id_tbl->use_cnt, g_p_proc_id_tbl->rsv_cnt);
772 } else if (cnt >= WARN_OTHER_PROC_NUM) {
773 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Lack of resources " \
774 "[WARN][use_cnt:%d rsv_cnt:%d]", g_p_proc_id_tbl->use_cnt, g_p_proc_id_tbl->rsv_cnt);
784 * Release resources (The table to translate process name to PNO)
790 void _pb_ReleaseOtherResource(void) {
793 /* Decrement reserved counter */
794 OtherDecRsvCntOfCnvTbl();