Init basesystem source codes.
[staging/basesystem.git] / video_in_hal / vehicleservice / positioning_base_library / library / src / _pbOther.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
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 /**
18  * @file
19  *    _pbOther.cpp
20  */
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <asm/unistd.h>
25 #include <native_service/frameworkunified_types.h>
26
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"
31 #include "tchar.h"
32
33
34
35 /*---------------------------------------------------------------------------------*
36  * Define                                                                          *
37  *---------------------------------------------------------------------------------*/
38 /* Shared memory */
39 #define POS_BASE_OTHER_PROC_ID    "POS_BASE_OTHER_PROC_ID"
40
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       */
43
44 #define OTHER_PNO_BASE          (0x9000) /** Base number of local process            */
45
46 #define THREAD_NAME_LEN_MAX     (32)
47
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) */
50
51 typedef void* (*_CWORD64_PROCMNG_START_ROUTINE)(void*);
52
53 /*---------------------------------------------------------------------------------*
54  * Structure                                                                       *
55  *---------------------------------------------------------------------------------*/
56 /*!
57   @brief    Process identification information
58  */
59 typedef struct {
60     PNO     pno;                        /**< Process number    */
61     char    name[THREAD_NAME_LEN_MAX];    /**< Process name        */
62 } PROC_ID;
63
64 /*!
65   @brief    Process information
66  */
67 typedef struct {
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       */
71 } PROC_INFO;
72
73 /*---------------------------------------------------------------------------------*
74  * Grobal Value                                                                    *
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
79
80 static PROC_INFO*    g_p_proc_id_tbl;    /** Process Name-PNO Translation Table    */
81
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);
95
96 static void OtherCreateMutex(void);
97 static void OtherDeleteMutex(void);
98 static void OtherLockMutex(void);
99 static void OtherUnlockMutex(void);
100
101 /**
102  * @brief
103  *  Initialize other funtion
104  *
105  * @return RET_NORMAL    Normal completion
106  */
107 RET_API ErrTrapInit(void) {
108     RET_API    ret_api = RET_NORMAL;
109     PROC_INFO **pp_tbl;
110     u_int16    idx;
111
112     pp_tbl = &g_p_proc_id_tbl; /* Set a pointer to a table to translate the process name to PNO */
113
114     OtherCreateMutex(); /* Create Mutex for accessing shared info */
115     OtherLockMutex(); /* Acquire Mutex for accessing shared info */
116
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));
119
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. */
131         }
132     }
133
134     OtherUnlockMutex(); /* Release Mutex for accessing shared info */
135
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));
138
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));
143     }
144
145     return ret_api;
146 }
147
148 /**
149  * @brief
150  *  Terminate other function
151  */
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);
155
156     OtherDeleteMutex();
157 }
158 // LCOV_EXCL_STOP
159
160 /**
161  * @brief
162  *   Create Thread
163  *
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
170  * @param[in]  pno                    PNO
171  * @param[in]  priority                Thread priority
172  *
173  * @return Non-zero:Normal status,  0:When an error occurs
174  */
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;
181     int32            lret = EOK;
182     BOOL            bret = FALSE;
183
184     /* null check */
185     if (lp_thread_id  == NULL) {
186         // no op
187     } else {
188         /* Initializing Attributes */
189         lret = pthread_attr_init(&st_thread_attr);
190
191         /* When the attribute initialization is successful */
192         if (lret == EOK) {
193             /* Do not inherit parent scheduling policies */
194             lret = pthread_attr_setinheritsched(&st_thread_attr, PTHREAD_EXPLICIT_SCHED);
195         }
196
197         /* If you successfully configure policy inheritance */
198         if (lret == EOK) {
199             /* Scheduling settings */
200             lret = pthread_attr_setschedpolicy(&st_thread_attr, SCHED_RR);
201         }
202
203         /* Successful Scheduling settings */
204         if (lret == EOK) {
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);
209         }
210
211         /* If the priority setting is successful */
212         if (lret == EOK) {
213             lret = pthread_create(&ul_thread_id,
214                                    NULL,
215                                    (_CWORD64_PROCMNG_START_ROUTINE)lp_start_address,
216                                    lp_parameter);
217         }
218
219         /* Successful pthread_create */
220         if (lret == EOK) {
221             bret = TRUE;
222         }
223     }
224
225     /* When priority setting is successful */
226     if (bret != FALSE) {
227         /* Return value setting */
228         handle         = (HANDLE)ul_thread_id;
229         *lp_thread_id    = ul_thread_id;
230     } else {
231         /* Error log output */
232         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "lret ERROR [lret:%d]", lret);
233     }
234
235     return handle;
236 }
237 // LCOV_EXCL_STOP
238
239 /**
240  * @brief
241  *   Get the thread ID
242  *
243  * @return Thread ID
244  */
245 uint32_t PbGetTid(void) {
246     uint32_t ul_tid;
247
248     ul_tid = (uint32_t)syscall(__NR_gettid);
249
250     return ul_tid;
251 }
252
253 /**
254  * @brief
255  *   Get the local thread ID
256  *
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>
260  *
261  * @return Local thread ID
262  */
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 */
269
270     uint32_t ul_tid;
271     uint32_t ul_idx;
272     uint32_t ul_local_tid = 0xFFFFFFFF;
273
274     ul_tid = PbGetTid();
275
276     OtherLockMutex(); /* Get Mutex for accessing shared info */
277
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;
281         }
282     }
283
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;
289
290                 break;
291             }
292         }
293
294         if (ul_local_tid == 0xFFFFFFFF) {
295             /* forbidden */
296             FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Local Tid buffer is overfull!!");
297             _pb_Exit();
298
299             /* don't arrive here. */
300         }
301     }
302
303     OtherUnlockMutex(); /* Release Mutex for accessing shared info */
304
305     return ul_local_tid;
306 }
307
308
309 /**
310  * @brief
311  *   Get Application Handle
312  *
313  *    Get the application handle of the invoking thread.
314  *
315  * @return Non-zero:Normal status,  0:When an error occurs
316  */
317 HANDLE _pb_GetAppHandle(void) {     // NOLINT(readability/nolint)  WPF_SYSAPI.h  API
318     const uint32_t offset = PbGetLocalTid();
319
320     return g_h_app[offset];
321 }
322
323
324 /**
325  * @brief
326  *   Set Application Handle
327  *
328  *    Set the application handle of the invoking thread.
329  *
330  * @param[in]  name Process name
331  */
332 void _pb_SetAppHandle(HANDLE h_app) {     // NOLINT(readability/nolint)  WPF_SYSAPI.h  API
333     const uint32_t offset = PbGetLocalTid();
334
335     OtherLockMutex(); /* Get Mutex for accessing shared info */
336
337     g_h_app[offset] = h_app;
338
339     OtherUnlockMutex(); /* Release Mutex for accessing shared info */
340
341     return;
342 }
343
344
345 /**
346  * @brief
347  *   Convert process name to pno
348  *
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.
353  *
354  * @param[in]  name Process name
355  *
356  * @return Process number
357  */
358 PNO _pb_CnvName2Pno(PCSTR name) {     // NOLINT(readability/nolint)  WPF_SYSAPI.h  API
359     u_int32 idx;
360     PNO pno = 0;
361     size_t len;
362
363     /* null check */
364     if (name == NULL) {
365         pno = 0;
366     } else {
367         len = _tcslen(name);
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);
371         } else {
372             OtherLockMutex();
373
374             idx = OtherSearchNameOfCnvTbl(name);
375
376             if (idx != MAX_OTHER_PROC_NUM) {
377                 pno = OtherGetPnoOfCnvTbl(idx);
378             } else {
379                 idx = OtherSearchNameOfCnvTbl("");
380                 OtherSetNameOfCnvTbl(idx, name);
381                 /* Increment using-counter */
382                 OtherIncUseCntOfCnvTbl();
383                 pno = OtherGetPnoOfCnvTbl(idx);
384             }
385
386             OtherUnlockMutex();
387         }
388     }
389
390     return pno;
391 }
392
393 /**
394  * @brief
395  *   Convert pno to process name
396  *
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,
400  *   NULL is returned.
401  *
402  * @param[in]  pno Process number
403  *
404  * @return Process name
405  */
406 PCSTR _pb_CnvPno2Name(PNO pno) {     // NOLINT(readability/nolint)  WPF_SYSAPI.h  API
407     u_int32 idx;
408     PCSTR name = NULL;
409
410     OtherLockMutex();
411
412     idx = OtherSearchPnoOfCnvTbl(pno);
413
414     if (idx != MAX_OTHER_PROC_NUM) {
415         name = OtherGetNameOfCnvTbl(idx);
416     }
417
418     OtherUnlockMutex();
419
420     return name;
421 }
422
423
424 /**
425  * @brief
426  *   Get environment variables
427  *
428  * @param[in]   Environment variable name
429  * @param[in]   Pointer to environment variable value
430  */
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);
434
435     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "VP_GetEnv:%s=%s", p_env_str, p_env_buff);
436
437     return;
438 }
439 // LCOV_EXCL_STOP
440
441 /*---------------------------------------------------------------------------------*
442  * Local Function                                                                  *
443  *---------------------------------------------------------------------------------*/
444 /**
445  * @brief
446  *   PNO setting(The table to translate the process name to PNO)
447  *
448  *   If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
449  *
450  * @param[in]    u_int32 idx        Table accessor
451  * @param[in]    PNO    pno    Process number
452  *
453  * @return none
454  */
455 static void OtherSetPnoOfCnvTbl(u_int32 idx, PNO pno) {
456     /* check index */
457     if (idx >= MAX_OTHER_PROC_NUM) {  // LCOV_EXCL_BR_LINE 6: idx cannot greater
458         /* forbidden */
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. */
463     }
464
465     g_p_proc_id_tbl->id[idx].pno = pno;
466
467     return;
468 }
469
470 /**
471  * @brief
472  *   Set process name (The table to translate the process name to PNO)
473  *
474  *   If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
475  *
476  * @param[in]    u_int32    idx        Table accessor
477  * @param[in]    PCSTR        name    Process name
478  *
479  * @return none
480  */
481 static void OtherSetNameOfCnvTbl(u_int32 idx, PCSTR name) {
482     /* check index */
483     if (idx >= MAX_OTHER_PROC_NUM) {  // LCOV_EXCL_BR_LINE 6: idx cannot greater
484         /* forbidden */
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. */
489     } else {
490         _tcscpy(g_p_proc_id_tbl->id[idx].name, name);
491     }
492
493     return;
494 }
495
496 /**
497  * @brief
498  *   Get PNO (The table to translate the process name to PNO)
499  *
500  *   If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
501  *
502  * @param[in]    u_int32    idx    Table accessor
503  *
504  * @return PNO
505  */
506 static PNO OtherGetPnoOfCnvTbl(u_int32 idx) {
507     /* check index */
508     if (idx >= MAX_OTHER_PROC_NUM) {  // LCOV_EXCL_BR_LINE 6: idx cannot greater
509         /* forbidden */
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. */
514     }
515
516     return g_p_proc_id_tbl->id[idx].pno;
517 }
518
519 /**
520  * @brief
521  *   Get process name (The table to translate the process name to PNO)
522  *
523  *   If an invalid value is specified for an argument, the system assumes that it is a design problem and calls _pb_Exit().
524  *
525  * @param[in]    u_int32    idx    Table accessor
526  *
527  * @return PCSTR
528  */
529 static PCSTR OtherGetNameOfCnvTbl(u_int32 idx) {
530     /* check index */
531     if (idx >= MAX_OTHER_PROC_NUM) {  // LCOV_EXCL_BR_LINE 6: idx cannot greater
532         /* forbidden */
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. */
537     }
538
539     return g_p_proc_id_tbl->id[idx].name;
540 }
541
542 /**
543  * @brief
544  *   Retrieve PNO (The table to translate the process name to PNO)
545  *
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).
548  *
549  * @param[in]    PNO    pno    Process number
550  *
551  * @return u_int32    Table accessor
552  */
553 static u_int32 OtherSearchPnoOfCnvTbl(PNO pno) {
554     u_int32 idx;
555     PNO lPno;
556
557     for (idx = 0; idx < MAX_OTHER_PROC_NUM; idx++) {
558         lPno = OtherGetPnoOfCnvTbl(idx);
559
560         if (lPno == pno) {
561             break;
562         }
563     }
564
565     return idx;
566 }
567
568 /**
569  * @brief
570  *   Retrieve process name (The table to translate the process name to PNO)
571  *
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).
574  *
575  * @param[in]    PCSTR name Process name
576  *
577  * @return u_int32    Table accessor
578  */
579 static u_int32 OtherSearchNameOfCnvTbl(PCSTR name) {
580     int32    ret;
581     u_int32 idx;
582
583     for (idx = 0; idx < MAX_OTHER_PROC_NUM; idx++) {
584         ret = _tcscmp(g_p_proc_id_tbl->id[idx].name, name);
585
586         /* If there is a match */
587         if (ret == 0) {
588             break;
589         }
590     }
591
592     return idx;
593 }
594
595
596 /**
597  * @brief
598  *   Create Mutex for accessing shared info
599  *
600  * @param[in]    none
601  *
602  * @return none
603  */
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);
608         _pb_Exit();
609         /* don't arrive here. */
610     }
611
612     return;
613 }
614
615 /**
616  * @brief
617  *   Delete Mutex for accessing shared info
618  *
619  * @param[in]  none
620  *
621  * @return none
622  */
623 static void OtherDeleteMutex(void) {  // LCOV_EXCL_START 8:dead code
624     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
625     DWORD    ret;
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);
630         _pb_Exit();
631         /* don't arrive here. */
632     }
633
634     return;
635 }
636 // LCOV_EXCL_STOP
637
638 /**
639  * @brief
640  *   Get Mutex for accessing shared info
641  *
642  * @param[in]  none
643  *
644  * @return none
645  */
646 static void OtherLockMutex(void) {
647     DWORD    ret;
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);
652         _pb_Exit();
653         /* don't arrive here. */
654     }
655
656     return;
657 }
658
659 /**
660  * @brief
661  *   Open Mutex for Accessing Shared Info
662  *
663  * @param[in]  none
664  *
665  * @return none
666  */
667 static void OtherUnlockMutex(void) {
668     BOOL    ret;
669     ret = PbMutexUnlock(g_h_mtx);
670     if (ret != TRUE) {
671         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "PbMutexUnlock ERROR " \
672             "[ret:%d, g_h_mtx:%p]", ret, g_h_mtx);
673         _pb_Exit();
674         /* don't arrive here. */
675     }
676
677     return;
678 }
679
680 /**
681  * @brief
682  *   Get dump information
683  *
684  * @param[out] pBuf      Dump info
685  */
686 void _pb_GetDebugOtherMngTbl(void* pBuf) {
687     static uint8_t  buf[DEBUG_DUMP_MAX_SIZE];
688     static uint8_t  bufTmp[64];
689     uint32_t         i;
690
691     if (pBuf != NULL) {
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"));
698             // LCOV_EXCL_STOP
699         } else {
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",
704                         i,
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])));
709             }
710         }
711         memcpy(pBuf, &buf[0], sizeof(buf));
712     }
713 }
714
715 /**
716  * @brief
717  *   Increment the usage counter of the table to translate process name to PNO
718  *
719  * @param[in] none
720  */
721 static void OtherIncUseCntOfCnvTbl(void) {
722     g_p_proc_id_tbl->use_cnt++;
723     return;
724 }
725
726 /**
727  * @brief
728  *   Increment the counter to reserve the table to translate the process name to PNO
729  *
730  * @param[in] none
731  */
732 static void OtherIncRsvCntOfCnvTbl(void) {
733     g_p_proc_id_tbl->rsv_cnt++;
734     return;
735 }
736
737 /**
738  * @brief
739  *   Decrement the counter to reserve the table to translate the process name to PNO
740  *
741  * @param[in] none
742  */
743 static void OtherDecRsvCntOfCnvTbl(void) {
744     g_p_proc_id_tbl->rsv_cnt--;
745     return;
746 }
747
748 /**
749  * @brief
750  *   Determine resources ready (The table to translate the process name to PNO)
751  *
752  * @param[in]  none
753  *
754  * @return BOOL
755  * @retval TRUE  : Normal
756  * @retval FALSE : Error (Resource shortage)
757  */
758 BOOL _pb_GetOtherResource(void) {
759     BOOL ret = TRUE;
760     uint32_t cnt;
761
762     OtherLockMutex();
763
764     /* Increment reserved counter */
765     OtherIncRsvCntOfCnvTbl();
766
767     cnt = g_p_proc_id_tbl->use_cnt + g_p_proc_id_tbl->rsv_cnt;
768     if (cnt >= FULL_OTHER_PROC_NUM) {
769         ret = FALSE;
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);
775     }
776
777     OtherUnlockMutex();
778
779     return ret;
780 }
781
782 /**
783  * @brief
784  *   Release resources (The table to translate process name to PNO)
785  *
786  * @param[in]  none
787  *
788  * @return none
789  */
790 void _pb_ReleaseOtherResource(void) {
791     OtherLockMutex();
792
793     /* Decrement reserved counter */
794     OtherDecRsvCntOfCnvTbl();
795
796     OtherUnlockMutex();
797
798     return;
799 }