xref: /utopia/UTPA2-700.0.x/modules/msos/msos/linux/MsOS_linux.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    MsOS.c
98 /// @brief  MStar OS Wrapper
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 /*
103  * Note! Functions related to
104  * pthread_mutex_timedlock/sem_timedwait/pthread_cond_timedwait
105  * may be disrupted by settimeofday() or other alike APIs.
106  *
107  * root cause:
108  *              your-process                            other-process
109  *  1. get "now" in realtime(ex: 5/7)
110  *  2. add duration(ex: 1 day -> 5/8)
111  *                                          a. modify "now" in realtime(ex: 5/5)
112  *  3. set expire time in realtime(ex: 5/8)
113  *
114  * Well, "now" you have to wait 3 days instead of 1 day.
115  * There's nothing we can do unless pthread_mutex_timedlock/sem_timedwait
116  * provide monotonic version.
117  */
118 
119 #if defined (MSOS_TYPE_LINUX)
120 
121 #if defined (ANDROID) && !defined (TV_OS)
122 #error "Define ANDROID, must define TV_OS"
123 #endif
124 #if defined (TV_OS) && defined (MSOS_PROCESS_SAFT_MUTEX)
125 #error "Can't both define TV_OS and MSOS_PROCESS_SAFT_MUTEX"
126 #endif
127 
128 #define _GNU_SOURCE
129 
130 #if 0
131 #undef malloc
132 #undef realloc
133 #undef free
134 #endif
135 
136 #include <fcntl.h>
137 #include <errno.h>
138 #include <stdio.h>
139 #include <stdlib.h>
140 #include <unistd.h>
141 #include <pthread.h>
142 #include <signal.h>
143 #include <time.h>
144 #include <limits.h>
145 #include <memory.h>
146 #include <semaphore.h>
147 #include <sys/stat.h>
148 #include <sys/ioctl.h>
149 #include <string.h>
150 #include <sys/prctl.h>
151 
152 // Android (bionic libc) do not support key based ipc,
153 // we must use ashmem (anonymous shared memory) instead
154 
155 #if defined (ANDROID)
156 #include <cutils/log.h>
157 #else
158 #include <sys/ipc.h>
159 #include <sys/shm.h>
160 #endif
161 
162 //-------------------------------------------------------------------------------------------------
163 // Include Files
164 //-------------------------------------------------------------------------------------------------
165 
166 #ifdef ENABLE_DLMALLOC
167 #define USE_DLMALLOC 1
168 #else
169 #define USE_DLMALLOC 0
170 #endif
171 
172 
173 #include "MsCommon.h"
174 
175 #include "mem.h"
176 
177 #include "MsOS.h"
178 #include "MsOS_private.h"
179 #include "asmCPU.h"
180 //#include "devCHIP.h"
181 #include "halCHIP.h"
182 #include "regCHIP.h"
183 #include "halMMIO.h"
184 #include "MsVersion.h"
185 #include "halMPool.h"
186 #if USE_DLMALLOC
187 #include "dlmalloc.h"
188 #endif
189 #include "utopia.h"
190 #include "ULog.h"
191 
192 #define MSOS_ERROR(fmt, args...)    ULOGE("MSOS","[%06d]     " fmt, __LINE__, ## args)
193 #define MSOS_WARN(fmt, args...)    ULOGW("MSOS","[%06d]     " fmt, __LINE__, ## args)
194 #define MSOS_PRINT(fmt, args...)    ULOGI("MSOS","[%06d]     " fmt, __LINE__, ## args)
195 #define MSOS_ASSERT(_bool, _f)    if (!(_bool)) { ULOGF("MSOS",_f); MS_ASSERT(0);) }
196 
197 #if 1 //Enable real assert from linux
198 #include <assert.h>
199 #include <unistd.h>
200 #define LINUX_ASSERT(x)  if (!(x)) {MSOS_WARN("\nAssert in %s,%d\n", __FUNCTION__, __LINE__); MsOS_DelayTask(100); assert(0);}
201 #endif
202 
203 
204 //-------------------------------------------------------------------------------------------------
205 // Local Defines
206 //------------------------------------------------------------------------------------------------
207 // Switch tasks every 1 ms.
208 //#define UCLIBC 1
209 #define TASK_TIME_SLICE             (TICK_PER_ONE_MS)
210 
211 // Combine 3-B prefix with s32ID = MSOS_ID_PREFIX | s32Id
212 //  to avoid the kernel object being used before initialzed.
213 #define MSOS_ID_PREFIX              0x76540000
214 #define MSOS_ID_PREFIX_MASK         0xFFFF0000
215 #define MSOS_ID_MASK                0x0000FFFF //~MSOS_ID_PREFIX_MASK
216 
217 
218 
219 #define CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE (10)
220 #if !defined (ANDROID)
221 /// Linux priority
222 typedef enum
223 {
224     E_LINUX_PRI_SYS      = 99,    ///< System priority task   ( interrupt level driver, e.g. TSP, SMART )
225     E_LINUX_PRI_HIGHEST  = 80,    ///< Highest priority task  ( background monitor driver, e.g. DVBC, HDMI )
226     E_LINUX_PRI_HIGH     = 60,    ///< High priority task     ( service task )
227     E_LINUX_PRI_MEDIUM   = 40,   ///< Medium priority task   ( application task )
228     E_LINUX_PRI_LOW      = 20,   ///< Low priority task      ( nonbusy application task )
229     E_LINUX_PRI_LOWEST   = 1,   ///< Lowest priority task   ( idle application task )
230 } _LinuxPriority;
231 #endif
232 
233 #ifdef UCLIBC
234 void Timer_Thread(void *data);
235 typedef struct {
236     TimerCb pTimerCb;
237     MS_U32 u32FirstTimeMs;
238     MS_U32 u32PeriodTimeMs;
239     MS_BOOL bStartTimer;
240     char *pTimerName;
241     MS_BOOL create_ready;
242     MS_S32 s32Id;
243 }TimerSET;
244 #endif
245 //Thread name length
246 #define MAX_NAME  30
247 
248 //-------------------------------------------------------------------------------------------------
249 // Macros
250 //-------------------------------------------------------------------------------------------------
251 #define HAS_FLAG(flag, bit)        ((flag) & (bit))
252 #define SET_FLAG(flag, bit)        ((flag)|= (bit))
253 #define RESET_FLAG(flag, bit)      ((flag)&= (~(bit)))
254 
255 /*
256  * clock_gettime() base should not be monotonic,
257  * though reatlime isnt excatly suitable.
258  * Only pthread_cond_timedwait can benefit from mononic.
259  * But to pthread_mutex_timedlock/sem_timedwait,
260  * it would be disaster if there's gap between monotonic/realtime
261  */
262 
263 #define _TimeAbsM(stTime, u32IntMs)                                      \
264 {                                                                       \
265     clock_gettime(CLOCK_MONOTONIC, &(stTime));                           \
266     if(u32IntMs > 0)                                                    \
267     {                                                                   \
268         MS_U32 u32Sec = (u32IntMs) / 1000;                              \
269         (stTime).tv_sec += u32Sec;                                      \
270         (stTime).tv_nsec += ((u32IntMs) - (1000 * u32Sec)) * 1000000;   \
271         if ((stTime).tv_nsec >= 1000000000)                             \
272         {                                                               \
273             (stTime).tv_sec++;                                          \
274             (stTime).tv_nsec -= 1000000000;                             \
275         }                                                               \
276     }                                                                   \
277 }
278 
279 #define _TimeAbs(stTime, u32IntMs)                                      \
280 {                                                                       \
281     clock_gettime(CLOCK_REALTIME, &(stTime));                           \
282     if(u32IntMs > 0)                                                    \
283     {                                                                   \
284         MS_U32 u32Sec = (u32IntMs) / 1000;                              \
285         (stTime).tv_sec += u32Sec;                                      \
286         (stTime).tv_nsec += ((u32IntMs) - (1000 * u32Sec)) * 1000000;   \
287         if ((stTime).tv_nsec >= 1000000000)                             \
288         {                                                               \
289             (stTime).tv_sec++;                                          \
290             (stTime).tv_nsec -= 1000000000;                             \
291         }                                                               \
292     }                                                                   \
293 }
294 
295 #ifdef MS_DEBUG
296 #include "string.h"
297 
298 #define PTH_RET_CHK(_pf_) \
299     ({ \
300         int r = _pf_; \
301         if ((r != 0) && (r != ETIMEDOUT)) \
302             fprintf(stderr, "[PTHREAD] %s: %d: %s: %s\n", __FILE__, __LINE__, #_pf_, strerror(r)); \
303         r; \
304     })
305 #else
306 #define PTH_RET_CHK(_pf_) _pf_
307 #endif
308 
309 //-------------------------------------------------------------------------------------------------
310 // Global Variables
311 //-------------------------------------------------------------------------------------------------
312 
313 // Use 'S' as magic number //Needs to sync with header in Linux kernel!!!!
314 #define SYS_IOCTL_MAGIC             'S'
315 #define IOCTL_SYS_FLUSH_MEMORY         _IO(SYS_IOCTL_MAGIC, 0x50)
316 #define IOCTL_SYS_READ_MEMORY          _IO(SYS_IOCTL_MAGIC, 0x51)
317 
318 static MS_S32 _s32FdSYS = -1;
319 
320 
321 //-------------------------------------------------------------------------------------------------
322 // Local Variables
323 //-------------------------------------------------------------------------------------------------
324 //
325 // Variable-size Memory pool
326 //
327 #if defined (MSOS_TYPE_LINUX)
328 
329 typedef struct
330 {
331     MS_BOOL                         bUsed;
332 #if USE_DLMALLOC
333     mspace stMemoryPool;                /* dlmalloc handler */
334 #else /* if USE_DLMALLOC */
335     cyg_handle_t                    stMemoryPool;
336     cyg_mempool_var                 stMemoryPoolInfo;
337 #endif /* if USE_DLMALLOC */
338     MS_BOOL bMPool;
339 } MsOS_MemoryPool_Info;
340 
341 static MsOS_MemoryPool_Info     _MsOS_MemoryPool_Info[MSOS_MEMPOOL_MAX];
342 static pthread_mutex_t          _MsOS_MemoryPool_Mutex;
343 
344 //
345 // Task Management
346 //
347 typedef struct
348 {
349     MS_BOOL             bUsed;
350     MS_BOOL             bWaitJoin;
351     pthread_t           stThreadInfo;
352     void*               pStackBase;
353     TaskEntry           pTaskEntry;
354     MS_VIRT              u32TaskEntryData;
355     char                pTaskName[MAX_NAME];
356 	MS_BOOL             bStackMalloc;
357 
358 } MsOS_Task_Info;
359 
360 static MsOS_Task_Info   _MsOS_Task_Info[MSOS_TASK_MAX];
361 static pthread_mutex_t  _MsOS_Task_Mutex;
362 
363 #if defined (TV_OS)
364 typedef struct
365 {
366     MS_BOOL             bUsed;
367     MS_BOOL             bShared;
368     union{
369         MS_S32          u32Index;
370         pthread_mutex_t     stMutex;
371     }msos_mutex;
372     MS_U8               u8Name[MAX_MUTEX_NAME_LENGTH];
373 } MsOS_Mutex_Info;
374 #else
375 typedef struct
376 {
377     MS_BOOL             bUsed;
378     pthread_mutex_t     stMutex;
379     MS_U8               u8Name[MAX_MUTEX_NAME_LENGTH];
380 } MsOS_Mutex_Info;
381 #endif
382 
383 
384 #define MUTEX_MUTEX_NAME        "msosMutexMutex"
385 
386 #if defined (TV_OS)
387     static MsOS_Mutex_Info          _MsOS_Mutex_Info[MSOS_MUTEX_MAX];
388     static MS_S32 u32MSos_Mutex_Index = -10;
389     #define MUTEX_MUTEX_LOCK()      MsOS_LockMutex(u32MSos_Mutex_Index,0)
390     #define MUTEX_MUTEX_UNLOCK()    MsOS_UnlockMutex(u32MSos_Mutex_Index,2)
391 #elif defined (MSOS_PROCESS_SAFT_MUTEX)
392     static MsOS_Mutex_Info*         _MsOS_Mutex_Info = NULL;
393     static sem_t* pMutexMutex =     NULL;
394     #define MUTEX_MUTEX_LOCK()      sem_wait(pMutexMutex)
395     #define MUTEX_MUTEX_UNLOCK()    sem_post(pMutexMutex)
396 #else
397     static MsOS_Mutex_Info          _MsOS_Mutex_Info[MSOS_MUTEX_MAX];
398     static pthread_mutex_t          _MsOS_Mutex_Mutex;
399     #define MUTEX_MUTEX_LOCK()      PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Mutex_Mutex));
400     #define MUTEX_MUTEX_UNLOCK()    PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Mutex_Mutex));
401 #endif
402 
403 //
404 // Semaphore
405 //
406 typedef struct
407 {
408     MS_BOOL                     bUsed;
409     sem_t                       stSemaphore;
410 } MsOS_Semaphore_Info;
411 
412 static MsOS_Semaphore_Info      _MsOS_Semaphore_Info[MSOS_SEMAPHORE_MAX];
413 static pthread_mutex_t          _MsOS_Semaphore_Mutex;
414 
415 //
416 // Event Group
417 //
418 typedef struct
419 {
420     MS_BOOL bUsed;
421     MS_U32                         u32EventGroup;
422     pthread_mutex_t             stMutexEvent;
423     pthread_cond_t              stSemaphore;
424     pthread_mutex_t             stMutex;
425 } MsOS_EventGroup_Info;
426 
427 static MsOS_EventGroup_Info     _MsOS_EventGroup_Info[MSOS_EVENTGROUP_MAX];
428 static pthread_mutex_t          _MsOS_EventGroup_Mutex;
429 
430 //
431 // Queue
432 //
433 typedef struct
434 {
435     MS_BOOL            bUsed;
436     MS_U8*             pu8Head;
437     MS_U8*             pu8Tail;
438     MS_U8*             pu8Write;
439     MS_U8*             pu8Read;
440     pthread_cond_t  SendSem;
441     pthread_mutex_t SendMutex;
442     pthread_cond_t  RecvSem;
443     pthread_mutex_t RecvMutex;
444     MessageType     eMsgType;
445     MS_U32             u32AlignedMsgSize;
446     pthread_mutex_t     WaitQueueSpaceMutex;
447     pthread_mutex_t     WaitQueueDataMutex;
448 } MsOS_Queue_Info;
449 
450 static MsOS_Queue_Info  _MsOS_Queue_Info[MSOS_QUEUE_MAX];
451 static pthread_mutex_t  _MsOS_Queue_Mutex;
452 
453 // @FIXME: Leave Timer later
454 //
455 // Timer
456 //
457 typedef struct
458 {
459     MS_BOOL                bUsed;
460     TimerCb             pTimerCb;
461     struct itimerspec   TimeInfo;
462     timer_t             TimerId;
463 	pthread_mutex_t     TimerMutex;
464 } MsOS_Timer_Info;
465 static MsOS_Timer_Info  _MsOS_Timer_Info[MSOS_TIMER_MAX];
466 #ifdef UCLIBC
467 static pid_t  _MsOS_Timer_Pid[MSOS_TIMER_MAX];
468 #endif
469 static pthread_mutex_t  _MsOS_Timer_Mutex;
470 
471 #endif
472 
473 
474 static pthread_mutex_t  _ISR_Mutex;
475 
476 static pthread_mutex_t  _MsOS_Init_Mutex = PTHREAD_MUTEX_INITIALIZER;
477 
478 //
479 // Share memory
480 //
481 /* FIXME: patch for monaco bring up */
482 #define SHM_SIZE_RESEVED      (124*1024)
483 #define SHM_SIZE              (2<<20)
484 #define MAX_SHM_CLIENT_NUM      320
485 #define SHM_MUTEX_NAME          "msos_shm_mutex"
486 
487 typedef struct
488 {
489     MS_U8       u8ClientName[MAX_CLIENT_NAME_LENGTH+ 1];
490     MS_U32      u32Offset;
491     MS_U32      u32Size;
492     MS_U32       u32ClientId;    // 0 means "never used"
493     MS_U8       u8RefCnt;
494     MS_U8       u8Dummy[2];
495 } MsOS_SHM_Context;
496 
497 typedef struct
498 {
499     MS_U32              u32MaxClientNum;
500     MS_U32              u32ClientNum;
501     MS_U32              u32ShmSize;
502     MS_U32              u32Offset;
503     MsOS_SHM_Context    context[MAX_SHM_CLIENT_NUM];
504 } MsOS_SHM_Hdr;
505 
506 static MS_VIRT _shm_id = -1;
507 static MS_U8 *_pu8ShareMem = NULL;
508 static MsOS_SHM_Hdr _ShmHdr; // dummy storage
509 
510 #if defined (TV_OS)
511 static MS_S32  pMutexShmIdx = -1;
512 #define SHAREMEM_MUTEX_NAME     "ShareMemoryMutex"
513 #define _MSOS_SHM_LOCK(pSemIndex)    MsOS_LockMutex(pSemIndex,0)
514 #define _MSOS_SHM_UNLOCK(pSemIndex)  MsOS_UnlockMutex(pSemIndex,4)
515 #elif defined (MSOS_PROCESS_SAFT_MUTEX)
516 static sem_t* pMutexShm = NULL;
517 #define _MSOS_SHM_LOCK(pSem)    sem_wait(pSem)
518 #define _MSOS_SHM_UNLOCK(pSem)  sem_post(pSem)
519 #else
520 #define _MSOS_SHM_LOCK(pSem)
521 #define _MSOS_SHM_UNLOCK(pSem)
522 #endif
523 
524 #ifdef CONFIG_UTOPIA_SHM_EXPAND_SUPPORT
525 #define SHM_EXPAND_SIZE (256*1024)
526 #endif
527 
528 //-------------------------------------------------------------------------------------------------
529 // Local Function Prototypes
530 //-------------------------------------------------------------------------------------------------
531 
532 void* _MsOS_LinuxTaskWrapper(void *);
533 
534 static MSIF_Version _drv_msos_version = {
535     .DDI = { MSOS_DRV_VERSION },
536 };
537 ////////////////////////////////////////////////////////////////////////////////
538 /// @brief \b Function  \b Name: MDrv_MSOS_GetLibVer
539 /// @brief \b Function  \b Description: Show the MSOS driver version
540 /// @param ppVersion    \b Out: Library version string
541 /// @return             \b Result
542 ////////////////////////////////////////////////////////////////////////////////
MDrv_MSOS_GetLibVer(const MSIF_Version ** ppVersion)543 MS_BOOL MDrv_MSOS_GetLibVer(const MSIF_Version **ppVersion)
544 {
545     if (!ppVersion)
546         return FALSE;
547 
548     *ppVersion = &_drv_msos_version;
549     return TRUE;
550 }
551 //-------------------------------------------------------------------------------------------------
552 /// Initialize MsOS
553 /// @return TRUE : succeed
554 /// @return FALSE : fail
555 //-------------------------------------------------------------------------------------------------
MsOS_Init(void)556 MS_BOOL MsOS_Init (void)
557 {
558     MS_U32 u32I;
559     MS_BOOL bRet = TRUE;
560     pthread_mutexattr_t _MsOS_Mutex_Attr;
561 #if defined (MSOS_PROCESS_SAFT_MUTEX)
562     MS_U32 u32ShmId;
563     MS_U32 u32Addr, u32Size;
564 #endif
565     static MS_S32 bInit = 0;
566 
567     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Init_Mutex));
568 
569     if (bInit == 1)
570     {
571         MSOS_PRINT("[MsOS_Init] already inited!\n");
572         bRet = TRUE;
573         goto ret;
574     }
575 
576     if (FALSE == MsOS_SHM_Init())
577     {
578         MSOS_ERROR("[MsOS_Init] MsOS_SHM_Init failed!\n");
579         bRet = FALSE;
580         goto ret;
581     }
582 
583     PTH_RET_CHK(pthread_mutexattr_init(&_MsOS_Mutex_Attr));
584     //PTH_RET_CHK(pthread_mutexattr_setprotocol(&_MsOS_Mutex_Attr, PTHREAD_PRIO_INHERIT));
585     #ifdef MS_DEBUG
586     PTH_RET_CHK(pthread_mutexattr_settype(&_MsOS_Mutex_Attr, PTHREAD_MUTEX_ERRORCHECK));
587     #endif
588     //
589     // Task Management
590     //
591     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Task_Mutex, &_MsOS_Mutex_Attr));
592     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Task_Mutex));
593     for( u32I=0; u32I<MSOS_TASK_MAX; u32I++)
594     {
595         _MsOS_Task_Info[u32I].bUsed = FALSE;
596         _MsOS_Task_Info[u32I].bWaitJoin = FALSE;
597 		_MsOS_Task_Info[u32I].pStackBase= NULL;
598 		_MsOS_Task_Info[u32I].bStackMalloc= FALSE;
599     }
600     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Task_Mutex));
601 
602     //
603     // Mutex
604     //
605 #if defined (TV_OS)
606     if(u32MSos_Mutex_Index < 0)
607     {
608         u32MSos_Mutex_Index = MsOS_CreateNamedMutex((MS_S8*)MUTEX_MUTEX_NAME);
609         if(u32MSos_Mutex_Index < 0)
610         {
611             MSOS_ERROR("%s : %d,crate named mutex %s \n",__FUNCTION__,__LINE__,MUTEX_MUTEX_NAME);
612             bRet = FALSE;
613             goto ret;
614         }
615     }
616     for( u32I=0; u32I<MSOS_MUTEX_MAX; u32I++)
617     {
618         _MsOS_Mutex_Info[u32I].bUsed = FALSE;
619     }
620 
621 #elif defined (MSOS_PROCESS_SAFT_MUTEX)
622     if (SEM_FAILED == (pMutexMutex = sem_open(MUTEX_MUTEX_NAME, O_CREAT | O_EXCL, 0666, 1)))
623     {
624         if (SEM_FAILED == (pMutexMutex = sem_open(MUTEX_MUTEX_NAME, 0)))
625         {
626             MSOS_ERROR("[MsOS_Init] sem_open failed!\n");
627             bRet = FALSE;
628             goto ret;
629         }
630     }
631     if (FALSE == MsOS_SHM_GetId((MS_U8*)"_proc_mutex", MSOS_MUTEX_MAX* sizeof(MsOS_Mutex_Info), &u32ShmId, &u32Addr, &u32Size, MSOS_SHM_QUERY))
632     {
633         if (FALSE == MsOS_SHM_GetId((MS_U8*)"_proc_mutex", MSOS_MUTEX_MAX* sizeof(MsOS_Mutex_Info), &u32ShmId, &u32Addr, &u32Size, MSOS_SHM_CREATE))
634         {
635             MSOS_ERROR("[MsOS_Init] MsOS_SHM_GetId _proc_mutex failed!\n");
636             bRet = FALSE;
637             goto ret;
638         }
639     }
640     _MsOS_Mutex_Info = (MsOS_Mutex_Info*)u32Addr;
641 
642 #else
643     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Mutex_Mutex, &_MsOS_Mutex_Attr));
644     for( u32I=0; u32I<MSOS_MUTEX_MAX; u32I++)
645     {
646         _MsOS_Mutex_Info[u32I].bUsed = FALSE;
647     }
648 #endif
649 
650     //
651     // Semaphore
652     //
653     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Semaphore_Mutex, &_MsOS_Mutex_Attr));
654     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Semaphore_Mutex));
655     for( u32I=0; u32I<MSOS_SEMAPHORE_MAX; u32I++)
656     {
657         _MsOS_Semaphore_Info[u32I].bUsed = FALSE;
658     }
659     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Semaphore_Mutex));
660 
661     //
662     // Event Group
663     //
664     PTH_RET_CHK(pthread_mutex_init(&_MsOS_EventGroup_Mutex, &_MsOS_Mutex_Attr));
665 
666     for( u32I=0; u32I<MSOS_EVENTGROUP_MAX; u32I++)
667     {
668         _MsOS_EventGroup_Info[u32I].bUsed = FALSE;
669     }
670 
671     //
672     // Queue
673     //
674     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Mutex, &_MsOS_Mutex_Attr));
675     for( u32I=0; u32I<MSOS_QUEUE_MAX; u32I++)
676     {
677         memset(&_MsOS_Queue_Info[u32I].bUsed, 0, sizeof(MsOS_Queue_Info));
678     }
679 
680     //
681     // Timer
682     //
683     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Timer_Mutex, &_MsOS_Mutex_Attr));
684     for( u32I=0; u32I<MSOS_TIMER_MAX; u32I++)
685     {
686         _MsOS_Timer_Info[u32I].bUsed = FALSE;
687         PTH_RET_CHK(pthread_mutex_init(&_MsOS_Timer_Info[u32I].TimerMutex, &_MsOS_Mutex_Attr));
688     }
689     //
690     // Interrupt
691     //
692     MSOS_PRINT("pthread_mutex_init\n");
693     PTH_RET_CHK(pthread_mutex_init(&_ISR_Mutex, &_MsOS_Mutex_Attr));
694     MSOS_PRINT("CHIP_InitISR\n");
695     CHIP_InitISR();
696 
697     PTH_RET_CHK(pthread_mutex_init(&_MsOS_MemoryPool_Mutex, &_MsOS_Mutex_Attr));
698 
699 
700     if (_s32FdSYS < 0)   //First time open
701     {
702         _s32FdSYS  = open("/dev/system", O_RDWR);
703 
704         if (_s32FdSYS < 0) // return 0 ~ 19 if open device success; return -1 if failed
705         {
706             MSOS_ERROR("[MsOS_Init]open device node failed!\n");
707             bRet = FALSE;
708             goto ret;
709         }
710     }
711 
712     UtopiaInit();
713 
714     bInit = 1;
715 
716 ret:
717 
718     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Init_Mutex));
719     return bRet;
720 }
721 #if defined(MSOS_TYPE_LINUX_KERNEL)
722 EXPORT_SYMBOL(MsOS_Init);
723 #endif
724 
725 
726 //
727 // Memory management
728 //
729 //-------------------------------------------------------------------------------------------------
730 /// Create a variable-size memory pool dynamically
731 /// @param  u32PoolSize         \b IN: pool size in bytes
732 /// @param  u32MinAllocation    \b IN: not used
733 /// @param  pPoolAddr           \b IN: starting address for the memory pool
734 /// @param  eAttribute          \b IN: only E_MSOS_FIFO - suspended in FIFO order
735 /// @param  pPoolName           \b IN: not used
736 /// @return >=0 : assigned memory pool ID
737 /// @return < 0 : fail
738 //-------------------------------------------------------------------------------------------------
MsOS_CreateMemoryPool(MS_U32 u32PoolSize,MS_U32 u32MinAllocation,void * pPoolAddr,MsOSAttribute eAttribute,char * pPoolName)739 MS_S32 MsOS_CreateMemoryPool (MS_U32 u32PoolSize,
740                            MS_U32 u32MinAllocation,
741                            void * pPoolAddr,
742                            MsOSAttribute eAttribute,
743                            char *pPoolName)
744 {
745     MS_S32 s32Id;
746 
747     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
748 
749     for(s32Id=0;s32Id<MSOS_MEMPOOL_MAX;s32Id++)
750     {
751         if(_MsOS_MemoryPool_Info[s32Id].bUsed == FALSE)
752         {
753             break;
754         }
755     }
756     if(s32Id < MSOS_MEMPOOL_MAX)
757     {
758         _MsOS_MemoryPool_Info[s32Id].bUsed = TRUE;
759     }
760     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
761 
762     if(s32Id >= MSOS_MEMPOOL_MAX)
763     {
764         return -1;
765     }
766 
767     if (pPoolAddr)
768     {
769         _MsOS_MemoryPool_Info[s32Id].bMPool= TRUE;
770 #if USE_DLMALLOC
771         PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
772 #ifdef ENABLE_KERNEL_DLMALLOC
773 		_MsOS_MemoryPool_Info[s32Id].stMemoryPool = MsOS_MPool_CreateMemoryPool(pPoolAddr, u32PoolSize, 1);
774 #else
775 		_MsOS_MemoryPool_Info[s32Id].stMemoryPool = mstar_create_mspace_with_base(pPoolAddr, u32PoolSize, 1);
776 #endif
777         if (NULL == _MsOS_MemoryPool_Info[s32Id].stMemoryPool)
778         {
779             PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
780             return -1;
781         }
782         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
783         // my_info = mspace_mallinfo(_MsOS_MemoryPool_Info[s32Id].stMemoryPool);
784         // printf("Total size %ld, used size %ld, free size %ld\n", (unsigned long) my_info.usmblks, (unsigned long) my_info.uordblks, (unsigned long) my_info.fordblks);
785 #else /* if USE_DLMALLOC */
786         PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
787         cyg_mempool_var_create( pPoolAddr,
788                                 u32PoolSize,
789                                 &_MsOS_MemoryPool_Info[s32Id].stMemoryPool,
790                                 &_MsOS_MemoryPool_Info[s32Id].stMemoryPoolInfo );
791         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
792 #endif /* if USE_DLMALLOC */
793     }
794     else
795     {
796         _MsOS_MemoryPool_Info[s32Id].bMPool= FALSE;
797     }
798     s32Id |= MSOS_ID_PREFIX;
799     return s32Id;
800 }
801 
802 //-------------------------------------------------------------------------------------------------
803 /// Delete a variable-size memory pool
804 /// @param  s32PoolId   \b IN: pool ID
805 /// @return TRUE : succeed
806 /// @return FALSE : fail
807 //-------------------------------------------------------------------------------------------------
MsOS_DeleteMemoryPool(MS_S32 s32PoolId)808 MS_BOOL MsOS_DeleteMemoryPool (MS_S32 s32PoolId)
809 {
810     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
811     {
812         return FALSE;
813     }
814     else
815     {
816         s32PoolId &= MSOS_ID_MASK;
817     }
818 
819     if ( (s32PoolId >= MSOS_MEMPOOL_MAX) )
820     {
821         if ( s32PoolId == MSOS_MALLOC_ID )
822         {
823             // herer ??
824         }
825 
826         MSOS_PRINT("Invalid memory pool ID: %td, you must use the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
827         return TRUE;
828 
829     }
830 
831     #if 1
832     if(_MsOS_MemoryPool_Info[s32PoolId].bUsed == FALSE)
833     {
834         MSOS_ERROR("MEMORY POOL WITH MEMORYPOOL_ID: 0x%tX NOT EXIST\n", (ptrdiff_t)s32PoolId);
835         return FALSE;
836     }
837     #endif
838     if (_MsOS_MemoryPool_Info[s32PoolId].bMPool)
839     {
840 #if USE_DLMALLOC
841         PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
842 #ifdef ENABLE_KERNEL_DLMALLOC
843 		MsOS_MPool_DeleteMemoryPool(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool);
844 #else
845 		mstar_destroy_mspace(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool);
846 #endif
847         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
848 #else /* if USE_DLMALLOC */
849         cyg_mempool_var_delete(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool);
850 #endif /* if USE_DLMALLOC */
851     }
852 
853     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
854 
855     _MsOS_MemoryPool_Info[s32PoolId].bUsed = FALSE;
856 
857     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
858     return TRUE;
859 }
860 
861 //-------------------------------------------------------------------------------------------------
862 /// Get the information of a variable-size memory pool
863 /// @param  s32PoolId   \b IN: memory pool ID
864 /// @param  pPoolAddr   \b OUT: holding the starting address for the memory pool
865 /// @param  pu32PoolSize \b OUT: holding the total size of the memory pool
866 /// @param  pu32FreeSize \b OUT: holding the available free size of the memory pool
867 /// @param  pu32LargestFreeBlockSize  \b OUT: holding the size of the largest free block
868 /// @return TRUE : succeed
869 /// @return FALSE : the pool has not been created
870 //-------------------------------------------------------------------------------------------------
MsOS_InfoMemoryPool(MS_S32 s32PoolId,void ** pPoolAddr,MS_U32 * pu32PoolSize,MS_U32 * pu32FreeSize,MS_U32 * pu32LargestFreeBlockSize)871 MS_BOOL MsOS_InfoMemoryPool (MS_S32 s32PoolId,
872                           void **pPoolAddr,
873                           MS_U32 *pu32PoolSize,
874                           MS_U32 *pu32FreeSize,
875                           MS_U32 *pu32LargestFreeBlockSize)
876 {
877 
878     return FALSE;
879 
880 }
881 
882 //-------------------------------------------------------------------------------------------------
883 /// Allocate a memory block with 16-Byte aligned starting address from the variable-size memory pool
884 /// @param  u32Size     \b IN: request size
885 /// @param  s32PoolId   \b IN: memory pool ID
886 /// @return NULL : not enough available memory
887 /// @return Otherwise : pointer to the allocated memory block
888 //-------------------------------------------------------------------------------------------------
MsOS_AllocateMemory(MS_U32 u32Size,MS_S32 s32PoolId)889 void * MsOS_AllocateMemory (MS_U32 u32Size, MS_S32 s32PoolId)
890 {
891     void  *pAddr;
892 
893 
894     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
895     {
896         return NULL;
897     }
898     else
899     {
900         s32PoolId &= MSOS_ID_MASK;
901     }
902 
903 
904     // Jerry.Tsao: cyg_mempool_var_try_alloc allocates the maximum pool it has when size is zero.
905     if (u32Size == 0)
906     {
907         return NULL;
908     }
909 
910 
911     if ( s32PoolId >= MSOS_MEMPOOL_MAX)
912     {
913 
914         if ( s32PoolId == MSOS_MALLOC_ID )
915         {
916             return malloc(u32Size);
917         }
918 
919         else
920         {
921             MSOS_ERROR("Invalid memory pool ID: %td, you must use the default ID: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
922             return NULL;
923         }
924 
925     }
926 
927     if (FALSE== _MsOS_MemoryPool_Info[s32PoolId].bMPool)
928     {
929         MSOS_WARN("Invalid memory pool ID: %td, you must use the default ID: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
930         MSOS_WARN("System will use default mpool to allocate memory here\n");
931         return malloc(u32Size);
932     }
933 
934 #if USE_DLMALLOC
935     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
936 #ifdef ENABLE_KERNEL_DLMALLOC
937     pAddr = MsOS_MPool_AllocateMemory(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32Size);
938 #else
939     pAddr = mstar_mspace_malloc(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32Size);
940 #endif
941 
942     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
943     // MSOS_PRINT(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %s %d: %d %p\n", __FUNCTION__, __LINE__, s32PoolId, pAddr);
944 #else /* if USE_DLMALLOC */
945     pAddr = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32Size);
946 #endif /* if USE_DLMALLOC */
947 
948     //Current eCosPro kernel always allocates 16-B aligned block
949     if (( (MS_VIRT)pAddr & 0xF) || ( (MS_VIRT)pAddr == 0x0))
950     {
951         return NULL;
952     }
953 
954     //flush Dcache data
955     MsOS_Dcache_Flush((MS_VIRT)pAddr,u32Size);
956 
957     //flush OCP data
958     MsOS_FlushMemory();
959 
960     return ( pAddr );
961 }
962 
963 //-------------------------------------------------------------------------------------------------
964 /// Free a memory block from the variable-size memory pool
965 /// @param  pAddress    \b IN: pointer to previously allocated memory block
966 /// @param  s32PoolId   \b IN: memory pool ID
967 /// @return TRUE : succeed
968 /// @return FALSE : fail
969 //-------------------------------------------------------------------------------------------------
MsOS_FreeMemory(void * pAddress,MS_S32 s32PoolId)970 MS_BOOL MsOS_FreeMemory (void *pAddress, MS_S32 s32PoolId)
971 {
972 #if USE_DLMALLOC
973     // struct mallinfo my_info;
974 #endif
975 
976 
977     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
978     {
979         return FALSE;
980     }
981     else
982     {
983         s32PoolId &= MSOS_ID_MASK;
984     }
985 
986     if (pAddress == NULL)
987     {
988         return FALSE;
989     }
990 
991 
992 
993     if ( s32PoolId >= MSOS_MEMPOOL_MAX )
994     {
995         if ( s32PoolId == MSOS_MALLOC_ID )
996         {
997             free(pAddress);
998             return TRUE;
999         }
1000 
1001         else
1002         {
1003             MSOS_ERROR("Invalid memory pool ID: %td, you must use the default ID: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
1004             return FALSE;
1005         }
1006 
1007     }
1008 
1009 
1010     if (FALSE== _MsOS_MemoryPool_Info[s32PoolId].bMPool)
1011     {
1012         MSOS_WARN("Invalid mpool ID:%td, you must use the default ID macro: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
1013         MSOS_WARN("System will free default mpool memory here\n");
1014         free(pAddress);
1015 
1016     }
1017     else
1018     {
1019 #if USE_DLMALLOC
1020         PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
1021 #ifdef ENABLE_KERNEL_DLMALLOC
1022 		MsOS_MPool_FreeMemory(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pAddress);
1023 #else
1024 		mstar_mspace_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pAddress);
1025 #endif
1026         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
1027 #else /* if USE_DLMALLOC */
1028         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pAddress);
1029 #endif /* if USE_DLMALLOC */
1030     }
1031     return TRUE;
1032 }
1033 
1034 //-------------------------------------------------------------------------------------------------
1035 /// Reallocate a block of memory with 4-byte aligned start address from the variable-size memory pool
1036 /// @param  pOrgAddress \b IN: points to the beginning of the original memory block
1037 /// @param  u32NewSize  \b IN: size of new memory block
1038 /// @param  s32PoolId   \b IN: memory pool ID
1039 /// @return NULL : not enough available memory to expand the block or u32NewSize == 0 && pOrgAddress != NULL
1040 /// @return Otherwise : pointer to the reallocated (and possibly moved) memory block
1041 //  @note   reference realloc in malloc.cxx
1042 //-------------------------------------------------------------------------------------------------
MsOS_ReallocateMemory(void * pOrgAddress,MS_U32 u32NewSize,MS_S32 s32PoolId)1043 void * MsOS_ReallocateMemory (void *pOrgAddress, MS_U32 u32NewSize, MS_S32 s32PoolId)
1044 {
1045     void *pNewAddress = NULL;
1046 #if !USE_DLMALLOC
1047     MS_U32 u32OrgSize;
1048 #endif /* if !USE_DLMALLOC */
1049 
1050     if ( (s32PoolId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1051     {
1052         return NULL;
1053     }
1054     else
1055     {
1056         s32PoolId &= MSOS_ID_MASK;
1057     }
1058 
1059 
1060     if ( s32PoolId >= MSOS_MEMPOOL_MAX )
1061     {
1062         if ( s32PoolId == MSOS_MALLOC_ID )
1063         {
1064             return realloc(pOrgAddress, u32NewSize);
1065         }
1066 
1067         else
1068         {
1069             MSOS_WARN("Invalid memory pool ID: %td, you must use the default ID: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
1070             return NULL;
1071         }
1072 
1073     }
1074     if (FALSE== _MsOS_MemoryPool_Info[s32PoolId].bMPool)
1075     {
1076         MSOS_WARN("Invalid mpool ID: %td, you must use the default ID macro: MSOS_MALLOC_ID ,or the ID of the mpool you created\n", (ptrdiff_t)s32PoolId);
1077         MSOS_WARN("System will reallocate memory from default pookl\n");
1078         return realloc(pOrgAddress, u32NewSize);
1079     }
1080 
1081 #if USE_DLMALLOC
1082     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_MemoryPool_Mutex));
1083 #ifdef ENABLE_KERNEL_DLMALLOC
1084 	pNewAddress = MsOS_MPool_ReallocateMemory(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress, u32NewSize);
1085 #else
1086 	pNewAddress = mstar_mspace_realloc(_MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress, u32NewSize);
1087 #endif
1088     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_MemoryPool_Mutex));
1089 #else /* if USE_DLMALLOC */
1090     if ( pOrgAddress == NULL)
1091     {
1092         //malloc
1093         pNewAddress = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32NewSize);
1094         return pNewAddress;
1095     }
1096 
1097     if ( u32NewSize == 0)
1098     {
1099         //free
1100         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress);
1101         return NULL;
1102     }
1103 
1104     //mvarimpl.inl
1105     struct memdq {
1106         struct memdq *prev, *next;
1107         MS_S32 size;
1108     };
1109 
1110     struct memdq *dq = (struct memdq *) ((MS_VIRT )pOrgAddress  - sizeof(struct memdq));
1111     u32OrgSize = dq->size - sizeof(struct memdq);   //dq->size was rounded up to 16B-aligned when malloc, so u32OrgSize may be larger than requested
1112 
1113     //No resize function is implemented, so malloc a new block directly
1114     pNewAddress = cyg_mempool_var_try_alloc( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, u32NewSize);
1115 
1116     if ( pNewAddress != NULL) //move to a new block
1117     {
1118         if ( u32NewSize < u32OrgSize)
1119         {
1120             memcpy( pNewAddress, pOrgAddress, u32NewSize );
1121         }
1122         else
1123         {
1124             memcpy( pNewAddress, pOrgAddress, u32OrgSize );
1125         }
1126         cyg_mempool_var_free( _MsOS_MemoryPool_Info[s32PoolId].stMemoryPool, pOrgAddress);
1127 
1128     }
1129     else //not enough available memory to expand the block to the given size
1130     {
1131         //the original block is unchanged
1132     }
1133 #endif /* if USE_DLMALLOC */
1134 
1135     return pNewAddress;
1136 }
1137 
1138 //
1139 // Task
1140 //
1141 //-------------------------------------------------------------------------------------------------
1142 /// Create a task
1143 /// @param  pTaskEntry       \b IN: task entry point
1144 /// @param  u32TaskEntryData \b IN: task entry data: a pointer to some static data, or a
1145 ///          small integer, or NULL if the task does not require any additional data.
1146 /// @param  eTaskPriority    \b IN: task priority
1147 /// @param  bAutoStart       \b IN: start immediately or later
1148 /// @param  pStackBase       \b IN: task stack
1149 /// @param  u32StackSize     \b IN: stack size
1150 /// @param  pTaskName        \b IN: task name
1151 /// @return >=0 : assigned Task ID
1152 /// @return < 0 : fail
1153 //-------------------------------------------------------------------------------------------------
MsOS_CreateTask(TaskEntry pTaskEntry,MS_VIRT u32TaskEntryData,TaskPriority eTaskPriority,MS_BOOL bAutoStart,void * pStackBase,MS_U32 u32StackSize,char * pTaskName)1154 MS_S32 MsOS_CreateTask (TaskEntry pTaskEntry,
1155                      MS_VIRT u32TaskEntryData,
1156                      TaskPriority eTaskPriority,
1157                      MS_BOOL bAutoStart,
1158                      void * pStackBase,
1159                      MS_U32 u32StackSize,
1160                      char *pTaskName)
1161 {
1162     MS_S32 s32Id;
1163     pthread_attr_t thread_attr;
1164 #if !defined (ANDROID)
1165     struct sched_param thrsched;
1166 #endif
1167 
1168     // Check parameters
1169     /* - MaxCC20080205
1170     if ( ((MS_U32)pStackBase & 0xFFF ) || (u32StackSize < PTHREAD_STACK_MIN)|| (u32StackSize & 0xFFF))
1171     {
1172         return -1;
1173     }
1174     // . MaxCC20080205 */
1175     //printf("pthread_mutex_lock\n");
1176     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Task_Mutex));
1177     for(s32Id=0; s32Id<MSOS_TASK_MAX; s32Id++)
1178     {
1179         if(_MsOS_Task_Info[s32Id].bUsed == FALSE)
1180         {
1181             if(_MsOS_Task_Info[s32Id].bWaitJoin == TRUE)
1182             {
1183                 if (0 == PTH_RET_CHK(pthread_join(_MsOS_Task_Info[s32Id].stThreadInfo, NULL)))
1184                 {
1185                     _MsOS_Task_Info[s32Id].bWaitJoin = FALSE;
1186                 }
1187                 else
1188                 {
1189                     MSOS_ERROR("thread %td join fail\n", (ptrdiff_t)s32Id);
1190                 }
1191             }
1192 
1193 			if((_MsOS_Task_Info[s32Id].pStackBase != NULL) && (_MsOS_Task_Info[s32Id].bStackMalloc == TRUE))
1194             {
1195 			    free(_MsOS_Task_Info[s32Id].pStackBase);
1196 				_MsOS_Task_Info[s32Id].pStackBase = NULL;
1197 				_MsOS_Task_Info[s32Id].bStackMalloc = FALSE;
1198 			}
1199 
1200             break;
1201         }
1202     }
1203     if( s32Id < MSOS_TASK_MAX)
1204     {
1205         _MsOS_Task_Info[s32Id].bUsed = TRUE;
1206         _MsOS_Task_Info[s32Id].bWaitJoin = TRUE;
1207     }
1208     //printf("pthread_mutex_unlock\n");
1209     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Task_Mutex));
1210 
1211     if( s32Id >= MSOS_TASK_MAX)
1212     {
1213         return -1;
1214     }
1215     //printf("pthread_attr_init\n");
1216     if (PTH_RET_CHK(pthread_attr_init(&thread_attr)))
1217     {
1218         return -1;
1219     }
1220 
1221     if (NULL != pStackBase)
1222     {
1223          //printf("posix_memalign\n");
1224 #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
1225         if (posix_memalign(&pStackBase, 0x1000, u32StackSize))
1226         {
1227             return -1;
1228         }
1229 #else
1230         pStackBase = memalign(0x1000, u32StackSize);
1231         if (0 == pStackBase)
1232         {
1233             return -1;
1234         }
1235 #endif
1236         MS_ASSERT(pStackBase);
1237         MS_ASSERT(0 == ((MS_VIRT)pStackBase & 0xFFF ));
1238         _MsOS_Task_Info[s32Id].pStackBase= pStackBase;
1239 		_MsOS_Task_Info[s32Id].bStackMalloc = TRUE;
1240     }
1241     else
1242     {
1243         _MsOS_Task_Info[s32Id].pStackBase= NULL;
1244     }
1245 
1246     _MsOS_Task_Info[s32Id].pTaskEntry = pTaskEntry;
1247     _MsOS_Task_Info[s32Id].u32TaskEntryData = u32TaskEntryData;
1248     memset(_MsOS_Task_Info[s32Id].pTaskName,'\0',sizeof(MAX_NAME));
1249     strncpy(_MsOS_Task_Info[s32Id].pTaskName,pTaskName,(MAX_NAME - 1));
1250 
1251     /* - MaxCC20080205
1252     if (pthread_attr_setstack(&thread_attr, (void*)(((MS_U32)pStackBase)+ u32StackSize), u32StackSize))
1253     {
1254         return -1;
1255     }
1256     // . MaxCC20080205 */
1257 #if !defined (ANDROID)
1258     //set thread priority
1259     pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);//thread will not exit after return until join
1260     //pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);//thread will auto exit after return.
1261     pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED);
1262     switch(eTaskPriority)
1263     {
1264         case E_TASK_PRI_SYS:
1265         case E_TASK_PRI_HIGHEST:
1266     		pthread_attr_setschedpolicy(&thread_attr, SCHED_RR);
1267             break;
1268         default:
1269             pthread_attr_setschedpolicy(&thread_attr, SCHED_OTHER);
1270             break;
1271     }
1272     pthread_attr_getschedparam(&thread_attr, &thrsched);
1273     switch(eTaskPriority)
1274     {
1275         case E_TASK_PRI_SYS:
1276                 thrsched.sched_priority = E_LINUX_PRI_SYS;
1277                 break;
1278         case E_TASK_PRI_HIGHEST:
1279                 thrsched.sched_priority = E_LINUX_PRI_HIGHEST;
1280                 break;
1281         case E_TASK_PRI_HIGH:
1282         case E_TASK_PRI_MEDIUM:
1283         case E_TASK_PRI_LOW:
1284         case E_TASK_PRI_LOWEST:
1285         default:
1286             thrsched.sched_priority = sched_get_priority_min(SCHED_OTHER);
1287                 break;
1288     }
1289     pthread_attr_setschedparam(&thread_attr, &thrsched);
1290     //pthread_attr_getschedparam(&thread_attr, &thrsched);printf("%d\n",thrsched.sched_priority);
1291     //printf("max=%d,min=%d\n",sched_get_priority_max(SCHED_RR),sched_get_priority_min(SCHED_RR));
1292 #endif
1293 
1294     // @FIXME:
1295     //     (1) eTaskPriority: Task priority is ignored here
1296     //     (2) bAutoStart: Auto start is ignored here
1297     //     (3) pTaskName: is ignored here
1298     //printf("pthread_create\n");
1299     PTH_RET_CHK(pthread_create(&_MsOS_Task_Info[s32Id].stThreadInfo,
1300                                &thread_attr,
1301                                _MsOS_LinuxTaskWrapper,
1302                                (void *)&_MsOS_Task_Info[s32Id]));
1303 
1304 
1305 
1306 
1307 
1308     s32Id |= MSOS_ID_PREFIX;
1309     return s32Id;
1310 }
1311 
1312 
1313 //-------------------------------------------------------------------------------------------------
1314 /// Delete a previously created task
1315 /// @param  s32TaskId   \b IN: task ID
1316 /// @return TRUE : succeed
1317 /// @return FALSE : fail
1318 //-------------------------------------------------------------------------------------------------
MsOS_DeleteTask(MS_S32 s32TaskId)1319 MS_BOOL MsOS_DeleteTask (MS_S32 s32TaskId)
1320 {
1321     if ((s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX)
1322     {
1323         return FALSE;
1324     }
1325 
1326     else
1327     {
1328         s32TaskId &= MSOS_ID_MASK;
1329     }
1330 
1331     #if 0
1332     if( _MsOS_Task_Info[s32TaskId].bUsed == FALSE )
1333     {
1334         printf("TASK WITH TASK_ID:0x%lx NOT EXIST\n",s32TaskId);
1335         return FALSE ;
1336     }
1337     #endif
1338 
1339 
1340 #if defined (ANDROID)
1341     MSOS_WARN("ERROR!!! pthread_cancel() is not supported by BIONIC libc\n");
1342 #else
1343     if (_MsOS_Task_Info[s32TaskId].stThreadInfo != (int)NULL)
1344     {
1345         PTH_RET_CHK(pthread_cancel(_MsOS_Task_Info[s32TaskId].stThreadInfo));
1346     }
1347     else
1348     {
1349         MSOS_ERROR("TASK WITH TASK_ID: %td NOT EXIST\n", (ptrdiff_t)s32TaskId);
1350         return FALSE ;
1351     }
1352 #endif
1353 
1354     if (0== PTH_RET_CHK(pthread_join(_MsOS_Task_Info[s32TaskId].stThreadInfo, NULL)))
1355     {
1356         PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Task_Mutex));
1357         if (_MsOS_Task_Info[s32TaskId].pStackBase)
1358         {
1359             free(_MsOS_Task_Info[s32TaskId].pStackBase);
1360             _MsOS_Task_Info[s32TaskId].pStackBase= NULL;
1361         }
1362         _MsOS_Task_Info[s32TaskId].bUsed = FALSE;
1363         _MsOS_Task_Info[s32TaskId].bWaitJoin = FALSE;
1364 
1365         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Task_Mutex));
1366         return TRUE;
1367     }
1368     else
1369     {
1370         return FALSE;
1371     }
1372 }
1373 
1374 
1375 //-------------------------------------------------------------------------------------------------
1376 /// Yield the execution right to ready tasks with "the same" priority
1377 /// @return None
1378 //-------------------------------------------------------------------------------------------------
MsOS_YieldTask(void)1379 void MsOS_YieldTask (void)
1380 {
1381     sched_yield();
1382 }
1383 
1384 //-------------------------------------------------------------------------------------------------
1385 /// Suspend the calling task for u32Ms milliseconds
1386 /// @param  u32Ms  \b IN: delay 1 ~ MSOS_WAIT_FOREVER ms
1387 /// @return None
1388 /// @note   Not allowed in interrupt context; otherwise, exception will occur.
1389 //-------------------------------------------------------------------------------------------------
MsOS_DelayTask(MS_U32 u32Ms)1390 void MsOS_DelayTask (MS_U32 u32Ms)
1391 {
1392     struct timespec req, rem;
1393     if(u32Ms >= 1000)
1394     {
1395         req.tv_sec = u32Ms/1000;
1396         req.tv_nsec = (long) ((u32Ms%1000)*1000000UL);
1397     }
1398     else
1399     {
1400         req.tv_sec = 0;
1401         req.tv_nsec = (long) (u32Ms*1000000UL);
1402     }
1403 
1404     //u32Ms=0 => The task will enter sleep state and wake up immediately with relative trigger time = 0
1405     // => Other ready tasks with the same or lower priorities will have no chance to run
1406     MS_ASSERT( u32Ms != 0);
1407 
1408     while(1)
1409     {
1410         MS_S32 err;
1411 
1412         err = nanosleep(&req, &rem);
1413 
1414         if(err==-1)
1415         {
1416             switch(errno)
1417             {
1418                 case EINTR:
1419                     req.tv_sec = rem.tv_sec;
1420                     req.tv_nsec = rem.tv_nsec;
1421                    continue;
1422                 default:
1423                     if(errno !=(int)NULL)
1424                         MSOS_ERROR("nanosleep is interrupted: %d\n", errno);
1425                     break;
1426             }
1427 
1428         }
1429 
1430         break;
1431     }
1432 }
1433 
1434 //-------------------------------------------------------------------------------------------------
1435 /// Delay for u32Us microseconds
1436 /// @param  u32Us  \b IN: delay 0 ~ 999 us
1437 /// @return None
1438 /// @note   implemented by "busy waiting". Plz call MsOS_DelayTask directly for ms-order delay
1439 //-------------------------------------------------------------------------------------------------
MsOS_DelayTaskUs(MS_U32 u32Us)1440 void MsOS_DelayTaskUs (MS_U32 u32Us)
1441 {
1442     struct timespec req, rem;
1443     req.tv_sec = 0;
1444     req.tv_nsec = (long) (u32Us*1000UL);
1445 
1446     while(1)
1447     {
1448         MS_S32 err;
1449 
1450         err = nanosleep(&req, &rem);
1451         if(err==-1)
1452         {
1453            switch(errno)
1454            {
1455               case EINTR:
1456                   req.tv_sec = rem.tv_sec;
1457                   req.tv_nsec = rem.tv_nsec;
1458                   continue;
1459               default:
1460                   if(errno !=(int)NULL)
1461                       MSOS_ERROR("nanosleep is interrupted: %d\n", errno);
1462                   break;
1463            }
1464 
1465       }
1466 
1467         break;
1468     }
1469 }
1470 
1471 //-------------------------------------------------------------------------------------------------
1472 /// Delay Poll for u32Us microseconds
1473 /// @param  u32Us  \b IN: delay 0 ~ 999 us
1474 /// @return None
1475 /// @note   implemented by "busy waiting". Plz call MsOS_DelayTask directly for ms-order delay
1476 //-------------------------------------------------------------------------------------------------
MsOS_DelayTaskUs_Poll(MS_U32 u32Us)1477 void MsOS_DelayTaskUs_Poll(MS_U32 u32Us)
1478 {
1479     struct timespec prev, cur;
1480 	MS_U32 u32Ns = (long) (u32Us*1000UL);
1481 
1482 	clock_gettime(CLOCK_REALTIME, &prev);
1483 
1484 	do
1485 	{
1486 		 clock_gettime(CLOCK_REALTIME, &cur);
1487 		 if (((cur.tv_nsec-prev.tv_nsec) + ((cur.tv_sec-prev.tv_sec)*1000000000UL)) >= u32Ns)
1488 			break;
1489 	} while (1);
1490 }
1491 
1492 //-------------------------------------------------------------------------------------------------
1493 /// Get task status
1494 /// @param  pTaskInfo       \b IN: task information structure pointer
1495 /// @param  peTaskState      \b OUT: ptr to task istate
1496 /// @return TRUE : succeed
1497 /// @return FALSE : invalid process result
1498 /// @note not support
1499 //-------------------------------------------------------------------------------------------------
MsOS_GetTaskStatus(Task_Info * pTaskInfo,TaskStatus * peTaskState)1500 MS_BOOL MsOS_GetTaskStatus (Task_Info* pTaskInfo, TaskStatus *peTaskState)
1501 {
1502 
1503     if ( (pTaskInfo == NULL) || (peTaskState == NULL))
1504     {
1505         return FALSE;
1506     }
1507 
1508     *peTaskState = E_TASK_INVALID_STATE;
1509     /* not support */
1510     return TRUE;
1511 }
1512 
1513 //-------------------------------------------------------------------------------------------------
1514 /// Resume the specified suspended task
1515 /// @param  s32TaskId   \b IN: Task ID
1516 /// @return TRUE : succeed
1517 /// @return FALSE : fail
1518 /// @note   This API is not supported in Linux
1519 //-------------------------------------------------------------------------------------------------
MsOS_ResumeTask(MS_S32 s32TaskId)1520 MS_BOOL MsOS_ResumeTask (MS_S32 s32TaskId)
1521 {
1522     return FALSE;
1523 }
1524 
1525 //-------------------------------------------------------------------------------------------------
1526 /// Suspend the specified task
1527 /// @param  s32TaskId   \b IN: Task ID
1528 /// @return TRUE : succeed
1529 /// @return FALSE : fail
1530 /// @note   This API is not supported in Linux
1531 //-------------------------------------------------------------------------------------------------
MsOS_SuspendTask(MS_S32 s32TaskId)1532 MS_BOOL MsOS_SuspendTask (MS_S32 s32TaskId)
1533 {
1534     return FALSE;
1535 }
1536 
1537 //-------------------------------------------------------------------------------------------------
1538 // Get a task information
1539 // @param  s32TaskId       \b IN: task ID
1540 // @param  peTaskPriority  \b OUT: ptr to task priority
1541 // @param  pu32StackSize   \b OUT: ptr to stack size
1542 // @param  pTaskName       \b OUT: ptr to task name
1543 // @return TRUE : succeed
1544 // @return FALSE : the task has not been created
1545 //-------------------------------------------------------------------------------------------------
MsOS_InfoTask(MS_S32 s32TaskId,TaskPriority * peTaskPriority,MS_U32 * pu32StackSize,char * pTaskName)1546 MS_BOOL MsOS_InfoTask (MS_S32 s32TaskId, TaskPriority *peTaskPriority, MS_U32 *pu32StackSize, char *pTaskName)
1547 {
1548     if ( (s32TaskId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1549     {
1550         return FALSE;
1551     }
1552     else
1553     {
1554         s32TaskId &= MSOS_ID_MASK;
1555     }
1556 
1557     //ToDO
1558     return TRUE;
1559 }
1560 
1561 //-------------------------------------------------------------------------------------------------
1562 /// Get current task ID
1563 /// @return >=0 : current task ID
1564 /// @return <0 : fail
1565 //-------------------------------------------------------------------------------------------------
MsOS_InfoTaskID(void)1566 MS_S32 MsOS_InfoTaskID (void)
1567 {
1568     MS_S32 s32Id;
1569     pthread_t self;
1570 
1571     self= pthread_self();
1572 
1573     for( s32Id=0; s32Id<MSOS_TASK_MAX; s32Id++)
1574     {
1575         if( self== _MsOS_Task_Info[s32Id].stThreadInfo)
1576         {
1577             break;
1578         }
1579     }
1580     if( s32Id < MSOS_TASK_MAX)
1581     {
1582         s32Id |= MSOS_ID_PREFIX;
1583         return s32Id;
1584     }
1585     else
1586     {
1587         return -1;
1588     }
1589 }
1590 
1591 //-------------------------------------------------------------------------------------------------
1592 /// Get thread ID of current thread/process in Linux
1593 /// @return : current thread ID
1594 //-------------------------------------------------------------------------------------------------
MsOS_GetOSThreadID(void)1595 MS_S32 MsOS_GetOSThreadID (void)
1596 {
1597     return (MS_S32)pthread_self();
1598 }
1599 
1600 //
1601 // Mutex
1602 //
1603 //-------------------------------------------------------------------------------------------------
1604 /// Create a mutex in the unlocked state
1605 /// @param  eAttribute  \b IN: E_MSOS_FIFO: suspended in FIFO order
1606 /// @param  pMutexName  \b IN: mutex name
1607 /// @param  u32Flag  \b IN: process data shared flag
1608 /// @return >=0 : assigned mutex Id
1609 /// @return <0 : fail
1610 /// @note   A mutex has the concept of an owner, whereas a semaphore does not.
1611 ///         A mutex provides priority inheritance protocol against proiorty inversion, whereas a binary semaphore does not.
1612 //-------------------------------------------------------------------------------------------------
MsOS_CreateMutex(MsOSAttribute eAttribute,char * pMutexName1,MS_U32 u32Flag)1613 MS_S32 MsOS_CreateMutex ( MsOSAttribute eAttribute, char *pMutexName1, MS_U32 u32Flag)
1614 {
1615     MS_S32 s32Id, s32LstUnused = MSOS_MUTEX_MAX;
1616     pthread_mutexattr_t _MsOS_Mutex_Attr;
1617     MS_S32 s32Prop = (MSOS_PROCESS_PRIVATE == u32Flag)? PTHREAD_PROCESS_PRIVATE: PTHREAD_PROCESS_SHARED;
1618     MS_U8 pMutexName[MAX_MUTEX_NAME_LENGTH];
1619     MS_U32 u32MaxLen;
1620 
1621     if (NULL == pMutexName1)
1622     {
1623         return -1L;
1624     }
1625     if (strlen(pMutexName1) >= (MAX_MUTEX_NAME_LENGTH-1))
1626     {
1627         MSOS_WARN("%s: Warning strlen(%s) is longer than MAX_MUTEX_NAME_LENGTH(%d). Oversize char will be discard.\n",
1628         __FUNCTION__,pMutexName1,MAX_MUTEX_NAME_LENGTH);
1629     }
1630     if (0 == (u32MaxLen = MIN(strlen(pMutexName1), (MAX_MUTEX_NAME_LENGTH-1))))
1631     {
1632         return -1L;
1633     }
1634     strncpy((char*)pMutexName, (const char*)pMutexName1, u32MaxLen);
1635     pMutexName[u32MaxLen] = '\0';
1636 
1637 #if defined (TV_OS)
1638     if (u32MSos_Mutex_Index < 0)
1639     {
1640         u32MSos_Mutex_Index = MsOS_CreateNamedMutex((MS_S8*)MUTEX_MUTEX_NAME);
1641         if(u32MSos_Mutex_Index < 0)
1642         {
1643             MSOS_ERROR("%s : %d,crate named mutex %s \n",__FUNCTION__,__LINE__,MUTEX_MUTEX_NAME);
1644             return FALSE;
1645         }
1646     }
1647 #endif
1648 
1649     MUTEX_MUTEX_LOCK();
1650     for (s32Id=0;s32Id<MSOS_MUTEX_MAX;s32Id++)
1651     {
1652         // if (PTHREAD_PROCESS_SHARED == s32Prop) // @FIXME: Richard: is the mutex name always used as an id, regardless of process shared/private property?
1653         {
1654             if(TRUE == _MsOS_Mutex_Info[s32Id].bUsed)
1655             {
1656                 if (0== strcmp((const char*)_MsOS_Mutex_Info[s32Id].u8Name, (const char*)pMutexName))
1657                 {
1658                     break;
1659                 }
1660             }
1661         }
1662         if (FALSE==_MsOS_Mutex_Info[s32Id].bUsed  && MSOS_MUTEX_MAX==s32LstUnused)
1663         {
1664             s32LstUnused = s32Id;
1665         }
1666     }
1667     if ((MSOS_MUTEX_MAX==s32Id) && (MSOS_MUTEX_MAX>s32LstUnused))
1668     {
1669 #if defined (TV_OS)
1670         if (PTHREAD_PROCESS_SHARED == s32Prop)       //want shared mutex
1671         {
1672             _MsOS_Mutex_Info[s32LstUnused].bUsed = TRUE;
1673             strncpy((char*)_MsOS_Mutex_Info[s32LstUnused].u8Name, (const char*)pMutexName,MIN(strlen((const char*)pMutexName),(MAX_MUTEX_NAME_LENGTH-1)));
1674             _MsOS_Mutex_Info[s32LstUnused].msos_mutex.u32Index = MsOS_CreateNamedMutex((MS_S8*)_MsOS_Mutex_Info[s32LstUnused].u8Name);
1675             if(_MsOS_Mutex_Info[s32LstUnused].msos_mutex.u32Index < 0)
1676             {
1677                 MSOS_ERROR("~!~%s create %s fail \n",__FUNCTION__,_MsOS_Mutex_Info[s32LstUnused].u8Name);
1678                 return -1L;
1679             }
1680             _MsOS_Mutex_Info[s32LstUnused].bShared = TRUE;
1681         }
1682         else        //want local mutex
1683         {
1684             PTH_RET_CHK(pthread_mutexattr_init(&_MsOS_Mutex_Attr));
1685             PTH_RET_CHK(pthread_mutexattr_setpshared(&_MsOS_Mutex_Attr, s32Prop));
1686            //PTH_RET_CHK(pthread_mutexattr_setprotocol(&_MsOS_Mutex_Attr, PTHREAD_PRIO_INHERIT));
1687          #ifdef MS_DEBUG
1688             PTH_RET_CHK(pthread_mutexattr_settype(&_MsOS_Mutex_Attr, PTHREAD_MUTEX_ERRORCHECK));
1689          #endif
1690             _MsOS_Mutex_Info[s32LstUnused].bUsed = TRUE;
1691             strncpy((char*)_MsOS_Mutex_Info[s32LstUnused].u8Name, (const char*)pMutexName,MIN(strlen((const char*)pMutexName),(MAX_MUTEX_NAME_LENGTH-1)));
1692             PTH_RET_CHK(pthread_mutex_init(&_MsOS_Mutex_Info[s32LstUnused].msos_mutex.stMutex, &_MsOS_Mutex_Attr));
1693             _MsOS_Mutex_Info[s32LstUnused].bShared = FALSE;
1694         }
1695         s32Id = s32LstUnused;
1696 #else
1697         PTH_RET_CHK(pthread_mutexattr_init(&_MsOS_Mutex_Attr));
1698         PTH_RET_CHK(pthread_mutexattr_setpshared(&_MsOS_Mutex_Attr, s32Prop));
1699        //PTH_RET_CHK(pthread_mutexattr_setprotocol(&_MsOS_Mutex_Attr, PTHREAD_PRIO_INHERIT));
1700      #ifdef MS_DEBUG
1701         PTH_RET_CHK(pthread_mutexattr_settype(&_MsOS_Mutex_Attr, PTHREAD_MUTEX_ERRORCHECK));
1702      #endif
1703         _MsOS_Mutex_Info[s32LstUnused].bUsed = TRUE;
1704         strncpy((char*)_MsOS_Mutex_Info[s32LstUnused].u8Name, (const char*)pMutexName,MIN(strlen((const char*)pMutexName),(MAX_MUTEX_NAME_LENGTH-1)));
1705         PTH_RET_CHK(pthread_mutex_init(&_MsOS_Mutex_Info[s32LstUnused].stMutex, &_MsOS_Mutex_Attr));
1706         s32Id = s32LstUnused;
1707 #endif
1708     }
1709     MUTEX_MUTEX_UNLOCK();
1710 
1711     if(MSOS_MUTEX_MAX <= s32Id)
1712     {
1713         return -1L;
1714     }
1715 
1716     s32Id |= MSOS_ID_PREFIX;
1717 
1718     return s32Id;
1719 }
1720 
1721 //-------------------------------------------------------------------------------------------------
1722 /// Delete the specified mutex
1723 /// @param  s32MutexId  \b IN: mutex ID
1724 /// @return TRUE : succeed
1725 /// @return FALSE : fail
1726 /// @note   It is important that the mutex be in the unlocked state when it is
1727 ///            destroyed, or else the behavior is undefined.
1728 //-------------------------------------------------------------------------------------------------
MsOS_DeleteMutex(MS_S32 s32MutexId)1729 MS_BOOL MsOS_DeleteMutex (MS_S32 s32MutexId)
1730 {
1731     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1732     {
1733         return FALSE;
1734     }
1735     else
1736     {
1737         s32MutexId &= MSOS_ID_MASK;
1738     }
1739 
1740     #if 1
1741     if( (_MsOS_Mutex_Info[s32MutexId].bUsed == FALSE))
1742     {
1743         MSOS_ERROR("MUTEX WITH MUTEX_ID: %td NOT EXIST\n", (ptrdiff_t)s32MutexId);
1744         return FALSE;
1745     }
1746     #endif
1747 
1748     MUTEX_MUTEX_LOCK();
1749 
1750     MS_ASSERT(_MsOS_Mutex_Info[s32MutexId].bUsed);
1751 
1752 #if defined (TV_OS)
1753     if(_MsOS_Mutex_Info[s32MutexId].bShared)
1754         MsOS_DeleteNamedMutexbyIndex((_MsOS_Mutex_Info[s32MutexId].msos_mutex.u32Index));
1755     else
1756         PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Mutex_Info[s32MutexId].msos_mutex.stMutex));
1757 #else
1758     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Mutex_Info[s32MutexId].stMutex));
1759 #endif
1760 
1761     _MsOS_Mutex_Info[s32MutexId].bUsed = FALSE;
1762     memset(_MsOS_Mutex_Info[s32MutexId].u8Name,0x00,sizeof(_MsOS_Mutex_Info[s32MutexId].u8Name));
1763 
1764 
1765     MUTEX_MUTEX_UNLOCK();
1766 
1767     return TRUE;
1768 }
1769 
1770 //-------------------------------------------------------------------------------------------------
1771 /// Attempt to lock a mutex
1772 /// @param  s32MutexId  \b IN: mutex ID
1773 /// @param  u32WaitMs   \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the mutex is locked
1774 /// @return TRUE : succeed
1775 /// @return FALSE : fail
1776 //-------------------------------------------------------------------------------------------------
MsOS_ObtainMutex(MS_S32 s32MutexId,MS_U32 u32WaitMs)1777 MS_BOOL MsOS_ObtainMutex (MS_S32 s32MutexId, MS_U32 u32WaitMs)
1778 {
1779     MS_BOOL bRet = FALSE;
1780 
1781     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1782     {
1783         return FALSE;
1784     }
1785     else
1786     {
1787         s32MutexId &= MSOS_ID_MASK;
1788     }
1789 
1790     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
1791     {
1792 #if defined (TV_OS)
1793         if (_MsOS_Mutex_Info[s32MutexId].bShared)
1794         {
1795             if(!MsOS_LockMutex(_MsOS_Mutex_Info[s32MutexId].msos_mutex.u32Index,0))
1796             {
1797                 fprintf(stderr, "Mutex Name: %s\n", _MsOS_Mutex_Info[s32MutexId].u8Name);
1798             }
1799             else
1800             {
1801                 bRet = TRUE;
1802             }
1803         }
1804         else
1805         {
1806             if(PTH_RET_CHK(pthread_mutex_lock(&(_MsOS_Mutex_Info[s32MutexId].msos_mutex.stMutex))))
1807             {
1808                 fprintf(stderr, "Mutex Name: %s\n", _MsOS_Mutex_Info[s32MutexId].u8Name);
1809             }
1810             else
1811             {
1812                 bRet = TRUE;
1813             }
1814         }
1815 #else
1816         if (PTH_RET_CHK(pthread_mutex_lock(&(_MsOS_Mutex_Info[s32MutexId].stMutex))))
1817         {
1818             fprintf(stderr, "Mutex Name: %s\n", _MsOS_Mutex_Info[s32MutexId].u8Name);
1819         }
1820         else
1821         {
1822             bRet = TRUE;
1823         }
1824 #endif
1825     }
1826     else if (u32WaitMs==0) //non-blocking
1827     {
1828 #if defined (TV_OS)
1829         if (_MsOS_Mutex_Info[s32MutexId].bShared)
1830         {
1831             if(!MsOS_LockMutex(_MsOS_Mutex_Info[s32MutexId].msos_mutex.u32Index,-1))      //!!!!!!  imply later
1832                 bRet = TRUE;
1833         }
1834         else
1835         {
1836             if (!PTH_RET_CHK(pthread_mutex_trylock(&_MsOS_Mutex_Info[s32MutexId].msos_mutex.stMutex)))
1837                 bRet = TRUE;
1838         }
1839 #else
1840         if (!PTH_RET_CHK(pthread_mutex_trylock(&_MsOS_Mutex_Info[s32MutexId].stMutex)))
1841         {
1842             bRet = TRUE;
1843         }
1844 #endif
1845     }
1846     else //blocking wait with timeout
1847     {
1848 #if defined (TV_OS)
1849         if (_MsOS_Mutex_Info[s32MutexId].bShared)
1850             bRet = MsOS_LockMutex(_MsOS_Mutex_Info[s32MutexId].msos_mutex.u32Index,u32WaitMs);
1851         else
1852         {
1853             PTH_RET_CHK(pthread_mutex_lock(&(_MsOS_Mutex_Info[s32MutexId].msos_mutex.stMutex)));
1854             bRet = TRUE;
1855         }
1856 #else
1857         struct timespec         StopTime;
1858         _TimeAbs(StopTime, u32WaitMs);
1859         bRet= (PTH_RET_CHK(pthread_mutex_timedlock(&_MsOS_Mutex_Info[s32MutexId].stMutex, &StopTime)))? FALSE: TRUE;
1860 #endif
1861     }
1862 
1863     return bRet;
1864 }
1865 
1866 //-------------------------------------------------------------------------------------------------
1867 /// Attempt to unlock a mutex
1868 /// @param  s32MutexId  \b IN: mutex ID
1869 /// @return TRUE : succeed
1870 /// @return FALSE : fail
1871 /// @note   Only the owner thread of the mutex can unlock it.
1872 //-------------------------------------------------------------------------------------------------
MsOS_ReleaseMutex(MS_S32 s32MutexId)1873 MS_BOOL MsOS_ReleaseMutex (MS_S32 s32MutexId)
1874 {
1875     MS_BOOL bRet = TRUE;
1876     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1877     {
1878         return FALSE;
1879     }
1880     else
1881     {
1882         s32MutexId &= MSOS_ID_MASK;
1883     }
1884 #if defined (TV_OS)
1885     if(_MsOS_Mutex_Info[s32MutexId].bShared)
1886     {
1887         if(!MsOS_UnlockMutex(_MsOS_Mutex_Info[s32MutexId].msos_mutex.u32Index,5))
1888         {
1889             bRet = FALSE;
1890             fprintf(stderr, "Mutex Name: %s\n", _MsOS_Mutex_Info[s32MutexId].u8Name);
1891         }
1892     }
1893     else
1894     {
1895         if(PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Mutex_Info[s32MutexId].msos_mutex.stMutex)))
1896         {
1897             bRet = FALSE;
1898             fprintf(stderr, "Mutex Name: %s\n", _MsOS_Mutex_Info[s32MutexId].u8Name);
1899         }
1900     }
1901 #else
1902     if(PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Mutex_Info[s32MutexId].stMutex)))
1903     {
1904         bRet = FALSE;
1905         fprintf(stderr, "Mutex Name: %s\n", _MsOS_Mutex_Info[s32MutexId].u8Name);
1906     }
1907 #endif
1908 
1909     return bRet;
1910 }
1911 
1912 //-------------------------------------------------------------------------------------------------
1913 /// Attempt to unlock a mutex by another thread
1914 /// @param  s32MutexId  \b IN: mutex ID
1915 /// @param  bEnable     \b IN: True(Enable) or False(Disable)
1916 /// @return TRUE : succeed
1917 /// @return FALSE : fail
1918 /// @note   Let another thread can unlock it.
1919 //-------------------------------------------------------------------------------------------------
MsOS_EnableCrossThreadReleaseMutex(MS_S32 s32MutexId,MS_BOOL bEnable)1920 MS_BOOL MsOS_EnableCrossThreadReleaseMutex (MS_S32 s32MutexId, MS_BOOL bEnable)
1921 {
1922 #if defined (TV_OS)
1923     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1924     {
1925         return FALSE;
1926     }
1927     else
1928     {
1929         s32MutexId &= MSOS_ID_MASK;
1930     }
1931     return MsOS_CrossThreadUnlockMutex(_MsOS_Mutex_Info[s32MutexId].msos_mutex.u32Index, bEnable);
1932 #else
1933     return TRUE;
1934 #endif
1935 }
1936 
1937 //-------------------------------------------------------------------------------------------------
1938 // Get a mutex informaton
1939 // @param  s32MutexId  \b IN: mutex ID
1940 // @param  peAttribute \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
1941 // @param  pMutexName  \b OUT: ptr to mutex name
1942 // @return TRUE : succeed
1943 // @return FALSE : the mutex has not been created.
1944 //-------------------------------------------------------------------------------------------------
MsOS_InfoMutex(MS_S32 s32MutexId,MsOSAttribute * peAttribute,char * pMutexName)1945 MS_BOOL MsOS_InfoMutex (MS_S32 s32MutexId, MsOSAttribute *peAttribute, char *pMutexName)
1946 {
1947     if ( (s32MutexId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
1948     {
1949         return FALSE;
1950     }
1951     else
1952     {
1953         s32MutexId &= MSOS_ID_MASK;
1954     }
1955 
1956     if(_MsOS_Mutex_Info[s32MutexId].bUsed == TRUE)
1957     {
1958         //ToDo: extend _MsOS_Mutex_Info structure ?
1959         *peAttribute = E_MSOS_FIFO; //only FIFO for eCos
1960         // @FIXME: linux porting
1961         // UTL_strcpy(pMutexName, "ABC");
1962         strncpy(pMutexName, (const char*)_MsOS_Mutex_Info[s32MutexId].u8Name,MIN(strlen((const char*)_MsOS_Mutex_Info[s32MutexId].u8Name),(MAX_MUTEX_NAME_LENGTH-1)));
1963         return TRUE;
1964     }
1965     else
1966     {
1967         return FALSE;
1968     }
1969 }
1970 
1971 //
1972 // Semaphore
1973 //
1974 //-------------------------------------------------------------------------------------------------
1975 /// Create a semaphore
1976 /// @param  u32InitCnt \b IN: initial semaphore value
1977 /// @param  eAttribute \b IN: E_MSOS_FIFO suspended in FIFO order
1978 /// @param  pSemaphoreName \b IN: semaphore name
1979 /// @return >=0 : assigned Semaphore Id
1980 /// @return <0 : fail
1981 /// @note   A semaphore does not have the concept of an owner; it is possible for one thread to lock a
1982 ///           binary semaphore and another thread to unlock it.
1983 //-------------------------------------------------------------------------------------------------
MsOS_CreateSemaphore(MS_U32 u32InitCnt,MsOSAttribute eAttribute,char * pSemaphoreName)1984 MS_S32 MsOS_CreateSemaphore (MS_U32 u32InitCnt,
1985                           MsOSAttribute eAttribute,
1986                           char *pSemaphoreName)
1987 {
1988     MS_S32 s32Id;
1989 
1990     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Semaphore_Mutex));
1991     for(s32Id=0;s32Id<MSOS_SEMAPHORE_MAX;s32Id++)
1992     {
1993         if(_MsOS_Semaphore_Info[s32Id].bUsed == FALSE)
1994         {
1995             break;
1996         }
1997     }
1998     if(s32Id < MSOS_SEMAPHORE_MAX)
1999     {
2000         _MsOS_Semaphore_Info[s32Id].bUsed = TRUE;
2001     }
2002     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Semaphore_Mutex));
2003 
2004     if(s32Id >= MSOS_SEMAPHORE_MAX)
2005     {
2006         return -1;
2007     }
2008 
2009     sem_init(&_MsOS_Semaphore_Info[s32Id].stSemaphore, 0, u32InitCnt);
2010     s32Id |= MSOS_ID_PREFIX;
2011 
2012     return s32Id;
2013 }
2014 
2015 //-------------------------------------------------------------------------------------------------
2016 /// Delete the specified semaphore
2017 /// @param  s32SemaphoreId  \b IN: semaphore ID
2018 /// @return TRUE : succeed
2019 /// @return FALSE : fail
2020 /// @note   It is important that there are not any threads waiting on the semaphore
2021 ///             when this function is called or the behavior is undefined.
2022 //-------------------------------------------------------------------------------------------------
MsOS_DeleteSemaphore(MS_S32 s32SemaphoreId)2023 MS_BOOL MsOS_DeleteSemaphore (MS_S32 s32SemaphoreId)
2024 {
2025     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2026     {
2027         return FALSE;
2028     }
2029     else
2030     {
2031         s32SemaphoreId &= MSOS_ID_MASK;
2032     }
2033 
2034     #if 1
2035     if(_MsOS_Semaphore_Info[s32SemaphoreId].bUsed == FALSE )
2036     {
2037         MSOS_ERROR("SEMAPHORE WITH SEMAPHORE_ID: %td NOT EXIST\n", (ptrdiff_t)s32SemaphoreId);
2038         return FALSE;
2039     }
2040     #endif
2041 
2042     sem_destroy(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore);
2043 
2044     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Semaphore_Mutex));
2045     _MsOS_Semaphore_Info[s32SemaphoreId].bUsed = FALSE;
2046     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Semaphore_Mutex));
2047     return TRUE;
2048 }
2049 
2050 //-------------------------------------------------------------------------------------------------
2051 /// Attempt to decrement a semaphore count
2052 /// @param  s32SemaphoreId  \b IN: semaphore ID
2053 /// @param  u32WaitMs       \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the semaphore count = 0
2054 /// @return TRUE : succeed
2055 /// @return FALSE : fail
2056 //-------------------------------------------------------------------------------------------------
MsOS_ObtainSemaphore(MS_S32 s32SemaphoreId,MS_U32 u32WaitMs)2057 MS_BOOL MsOS_ObtainSemaphore (MS_S32 s32SemaphoreId, MS_U32 u32WaitMs)
2058 {
2059     MS_BOOL bRet = FALSE;
2060 
2061     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2062     {
2063         return FALSE;
2064     }
2065     else
2066     {
2067         s32SemaphoreId &= MSOS_ID_MASK;
2068     }
2069 
2070     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
2071     {
2072         bRet = sem_wait(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore)  >=0 ? TRUE : FALSE;
2073     }
2074     else //blocking wait with timeout
2075     {
2076         struct timespec         StopTime;
2077 //        if (0== u32WaitMs)
2078 //        {
2079 //            u32WaitMs=          MSOS_TIME_MIN_WAIT_TV;
2080 //        }
2081         _TimeAbs(StopTime, u32WaitMs);
2082         bRet = sem_timedwait(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore, &StopTime) >=0 ? TRUE : FALSE;
2083     }
2084 
2085     return bRet;
2086 }
2087 
2088 //-------------------------------------------------------------------------------------------------
2089 /// Increase a semaphore count
2090 /// @param  s32SemaphoreId  \b IN: semaphore ID
2091 /// @return TRUE : succeed
2092 /// @return FALSE : fail
2093 /// @note   It's possible for any thread to increase the semaphore count
2094 //-------------------------------------------------------------------------------------------------
MsOS_ReleaseSemaphore(MS_S32 s32SemaphoreId)2095 MS_BOOL MsOS_ReleaseSemaphore (MS_S32 s32SemaphoreId)
2096 {
2097     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2098     {
2099         return FALSE;
2100     }
2101     else
2102     {
2103         s32SemaphoreId &= MSOS_ID_MASK;
2104     }
2105 
2106     return sem_post(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore) >= 0 ? TRUE : FALSE;
2107 }
2108 
2109 //-------------------------------------------------------------------------------------------------
2110 // Get a semaphore informaton
2111 // @param  s32SemaphoreId  \b IN: semaphore ID
2112 // @param  pu32InitCnt     \b OUT: ptr to initial semaphore value
2113 // @param  peAttribute     \b OUT: ptr to suspended mode: E_MSOS_FIFO / E_MSOS_PRIORITY
2114 // @param  pSemaphoreName  \b OUT: ptr to semaphore name
2115 // @return TRUE : succeed
2116 // @return FALSE : the semaphore has not been created.
2117 //-------------------------------------------------------------------------------------------------
MsOS_InfoSemaphore(MS_S32 s32SemaphoreId,MS_U32 * pu32InitCnt,MsOSAttribute * peAttribute,char * pSemaphoreName)2118 MS_BOOL MsOS_InfoSemaphore (MS_S32 s32SemaphoreId, MS_U32 *pu32InitCnt, MsOSAttribute *peAttribute, char *pSemaphoreName)
2119 {
2120     if ( (s32SemaphoreId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2121     {
2122         return FALSE;
2123     }
2124     else
2125     {
2126         s32SemaphoreId &= MSOS_ID_MASK;
2127     }
2128 
2129     return sem_getvalue(&_MsOS_Semaphore_Info[s32SemaphoreId].stSemaphore,
2130         (int *)pu32InitCnt) >= 0 ? TRUE : FALSE;
2131 }
2132 
2133 
2134 //
2135 // Event management
2136 //
2137 //-------------------------------------------------------------------------------------------------
2138 /// Create an event group
2139 /// @param  pEventName  \b IN: event group name
2140 /// @return >=0 : assigned Event Id
2141 /// @return <0 : fail
2142 //-------------------------------------------------------------------------------------------------
MsOS_CreateEventGroup(char * pEventName)2143 MS_S32 MsOS_CreateEventGroup (char *pEventName)
2144 {
2145     MS_S32 s32Id;
2146     pthread_mutexattr_t _MsOS_Mutex_Attr;
2147 #if !defined (ANDROID) || defined (__LP64__)
2148     pthread_condattr_t attr;
2149 #endif
2150 
2151     PTH_RET_CHK(pthread_mutexattr_init(&_MsOS_Mutex_Attr));
2152     //PTH_RET_CHK(pthread_mutexattr_setprotocol(&_MsOS_Mutex_Attr, PTHREAD_PRIO_INHERIT));
2153 #ifdef MS_DEBUG
2154     PTH_RET_CHK(pthread_mutexattr_settype(&_MsOS_Mutex_Attr, PTHREAD_MUTEX_ERRORCHECK));
2155 #endif
2156 
2157     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Mutex));
2158     for(s32Id=0; s32Id<MSOS_EVENTGROUP_MAX; s32Id++)
2159     {
2160         if(_MsOS_EventGroup_Info[s32Id].bUsed == FALSE)
2161         {
2162             break;
2163         }
2164     }
2165 
2166     if(s32Id < MSOS_EVENTGROUP_MAX)
2167     {
2168         PTH_RET_CHK(pthread_mutex_init(&_MsOS_EventGroup_Info[s32Id].stMutexEvent, &_MsOS_Mutex_Attr));
2169         PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Info[s32Id].stMutexEvent));
2170         _MsOS_EventGroup_Info[s32Id].bUsed = TRUE;
2171         _MsOS_EventGroup_Info[s32Id].u32EventGroup= 0;
2172         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Info[s32Id].stMutexEvent));
2173     }
2174     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Mutex));
2175 
2176     if(s32Id >= MSOS_EVENTGROUP_MAX)
2177     {
2178         return -1;
2179     }
2180 
2181     PTH_RET_CHK(pthread_mutex_init(&_MsOS_EventGroup_Info[s32Id].stMutex, &_MsOS_Mutex_Attr));
2182 #if !defined (ANDROID) || defined (__LP64__)
2183     // Set the clock to be CLOCK_MONOTONIC
2184     pthread_condattr_init(&attr);
2185     PTH_RET_CHK(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
2186     PTH_RET_CHK(pthread_cond_init(&_MsOS_EventGroup_Info[s32Id].stSemaphore, &attr));
2187 #else
2188     PTH_RET_CHK(pthread_cond_init(&_MsOS_EventGroup_Info[s32Id].stSemaphore, NULL));
2189 #endif
2190     s32Id |= MSOS_ID_PREFIX;
2191     return s32Id;
2192 }
2193 
2194 //-------------------------------------------------------------------------------------------------
2195 /// Delete the event group
2196 /// @param  s32EventGroupId \b IN: event group ID
2197 /// @return TRUE : succeed
2198 /// @return FALSE : fail, sb is waiting for the event flag
2199 /// @note event group that are being waited on must not be deleted
2200 //-------------------------------------------------------------------------------------------------
MsOS_DeleteEventGroup(MS_S32 s32EventGroupId)2201 MS_BOOL MsOS_DeleteEventGroup (MS_S32 s32EventGroupId)
2202 {
2203     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2204     {
2205         return FALSE;
2206     }
2207     else
2208     {
2209         s32EventGroupId &= MSOS_ID_MASK;
2210     }
2211 
2212     #if 1
2213     if( _MsOS_EventGroup_Info[s32EventGroupId].bUsed == FALSE)
2214     {
2215         MSOS_ERROR("EVENTGROUP WITH EVENTGROUP: %td NOT EXIST\n", (ptrdiff_t)s32EventGroupId);
2216         return FALSE;
2217     }
2218     #endif
2219 
2220     PTH_RET_CHK(pthread_cond_destroy(&_MsOS_EventGroup_Info[s32EventGroupId].stSemaphore));
2221     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_EventGroup_Info[s32EventGroupId].stMutex));
2222     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Mutex));
2223     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2224     _MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup= 0;
2225     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2226     _MsOS_EventGroup_Info[s32EventGroupId].bUsed = FALSE;
2227     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Mutex));
2228     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2229     return TRUE;
2230 }
2231 
2232 
2233 //-------------------------------------------------------------------------------------------------
2234 /// Set the event flag (bitwise OR w/ current value) in the specified event group
2235 /// @param  s32EventGroupId \b IN: event group ID
2236 /// @param  u32EventFlag    \b IN: event flag value
2237 /// @return TRUE : succeed
2238 /// @return FALSE : fail
2239 //-------------------------------------------------------------------------------------------------
MsOS_SetEvent(MS_S32 s32EventGroupId,MS_U32 u32EventFlag)2240 MS_BOOL MsOS_SetEvent (MS_S32 s32EventGroupId, MS_U32 u32EventFlag)
2241 {
2242     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2243     {
2244         return FALSE;
2245     }
2246     else
2247     {
2248         s32EventGroupId &= MSOS_ID_MASK;
2249     }
2250 
2251     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2252     SET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32EventFlag);
2253     PTH_RET_CHK(pthread_cond_broadcast(&_MsOS_EventGroup_Info[s32EventGroupId].stSemaphore));
2254     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2255     return TRUE;
2256 }
2257 
2258 //-------------------------------------------------------------------------------------------------
2259 /// Clear the specified event flag (bitwise XOR operation) in the specified event group
2260 /// @param  s32EventGroupId \b IN: event group ID
2261 /// @param  u32EventFlag    \b IN: event flag value
2262 /// @return TRUE : succeed
2263 /// @return FALSE : fail
2264 //-------------------------------------------------------------------------------------------------
MsOS_ClearEvent(MS_S32 s32EventGroupId,MS_U32 u32EventFlag)2265 MS_BOOL MsOS_ClearEvent (MS_S32 s32EventGroupId, MS_U32 u32EventFlag)
2266 {
2267     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2268     {
2269         return FALSE;
2270     }
2271     else
2272     {
2273         s32EventGroupId &= MSOS_ID_MASK;
2274     }
2275 
2276     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2277     RESET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32EventFlag);
2278     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2279     return TRUE;
2280 }
2281 
2282 //-------------------------------------------------------------------------------------------------
2283 /// Wait for the specified event flag combination from the event group
2284 /// @param  s32EventGroupId     \b IN: event group ID
2285 /// @param  u32WaitEventFlag    \b IN: wait event flag value
2286 /// @param  pu32RetrievedEventFlag \b OUT: retrieved event flag value
2287 /// @param  eWaitMode           \b IN: E_AND/E_OR/E_AND_CLEAR/E_OR_CLEAR
2288 /// @param  u32WaitMs           \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the event is not ready
2289 /// @return TRUE : succeed
2290 /// @return FALSE : fail
2291 //-------------------------------------------------------------------------------------------------
MsOS_WaitEvent(MS_S32 s32EventGroupId,MS_U32 u32WaitEventFlag,MS_U32 * pu32RetrievedEventFlag,EventWaitMode eWaitMode,MS_U32 u32WaitMs)2292 MS_BOOL MsOS_WaitEvent (MS_S32 s32EventGroupId,
2293                      MS_U32 u32WaitEventFlag,
2294                      MS_U32 *pu32RetrievedEventFlag,
2295                      EventWaitMode eWaitMode,
2296                      MS_U32 u32WaitMs)
2297 {
2298     MS_BOOL bRet= FALSE;
2299     struct timespec StopTime;
2300     MS_BOOL bAnd;
2301     MS_BOOL bClear;
2302 
2303     *pu32RetrievedEventFlag = 0;
2304 
2305     if (!u32WaitEventFlag)
2306     {
2307         return FALSE;
2308     }
2309 
2310     if ( (s32EventGroupId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2311     {
2312         return FALSE;
2313     }
2314     else
2315     {
2316         s32EventGroupId &= MSOS_ID_MASK;
2317     }
2318 
2319     bClear= ((E_AND_CLEAR== eWaitMode) || (E_OR_CLEAR== eWaitMode))? TRUE: FALSE;
2320     bAnd= ((E_AND== eWaitMode)|| (E_AND_CLEAR== eWaitMode))? TRUE: FALSE;
2321 
2322     if (u32WaitMs!= MSOS_WAIT_FOREVER) //blocking wait
2323     {
2324 //        if (0== u32WaitMs)
2325 //        {
2326 //            u32WaitMs=          MSOS_TIME_MIN_WAIT_TV;
2327 //        }
2328         _TimeAbsM(StopTime, u32WaitMs);
2329     }
2330 
2331     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2332     do{
2333         *pu32RetrievedEventFlag= HAS_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, u32WaitEventFlag);
2334         if ((bAnd)? (*pu32RetrievedEventFlag== u32WaitEventFlag): (0!= *pu32RetrievedEventFlag))
2335         {
2336             break;
2337         }
2338         if (u32WaitMs== MSOS_WAIT_FOREVER) //blocking wait
2339         {
2340             PTH_RET_CHK(pthread_cond_wait(&_MsOS_EventGroup_Info[s32EventGroupId].stSemaphore,
2341                                           &_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2342         }
2343         else if(u32WaitMs == 0)
2344         {
2345             break;
2346         }
2347         else
2348         {
2349 #if !defined (ANDROID) || defined (__LP64__)
2350             if (PTH_RET_CHK(pthread_cond_timedwait(&_MsOS_EventGroup_Info[s32EventGroupId].stSemaphore,
2351                                                    &_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,
2352                                                    &StopTime)))
2353 #else
2354             if (PTH_RET_CHK(pthread_cond_timedwait_monotonic(&_MsOS_EventGroup_Info[s32EventGroupId].stSemaphore,
2355                                                    &_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent,
2356                                                    &StopTime)))
2357 #endif
2358             {
2359                 break;
2360             }
2361         }
2362     } while (1);
2363 
2364     bRet= (bAnd)? (*pu32RetrievedEventFlag== u32WaitEventFlag): (0!= *pu32RetrievedEventFlag);
2365     if (bRet && bClear)
2366     {
2367         RESET_FLAG(_MsOS_EventGroup_Info[s32EventGroupId].u32EventGroup, *pu32RetrievedEventFlag);
2368     }
2369     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_EventGroup_Info[s32EventGroupId].stMutexEvent));
2370     return bRet;
2371 }
2372 
2373 //-------------------------------------------------------------------------------------------------
2374 /// Wait for the specified event flag combination from the event group
2375 /// @param  s32EventGroupId     \b IN: event group ID
2376 /// @param  u32WaitEventFlag    \b IN: wait event flag value
2377 /// @param  pu32RetrievedEventFlag \b OUT: retrieved event flag value
2378 /// @param  eWaitMode           \b IN: E_AND/E_OR/E_AND_CLEAR/E_OR_CLEAR
2379 /// @param  u32WaitMs           \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the event is not ready
2380 /// @return TRUE : succeed
2381 /// @return FALSE : fail
2382 //-------------------------------------------------------------------------------------------------
MsOS_WaitEvent_Interrupt(MS_S32 s32EventGroupId,MS_U32 u32WaitEventFlag,MS_U32 * pu32RetrievedEventFlag,EventWaitMode eWaitMode,MS_U32 u32WaitMs)2383 MS_S32 MsOS_WaitEvent_Interrupt(MS_S32 s32EventGroupId,
2384                      MS_U32 u32WaitEventFlag,
2385                      MS_U32 *pu32RetrievedEventFlag,
2386                      EventWaitMode eWaitMode,
2387                      MS_U32 u32WaitMs)
2388 {
2389     return  (MS_S32)MsOS_WaitEvent(s32EventGroupId,u32WaitEventFlag,pu32RetrievedEventFlag,eWaitMode,u32WaitMs);
2390 }
2391 
2392 //
2393 // Timer management
2394 //
2395 #ifdef UCLIBC
_MsOS_TimerNotify(MS_S32 sig,siginfo_t * si,void * uc)2396 static void _MsOS_TimerNotify(MS_S32 sig, siginfo_t *si, void *uc)
2397 {
2398     //printf("_MsOS_TimerNotify\n");
2399     timer_t *tidp;
2400     MS_S32 s32Id;
2401 
2402     tidp = si->si_value.sival_ptr;
2403     s32Id = (MS_S32)*tidp;
2404 
2405     MS_ASSERT(_MsOS_Timer_Info[s32Id].bUsed);
2406     _MsOS_Timer_Info[s32Id].pTimerCb(0, s32Id| MSOS_ID_PREFIX);
2407 }
2408 #else
_MsOS_TimerNotify(sigval_t v)2409 static void _MsOS_TimerNotify(sigval_t v)
2410 {
2411     MS_S32 s32Id= v.sival_int;
2412     int err = errno;
2413     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Timer_Info[s32Id].TimerMutex));
2414     MS_ASSERT(_MsOS_Timer_Info[s32Id].bUsed);
2415     if(_MsOS_Timer_Info[s32Id].bUsed)
2416         _MsOS_Timer_Info[s32Id].pTimerCb(0, s32Id| MSOS_ID_PREFIX);
2417     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Timer_Info[s32Id].TimerMutex));
2418     errno = err;
2419 }
2420 #endif
2421 
2422 #ifdef UCLIBC
Timer_Thread(void * data)2423 void Timer_Thread(void *data)
2424 {
2425     TimerSET curr_set;
2426     curr_set.create_ready= ((TimerSET*)data)->create_ready;
2427     curr_set.pTimerCb= ((TimerSET*)data)->pTimerCb;
2428     curr_set.u32FirstTimeMs= ((TimerSET*)data)->u32FirstTimeMs;
2429     curr_set.u32PeriodTimeMs= ((TimerSET*)data)->u32PeriodTimeMs;
2430     curr_set.bStartTimer= ((TimerSET*)data)->bStartTimer;
2431     curr_set.pTimerName= ((TimerSET*)data)->pTimerName;
2432     MS_S32 s32Id = ((TimerSET*)data)->s32Id;
2433 
2434     struct itimerspec StopTimer;
2435     struct itimerspec dummy;
2436     struct sigevent   SignalEvent;
2437     struct sigaction sa;
2438 
2439     sa.sa_flags = SA_SIGINFO;
2440     sa.sa_sigaction = _MsOS_TimerNotify;
2441     sigaddset(&sa.sa_mask, SIGRTMIN);
2442     sigemptyset(&sa.sa_mask);
2443     if (sigaction(SIGRTMIN, &sa, NULL) == -1)
2444     {
2445         // @FIXME: should not fail here. Do error handling later
2446         MS_ASSERT(0);
2447     }
2448     /* Block timer signal temporarily */
2449     MSOS_PRINT("Blocking signal %d\n", SIGRTMIN);
2450 
2451     if (sigprocmask(SIG_BLOCK, &sa.sa_mask, NULL) == -1)
2452     {
2453         // @FIXME: should not fail here. Do error handling later
2454         MS_ASSERT(0);
2455     }
2456     /* Create the timer */
2457     SignalEvent.sigev_notify = SIGEV_SIGNAL;
2458     SignalEvent.sigev_signo = SIGRTMIN;
2459     SignalEvent.sigev_value.sival_ptr = &s32Id;
2460 
2461     if (0 > timer_create(CLOCK_REALTIME, &SignalEvent, &_MsOS_Timer_Info[s32Id].TimerId))
2462     {
2463         MSOS_ERROR("Failed to Create the timer.\n");
2464         // @FIXME: should not fail here. Do error handling later
2465         MS_ASSERT(0);
2466     }
2467     /* Start the timer */
2468     _MsOS_Timer_Info[s32Id].pTimerCb=   curr_set.pTimerCb;
2469     _MsOS_Timer_Info[s32Id].TimeInfo.it_value.tv_sec=           curr_set.u32FirstTimeMs/1000;
2470     _MsOS_Timer_Info[s32Id].TimeInfo.it_value.tv_nsec=          (curr_set.u32FirstTimeMs- (_MsOS_Timer_Info[s32Id].TimeInfo.it_value.tv_sec)*1000)* 1000000;
2471     _MsOS_Timer_Info[s32Id].TimeInfo.it_interval.tv_sec=        curr_set.u32PeriodTimeMs/1000;
2472     _MsOS_Timer_Info[s32Id].TimeInfo.it_interval.tv_nsec=       (curr_set.u32PeriodTimeMs- (_MsOS_Timer_Info[s32Id].TimeInfo.it_interval.tv_sec)*1000)* 1000000;
2473     if(curr_set.bStartTimer)
2474     {
2475         if (0> timer_settime(_MsOS_Timer_Info[s32Id].TimerId, 0, &_MsOS_Timer_Info[s32Id].TimeInfo, &dummy))
2476         {
2477             // @FIXME: should not fail here. Do error handling later
2478             MS_ASSERT(0);
2479         }
2480     }
2481     else
2482     {
2483         memset(&StopTimer, 0, sizeof(StopTimer));
2484         if (0> timer_settime(_MsOS_Timer_Info[s32Id].TimerId, 0, &StopTimer, &dummy))
2485         {
2486             // @FIXME: should not fail here. Do error handling later
2487             MS_ASSERT(0);
2488         }
2489     }
2490     //Unblock signal
2491     if (sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL) == -1)
2492     {
2493         // @FIXME: should not fail here. Do error handling later
2494         MS_ASSERT(0);
2495     }
2496 
2497     ((TimerSET*)data)->create_ready=1;
2498     while(1)
2499     {
2500         sigwaitinfo(&sa.sa_mask, NULL);
2501     }
2502 }
2503 #endif
2504 
2505 //-------------------------------------------------------------------------------------------------
2506 /// Create a Timer
2507 /// @param  pTimerCb        \b IN: timer callback function
2508 /// @param  u32FirstTimeMs  \b IN: first ms for timer expiration
2509 /// @param  u32PeriodTimeMs \b IN: periodic ms for timer expiration after first expiration
2510 ///                                0: one shot timer
2511 /// @param  bStartTimer     \b IN: TRUE: activates the timer after it is created
2512 ///                                FALSE: leaves the timer disabled after it is created
2513 /// @param  pTimerName      \b IN: Timer name (not used by eCos)
2514 /// @return >=0 : assigned Timer ID
2515 ///         <0 : fail
2516 //-------------------------------------------------------------------------------------------------
MsOS_CreateTimer(TimerCb pTimerCb,MS_U32 u32FirstTimeMs,MS_U32 u32PeriodTimeMs,MS_BOOL bStartTimer,char * pTimerName)2517 MS_S32 MsOS_CreateTimer (TimerCb pTimerCb,
2518                       MS_U32 u32FirstTimeMs,
2519                       MS_U32 u32PeriodTimeMs,
2520                       MS_BOOL bStartTimer,
2521                       char *pTimerName)
2522 {
2523     MS_S32 s32Id;
2524     struct itimerspec StopTimer;
2525     struct itimerspec dummy;
2526     struct sigevent   SignalEvent;
2527 
2528     PTH_RET_CHK(pthread_mutex_lock( &_MsOS_Timer_Mutex));
2529     for(s32Id=0;s32Id<MSOS_TIMER_MAX;s32Id++)
2530     {
2531         if(_MsOS_Timer_Info[s32Id].bUsed == FALSE)
2532         {
2533             break;
2534         }
2535     }
2536     if(s32Id < MSOS_TIMER_MAX)
2537     {
2538         _MsOS_Timer_Info[s32Id].bUsed = TRUE;
2539     }
2540     PTH_RET_CHK(pthread_mutex_unlock( &_MsOS_Timer_Mutex));
2541 
2542     if(s32Id >= MSOS_TIMER_MAX)
2543     {
2544         return -1;
2545     }
2546 #ifdef UCLIBC //hardes
2547     TimerSET* curr_set = malloc(sizeof(TimerSET));
2548     curr_set->create_ready = 0;
2549     curr_set->pTimerCb=pTimerCb;
2550     curr_set->u32FirstTimeMs=u32FirstTimeMs;
2551     curr_set->u32PeriodTimeMs=u32PeriodTimeMs;
2552     curr_set->bStartTimer=bStartTimer;
2553     curr_set->pTimerName=pTimerName;
2554     curr_set->s32Id = s32Id;
2555     pthread_t id;
2556     MS_S32 ret;
2557     //ret=pthread_create(&id,NULL,(void *) _thread,NULL);
2558     ret=pthread_create(&id,NULL,(void *) Timer_Thread,(void *) curr_set);
2559     if(ret!=0){
2560         MSOS_ERROR("Create pthread error!\n");
2561         MS_ASSERT(0);
2562     }
2563     else
2564     {
2565         MSOS_PRINT ("Create pthread success!\n");
2566     }
2567     while(!curr_set->create_ready)
2568     {
2569         sleep(0);
2570     }
2571     free(curr_set);
2572     s32Id |= MSOS_ID_PREFIX;
2573     return s32Id;
2574 
2575 #else
2576     memset(&SignalEvent, 0, sizeof(SignalEvent));
2577     SignalEvent.sigev_notify=           SIGEV_THREAD;
2578     SignalEvent.sigev_notify_function=  _MsOS_TimerNotify;
2579     SignalEvent.sigev_value.sival_int=  s32Id;
2580 
2581     if(0> timer_create(CLOCK_REALTIME, &SignalEvent, &_MsOS_Timer_Info[s32Id].TimerId))
2582     {
2583         return -1;
2584     }
2585 
2586     _MsOS_Timer_Info[s32Id].pTimerCb=   pTimerCb;
2587     _MsOS_Timer_Info[s32Id].TimeInfo.it_value.tv_sec=           u32FirstTimeMs/1000;
2588     _MsOS_Timer_Info[s32Id].TimeInfo.it_value.tv_nsec=          (u32FirstTimeMs- (_MsOS_Timer_Info[s32Id].TimeInfo.it_value.tv_sec)*1000)* 1000000;
2589     _MsOS_Timer_Info[s32Id].TimeInfo.it_interval.tv_sec=        u32PeriodTimeMs/1000;
2590     _MsOS_Timer_Info[s32Id].TimeInfo.it_interval.tv_nsec=       (u32PeriodTimeMs- (_MsOS_Timer_Info[s32Id].TimeInfo.it_interval.tv_sec)*1000)* 1000000;
2591 
2592     if(bStartTimer)
2593     {
2594         if (0> timer_settime(_MsOS_Timer_Info[s32Id].TimerId, 0, &_MsOS_Timer_Info[s32Id].TimeInfo, &dummy))
2595         {
2596             // @FIXME: should not fail here. Do error handling later
2597             MS_ASSERT(0);
2598         }
2599     }
2600     else
2601     {
2602         memset(&StopTimer, 0, sizeof(StopTimer));
2603         if (0> timer_settime(_MsOS_Timer_Info[s32Id].TimerId, 0, &StopTimer, &dummy))
2604         {
2605             // @FIXME: should not fail here. Do error handling later
2606             MS_ASSERT(0);
2607         }
2608     }
2609 
2610     s32Id |= MSOS_ID_PREFIX;
2611     return s32Id;
2612 #endif
2613 }
2614 
2615 //-------------------------------------------------------------------------------------------------
2616 /// Delete the Timer
2617 /// @param  s32TimerId  \b IN: Timer ID
2618 /// @return TRUE : succeed
2619 /// @return FALSE : fail
2620 //-------------------------------------------------------------------------------------------------
MsOS_DeleteTimer(MS_S32 s32TimerId)2621 MS_BOOL MsOS_DeleteTimer (MS_S32 s32TimerId)
2622 {
2623     MsOS_StopTimer(s32TimerId);
2624     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2625     {
2626         return FALSE;
2627     }
2628     else
2629     {
2630         s32TimerId &= MSOS_ID_MASK;
2631     }
2632 
2633     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Timer_Info[s32TimerId].TimerMutex));
2634     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2635     {
2636         #ifdef UCLIBC
2637         kill(_MsOS_Timer_Pid[s32TimerId], SIGTERM);
2638         #endif
2639         timer_delete(_MsOS_Timer_Info[s32TimerId].TimerId);
2640         _MsOS_Timer_Info[s32TimerId].bUsed = FALSE;
2641         _MsOS_Timer_Info[s32TimerId].pTimerCb = NULL;
2642         memset(&_MsOS_Timer_Info[s32TimerId].TimeInfo, 0, sizeof(struct itimerspec));
2643         _MsOS_Timer_Info[s32TimerId].TimerId = 0;
2644         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Timer_Info[s32TimerId].TimerMutex));
2645         return TRUE;
2646     }
2647     else
2648     {
2649         MSOS_ERROR("TIMER WITH TIMER_ID: %td NOT EXIST\n", (ptrdiff_t)s32TimerId);
2650         PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Timer_Info[s32TimerId].TimerMutex));
2651         return FALSE;
2652     }
2653 }
2654 
2655 //-------------------------------------------------------------------------------------------------
2656 /// Start the Timer
2657 /// @param  s32TimerId  \b IN: Timer ID
2658 /// @return TRUE : succeed
2659 /// @return FALSE : fail
2660 //-------------------------------------------------------------------------------------------------
MsOS_StartTimer(MS_S32 s32TimerId)2661 MS_BOOL MsOS_StartTimer (MS_S32 s32TimerId)
2662 {
2663     struct itimerspec dummy;
2664 
2665     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2666     {
2667         return FALSE;
2668     }
2669     else
2670     {
2671         s32TimerId &= MSOS_ID_MASK;
2672     }
2673 
2674     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2675     {
2676         if(0> timer_settime(_MsOS_Timer_Info[s32TimerId].TimerId, 0, &_MsOS_Timer_Info[s32TimerId].TimeInfo, &dummy))
2677         {
2678             MS_ASSERT(0);
2679         }
2680         return TRUE;
2681     }
2682     else
2683     {
2684         return FALSE;
2685     }
2686 }
2687 
2688 //-------------------------------------------------------------------------------------------------
2689 /// Stop the Timer
2690 /// @param  s32TimerId  \b IN: Timer ID
2691 /// @return TRUE : succeed
2692 /// @return FALSE : fail
2693 /// @note   MsOS_StopTimer then MsOS_StartTimer => The timer will trigger at the same relative
2694 ///             intervals that it would have if it had not been disabled.
2695 //-------------------------------------------------------------------------------------------------
MsOS_StopTimer(MS_S32 s32TimerId)2696 MS_BOOL MsOS_StopTimer (MS_S32 s32TimerId)
2697 {
2698     struct itimerspec StopTimer;
2699     struct itimerspec dummy;
2700 
2701     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2702     {
2703         return FALSE;
2704     }
2705     else
2706     {
2707         s32TimerId &= MSOS_ID_MASK;
2708     }
2709 
2710     if( _MsOS_Timer_Info[s32TimerId].bUsed )
2711     {
2712         #ifdef UCLIBC
2713         // Need to kill previous thread and create a new thread for new timer?
2714         #endif
2715         memset(&StopTimer, 0, sizeof(StopTimer));
2716         if(0> timer_settime(_MsOS_Timer_Info[s32TimerId].TimerId, 0, &StopTimer, &dummy))
2717         {
2718            MS_ASSERT(0);
2719         }
2720         return TRUE;
2721     }
2722     else
2723     {
2724         return FALSE;
2725     }
2726 }
2727 
2728 //-------------------------------------------------------------------------------------------------
2729 /// Reset a Timer & reset the expiration periods
2730 /// @param  s32TimerId      \b IN: Timer ID
2731 /// @param  u32FirstTimeMs  \b IN: first ms for timer expiration
2732 /// @param  u32PeriodTimeMs \b IN: periodic ms for timer expiration after first expiration
2733 ///                                0: one shot timer
2734 /// @param  bStartTimer     \b IN: TRUE: activates the timer after it is created
2735 ///                                FALSE: leaves the timer disabled after it is created
2736 /// @return TRUE : succeed
2737 /// @return FALSE : fail
2738 //-------------------------------------------------------------------------------------------------
MsOS_ResetTimer(MS_S32 s32TimerId,MS_U32 u32FirstTimeMs,MS_U32 u32PeriodTimeMs,MS_BOOL bStartTimer)2739 MS_BOOL MsOS_ResetTimer (MS_S32 s32TimerId,
2740                       MS_U32 u32FirstTimeMs,
2741                       MS_U32 u32PeriodTimeMs,
2742                       MS_BOOL bStartTimer)
2743 {
2744     struct itimerspec StopTimer;
2745     struct itimerspec dummy;
2746 
2747     if ( (s32TimerId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2748     {
2749         return FALSE;
2750     }
2751     else
2752     {
2753         s32TimerId &= MSOS_ID_MASK;
2754     }
2755 
2756     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_value.tv_sec=           u32FirstTimeMs/1000;
2757     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_value.tv_nsec=          (u32FirstTimeMs- (_MsOS_Timer_Info[s32TimerId].TimeInfo.it_value.tv_sec)*1000)* 1000000;
2758     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_interval.tv_sec=        u32PeriodTimeMs/1000;
2759     _MsOS_Timer_Info[s32TimerId].TimeInfo.it_interval.tv_sec=        (u32PeriodTimeMs- (_MsOS_Timer_Info[s32TimerId].TimeInfo.it_interval.tv_sec)*1000)* 1000000;
2760 
2761 
2762     #ifdef UCLIBC
2763     // Need to kill previous thread and create a new thread for new timer
2764     #endif
2765 
2766     if(bStartTimer)
2767     {
2768         if (0> timer_settime(_MsOS_Timer_Info[s32TimerId].TimerId, 0, &_MsOS_Timer_Info[s32TimerId].TimeInfo, &dummy))
2769         {
2770             // @FIXME: should not fail here. Do error handling later
2771             MS_ASSERT(0);
2772         }
2773     }
2774     else
2775     {
2776         memset(&StopTimer, 0, sizeof(StopTimer));
2777         if (0> timer_settime(_MsOS_Timer_Info[s32TimerId].TimerId, 0, &StopTimer, &dummy))
2778         {
2779             // @FIXME: should not fail here. Do error handling later
2780             MS_ASSERT(0);
2781         }
2782     }
2783 
2784     return TRUE;
2785 }
2786 
2787 
2788 //
2789 // System time
2790 //
2791 //-------------------------------------------------------------------------------------------------
2792 /// Get current system time in ms
2793 /// @return system time in ms
2794 //-------------------------------------------------------------------------------------------------
MsOS_GetSystemTime(void)2795 MS_U32 MsOS_GetSystemTime (void)
2796 {
2797     struct timespec         ts;
2798 
2799 #ifdef UCLIBC
2800     clock_gettime(CLOCK_REALTIME, &ts);
2801 #else
2802     clock_gettime(CLOCK_MONOTONIC, &ts);
2803 #endif
2804     return ts.tv_sec* 1000+ ts.tv_nsec/1000000;
2805 }
2806 //-------------------------------------------------------------------------------------------------
2807 ///[OBSOLETE]
2808 /// Time difference between current time and task time
2809 /// @return system time diff in ms
2810 //-------------------------------------------------------------------------------------------------
MsOS_Timer_DiffTimeFromNow(MS_U32 u32TaskTimer)2811 MS_U32 MsOS_Timer_DiffTimeFromNow(MS_U32 u32TaskTimer) //unit = ms
2812 {
2813     return (MsOS_GetSystemTime() - u32TaskTimer);
2814 }
2815 //-------------------------------------------------------------------------------------------------
2816 ///[OBSOLETE]
2817 /// Time difference between setting time and task time
2818 /// @return system time diff in ms
2819 //-------------------------------------------------------------------------------------------------
MsOS_Timer_DiffTime(MS_U32 u32Timer,MS_U32 u32TaskTimer)2820 MS_U32 MsOS_Timer_DiffTime(MS_U32 u32Timer, MS_U32 u32TaskTimer) //unit = ms
2821 {
2822     // simple minus is enough, because max(timer_counter) == max(u32)
2823     return (u32Timer - u32TaskTimer);
2824 }
2825 /*
2826 //COUNT was reset at system initialization
2827 //-------------------------------------------------------------------------------------------------
2828 /// Set current system time
2829 /// @param  u32SystemTime  \b IN: system time in ms
2830 /// @return TRUE - succeed
2831 //-------------------------------------------------------------------------------------------------
2832 MS_BOOL MsOS_SetSystemTime (MS_U32 u32SystemTime)
2833 {
2834     MS_U32 u32COUNT = u32SystemTime*TICK_PER_ONE_MS*CYGNUM_HAL_RTC_PERIOD;
2835 
2836     asm volatile (
2837         "move $8,%0;"
2838         "mtc0 $8,$9;"
2839         "nop; nop; nop;"
2840         :
2841         : "r"(u32COUNT)
2842         : "$8"
2843         );
2844 
2845     return TRUE;
2846 }
2847 */
2848 
2849 //
2850 // Queue
2851 //
_MsOS_QueueUsedSize(MsOS_Queue_Info * pQueueInfo)2852 static inline MS_U32 _MsOS_QueueUsedSize(MsOS_Queue_Info* pQueueInfo)
2853 {
2854     return (pQueueInfo->pu8Write>= pQueueInfo->pu8Read)?
2855                (pQueueInfo->pu8Write- pQueueInfo->pu8Read):
2856                (pQueueInfo->pu8Tail- pQueueInfo->pu8Head+ pQueueInfo->pu8Write- pQueueInfo->pu8Read);
2857 }
2858 
_MsOS_QueueFreeSize(MsOS_Queue_Info * pQueueInfo)2859 static inline MS_U32 _MsOS_QueueFreeSize(MsOS_Queue_Info* pQueueInfo)
2860 {
2861     return pQueueInfo->pu8Tail- pQueueInfo->pu8Head- _MsOS_QueueUsedSize(pQueueInfo);
2862 }
2863 
_MsOS_QueueMutexUnlock(pthread_mutex_t * pMutex)2864 static void _MsOS_QueueMutexUnlock(pthread_mutex_t* pMutex)
2865 {
2866     PTH_RET_CHK(pthread_mutex_unlock(pMutex));
2867 }
_MsOS_QueueMutexLock(pthread_mutex_t * pMutex,MS_U32 u32WaitMs)2868 static MS_BOOL _MsOS_QueueMutexLock(pthread_mutex_t* pMutex, MS_U32 u32WaitMs)
2869 {
2870     MS_BOOL bRet = TRUE;
2871 
2872     if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
2873     {
2874         PTH_RET_CHK(pthread_mutex_lock(pMutex));
2875         bRet = TRUE;
2876     }
2877     else if (u32WaitMs==0) //non-blocking
2878     {
2879         if (!PTH_RET_CHK(pthread_mutex_trylock(pMutex)))
2880         {
2881             bRet = TRUE;
2882         }
2883     }
2884     else //blocking wait with timeout
2885     {
2886 #if defined (TV_OS)
2887         PTH_RET_CHK(pthread_mutex_lock(pMutex));
2888         bRet = TRUE;
2889 #else
2890         struct timespec         StopTime;
2891         _TimeAbs(StopTime, u32WaitMs);
2892         bRet= (PTH_RET_CHK(pthread_mutex_timedlock(pMutex, &StopTime)))? FALSE: TRUE;
2893 #endif
2894     }
2895     return bRet;
2896 }
2897 //-------------------------------------------------------------------------------------------------
2898 /// Create a Queue
2899 /// @param  pStartAddr      \b IN: It is useless now, can pass NULL.
2900 /// @param  u32QueueSize    \b IN: queue size (byte unit) : now fixed as
2901 ///                                CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE * u32MessageSize
2902 /// @param  eMessageType    \b IN: E_MSG_FIXED_SIZE / E_MSG_VAR_SIZE
2903 /// @param  u32MessageSize  \b IN: message size (byte unit) for E_MSG_FIXED_SIZE
2904 ///                                max message size (byte unit) for E_MSG_VAR_SIZE
2905 /// @param  eAttribute      \b IN: E_MSOS_FIFO suspended in FIFO order
2906 /// @param  pQueueName      \b IN: queue name
2907 /// @return assigned message queue ID
2908 /// @return < 0 - fail
2909 //-------------------------------------------------------------------------------------------------
MsOS_CreateQueue(void * pStartAddr,MS_U32 u32QueueSize,MessageType eMessageType,MS_U32 u32MessageSize,MsOSAttribute eAttribute,char * pQueueName)2910 MS_S32 MsOS_CreateQueue (void         *pStartAddr,
2911                       MS_U32           u32QueueSize,
2912                       MessageType   eMessageType,
2913                       MS_U32           u32MessageSize,
2914                       MsOSAttribute eAttribute,
2915                       char         *pQueueName)
2916 {
2917     MS_S32 s32Id;
2918     MS_U32 u32AlignSize;
2919     pthread_mutexattr_t _MsOS_Mutex_Attr;
2920 #if !defined (ANDROID) || defined (__LP64__)
2921     pthread_condattr_t attr;
2922 #endif
2923 
2924     PTH_RET_CHK(pthread_mutexattr_init(&_MsOS_Mutex_Attr));
2925     //PTH_RET_CHK(pthread_mutexattr_setprotocol(&_MsOS_Mutex_Attr, PTHREAD_PRIO_INHERIT));
2926 #ifdef MS_DEBUG
2927     PTH_RET_CHK(pthread_mutexattr_settype(&_MsOS_Mutex_Attr, PTHREAD_MUTEX_ERRORCHECK));
2928 #endif
2929 
2930     if (E_MSG_VAR_SIZE== eMessageType)
2931     {
2932         MSOS_ERROR("E_MSG_VAR_SIZE has not been supported yet\n");
2933         return -1;
2934     }
2935 
2936     PTH_RET_CHK(pthread_mutex_lock( &_MsOS_Queue_Mutex));
2937     for( s32Id=0; s32Id<MSOS_QUEUE_MAX; s32Id++)
2938     {
2939         if(_MsOS_Queue_Info[s32Id].bUsed == FALSE)
2940         {
2941             break;
2942         }
2943     }
2944     if(s32Id < MSOS_QUEUE_MAX)
2945     {
2946         _MsOS_Queue_Info[s32Id].u32AlignedMsgSize = u32AlignSize= ALIGN_4(u32MessageSize);
2947         u32QueueSize= u32AlignSize* (CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE+1);
2948         _MsOS_Queue_Info[s32Id].pu8Head= (MS_U8*)malloc(u32AlignSize* (CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE+1));
2949         if(!_MsOS_Queue_Info[s32Id].pu8Head)
2950         {
2951             s32Id = MSOS_QUEUE_MAX; // Invalid queue index
2952         }
2953         else
2954         {
2955             _MsOS_Queue_Info[s32Id].pu8Read= _MsOS_Queue_Info[s32Id].pu8Write= _MsOS_Queue_Info[s32Id].pu8Head;
2956             _MsOS_Queue_Info[s32Id].pu8Tail= _MsOS_Queue_Info[s32Id].pu8Head+ u32QueueSize;
2957             _MsOS_Queue_Info[s32Id].bUsed = TRUE;
2958             _MsOS_Queue_Info[s32Id].eMsgType = eMessageType;
2959         }
2960     }
2961     PTH_RET_CHK(pthread_mutex_unlock( &_MsOS_Queue_Mutex));
2962 
2963     if(s32Id >= MSOS_QUEUE_MAX)
2964     {
2965         return -1;
2966     }
2967 
2968 #if !defined (ANDROID) || defined (__LP64__)
2969     pthread_condattr_init(&attr);
2970     PTH_RET_CHK(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
2971     PTH_RET_CHK(pthread_cond_init(&_MsOS_Queue_Info[s32Id].SendSem, &attr));
2972     PTH_RET_CHK(pthread_cond_init(&_MsOS_Queue_Info[s32Id].RecvSem, &attr));
2973 #else
2974     PTH_RET_CHK(pthread_cond_init(&_MsOS_Queue_Info[s32Id].SendSem, NULL));
2975     PTH_RET_CHK(pthread_cond_init(&_MsOS_Queue_Info[s32Id].RecvSem, NULL));
2976 #endif
2977     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Info[s32Id].SendMutex, &_MsOS_Mutex_Attr));
2978     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Info[s32Id].RecvMutex, &_MsOS_Mutex_Attr));
2979     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Info[s32Id].WaitQueueSpaceMutex, &_MsOS_Mutex_Attr));
2980     PTH_RET_CHK(pthread_mutex_init(&_MsOS_Queue_Info[s32Id].WaitQueueDataMutex, &_MsOS_Mutex_Attr));
2981 
2982     s32Id |= MSOS_ID_PREFIX;
2983     return s32Id;
2984 }
2985 
2986 //-------------------------------------------------------------------------------------------------
2987 /// Delete the Queue
2988 /// @param  s32QueueId  \b IN: Queue ID
2989 /// @return TRUE : succeed
2990 /// @return FALSE :  fail
2991 /// @note   It is important that there are not any threads blocked on the queue
2992 ///             when this function is called or the behavior is undefined.
2993 //-------------------------------------------------------------------------------------------------
MsOS_DeleteQueue(MS_S32 s32QueueId)2994 MS_BOOL MsOS_DeleteQueue (MS_S32 s32QueueId)
2995 {
2996     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
2997     {
2998         return FALSE;
2999     }
3000     else
3001     {
3002         s32QueueId &= MSOS_ID_MASK;
3003     }
3004 
3005     #if 1
3006     if(_MsOS_Queue_Info[s32QueueId].bUsed == FALSE)
3007     {
3008         MSOS_ERROR("QUEUE WITH QUEUEID: %td NOT EXIST\n", (ptrdiff_t)s32QueueId);
3009         return FALSE;
3010     }
3011     #endif
3012 
3013 
3014     PTH_RET_CHK(pthread_mutex_lock( &_MsOS_Queue_Mutex));
3015     if(_MsOS_Queue_Info[s32QueueId].pu8Head)
3016     {
3017         free(_MsOS_Queue_Info[s32QueueId].pu8Head);
3018     }
3019     _MsOS_Queue_Info[s32QueueId].pu8Head= NULL;
3020     _MsOS_Queue_Info[s32QueueId].bUsed = FALSE;
3021     PTH_RET_CHK(pthread_mutex_unlock( &_MsOS_Queue_Mutex));
3022 
3023     PTH_RET_CHK(pthread_cond_destroy(&_MsOS_Queue_Info[s32QueueId].SendSem));
3024     PTH_RET_CHK(pthread_cond_destroy(&_MsOS_Queue_Info[s32QueueId].RecvSem));
3025     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].SendMutex));
3026     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].RecvMutex));
3027     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].WaitQueueSpaceMutex));
3028     PTH_RET_CHK(pthread_mutex_destroy(&_MsOS_Queue_Info[s32QueueId].WaitQueueDataMutex));
3029     return TRUE;
3030 }
3031 
3032 //-------------------------------------------------------------------------------------------------
3033 /// Send a message to the end of the specified queue
3034 /// @param  s32QueueId  \b IN: Queue ID
3035 /// @param  pu8Message  \b IN: ptr to msg to send. NULL ptr is not allowed
3036 /// @param  u32Size     \b IN: msg size (byte)
3037 /// @param  u32WaitMs   \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the queue is full
3038 /// @return TRUE : succeed
3039 /// @return FALSE :  fail
3040 //-------------------------------------------------------------------------------------------------
MsOS_SendToQueue(MS_S32 s32QueueId,MS_U8 * pu8Message,MS_U32 u32Size,MS_U32 u32WaitMs)3041 MS_BOOL MsOS_SendToQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32Size, MS_U32 u32WaitMs)
3042 {
3043     MsOS_Queue_Info* pQueueInfo= NULL;
3044 
3045     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
3046     {
3047         return FALSE;
3048     }
3049     else
3050     {
3051         s32QueueId &= MSOS_ID_MASK;
3052     }
3053 
3054     //coz cyg_mbox_get will return NULL for error
3055     if ( pu8Message==NULL)
3056     {
3057         return FALSE;
3058     }
3059 
3060     _MsOS_QueueMutexLock(&_MsOS_Queue_Info[s32QueueId].SendMutex, u32WaitMs);
3061 
3062     pQueueInfo= &_MsOS_Queue_Info[s32QueueId];
3063     if(u32Size > pQueueInfo->u32AlignedMsgSize)
3064     {
3065         _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].SendMutex);
3066         return FALSE;
3067     }
3068 
3069     if (u32Size>= _MsOS_QueueFreeSize(pQueueInfo))
3070     {
3071         _MsOS_QueueMutexLock(&_MsOS_Queue_Info[s32QueueId].WaitQueueSpaceMutex, u32WaitMs);
3072         if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
3073         {
3074             PTH_RET_CHK(pthread_cond_wait(&pQueueInfo->RecvSem, &pQueueInfo->WaitQueueSpaceMutex));
3075         }
3076         else
3077         {
3078             struct timespec     StopTime;
3079 //            if (0== u32WaitMs)
3080 //            {
3081 //                u32WaitMs=          MSOS_TIME_MIN_WAIT_TV;
3082 //            }
3083             _TimeAbsM(StopTime, u32WaitMs);
3084 #if !defined (ANDROID) || defined (__LP64__)
3085             if (PTH_RET_CHK(pthread_cond_timedwait(&pQueueInfo->RecvSem, &pQueueInfo->WaitQueueSpaceMutex, &StopTime)))
3086 #else
3087             if (PTH_RET_CHK(pthread_cond_timedwait_monotonic(&pQueueInfo->RecvSem, &pQueueInfo->WaitQueueSpaceMutex, &StopTime)))
3088 #endif
3089             {
3090                 _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].WaitQueueSpaceMutex);
3091                 _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].SendMutex);
3092                 return FALSE;
3093             }
3094         }
3095         _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].WaitQueueSpaceMutex);
3096     }
3097 
3098     memcpy(pQueueInfo->pu8Write, pu8Message, u32Size);
3099     pQueueInfo->pu8Write+= pQueueInfo->u32AlignedMsgSize;
3100     if (pQueueInfo->pu8Write>= pQueueInfo->pu8Tail)
3101     {
3102         pQueueInfo->pu8Write= pQueueInfo->pu8Head;
3103     }
3104     PTH_RET_CHK(pthread_cond_signal(&pQueueInfo->SendSem));
3105     _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].SendMutex);
3106     return TRUE;
3107 }
3108 
3109 //-------------------------------------------------------------------------------------------------
3110 /// Receive a message from the specified queue
3111 /// @param  s32QueueId      \b IN: Queue ID
3112 /// @param  pu8Message      \b OUT: msg destination
3113 /// @param  u32IntendedSize \b IN: intended msg size (byte unit) to receive:
3114 /// @param  pu32ActualSize  \b OUT: actual msg size (byte unit) received
3115 /// @param  u32WaitMs       \b IN: 0 ~ MSOS_WAIT_FOREVER: suspend time (ms) if the queue is empty
3116 /// @return TRUE : succeed
3117 /// @return FALSE :  fail
3118 //-------------------------------------------------------------------------------------------------
MsOS_RecvFromQueue(MS_S32 s32QueueId,MS_U8 * pu8Message,MS_U32 u32IntendedSize,MS_U32 * pu32ActualSize,MS_U32 u32WaitMs)3119 MS_BOOL MsOS_RecvFromQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32IntendedSize, MS_U32 *pu32ActualSize, MS_U32 u32WaitMs)
3120 {
3121     MsOS_Queue_Info* pQueueInfo= NULL;
3122 
3123     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
3124     {
3125         return FALSE;
3126     }
3127     else
3128     {
3129         s32QueueId &= MSOS_ID_MASK;
3130     }
3131 
3132     _MsOS_QueueMutexLock(&_MsOS_Queue_Info[s32QueueId].RecvMutex, u32WaitMs);
3133 
3134     pQueueInfo= &_MsOS_Queue_Info[s32QueueId];
3135 
3136     MS_ASSERT(ALIGN_4(u32IntendedSize)== pQueueInfo->u32AlignedMsgSize);
3137 
3138     if (0== _MsOS_QueueUsedSize(pQueueInfo))
3139     {
3140         _MsOS_QueueMutexLock(&_MsOS_Queue_Info[s32QueueId].WaitQueueDataMutex, u32WaitMs);
3141         if (u32WaitMs==MSOS_WAIT_FOREVER) //blocking wait
3142         {
3143             PTH_RET_CHK(pthread_cond_wait(&pQueueInfo->SendSem, &pQueueInfo->WaitQueueDataMutex));
3144         }
3145         else
3146         {
3147             struct timespec     StopTime;
3148 //            if (0== u32WaitMs)
3149 //            {
3150 //                u32WaitMs=          MSOS_TIME_MIN_WAIT_TV;
3151 //            }
3152             _TimeAbsM(StopTime, u32WaitMs);
3153 
3154 #if !defined (ANDROID) || defined (__LP64__)
3155             if (PTH_RET_CHK(pthread_cond_timedwait(&pQueueInfo->SendSem, &pQueueInfo->WaitQueueDataMutex, &StopTime)))
3156 #else
3157             if (PTH_RET_CHK(pthread_cond_timedwait_monotonic(&pQueueInfo->SendSem, &pQueueInfo->WaitQueueDataMutex, &StopTime)))
3158 #endif
3159             {
3160                 _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].WaitQueueDataMutex);
3161                 _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].RecvMutex);
3162                 return FALSE;
3163             }
3164         }
3165         _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].WaitQueueDataMutex);
3166     }
3167 
3168     memcpy(pu8Message, pQueueInfo->pu8Read, u32IntendedSize);
3169     pQueueInfo->pu8Read+= pQueueInfo->u32AlignedMsgSize;
3170     if (pQueueInfo->pu8Read>= pQueueInfo->pu8Tail)
3171     {
3172         pQueueInfo->pu8Read= pQueueInfo->pu8Head;
3173     }
3174     PTH_RET_CHK(pthread_cond_signal(&pQueueInfo->RecvSem));
3175     *pu32ActualSize = u32IntendedSize;
3176     _MsOS_QueueMutexUnlock(&_MsOS_Queue_Info[s32QueueId].RecvMutex);
3177     return TRUE;
3178 }
3179 
3180 //-------------------------------------------------------------------------------------------------
3181 /// Receive a message from the specified queue
3182 /// @param  s32QueueId      \b IN: Queue ID
3183 /// @param  pu8Message      \b OUT: msg destination
3184 /// @param  u32IntendedSize \b IN: intended msg size (byte unit) to receive:
3185 /// @param  pu32ActualSize  \b OUT: actual msg size (byte unit) received
3186 /// @return TRUE : succeed
3187 /// @return FALSE :  fail
3188 //-------------------------------------------------------------------------------------------------
MsOS_PeekFromQueue(MS_S32 s32QueueId,MS_U8 * pu8Message,MS_U32 u32IntendedSize,MS_U32 * pu32ActualSize)3189 MS_BOOL MsOS_PeekFromQueue (MS_S32 s32QueueId, MS_U8 *pu8Message, MS_U32 u32IntendedSize, MS_U32 *pu32ActualSize)
3190 {
3191     MsOS_Queue_Info* pQueueInfo= NULL;
3192 
3193     if ( (s32QueueId & MSOS_ID_PREFIX_MASK) != MSOS_ID_PREFIX )
3194     {
3195         return FALSE;
3196     }
3197     else
3198     {
3199         s32QueueId &= MSOS_ID_MASK;
3200     }
3201 
3202     pQueueInfo= &_MsOS_Queue_Info[s32QueueId];
3203 
3204     MS_ASSERT(ALIGN_4(u32IntendedSize)== pQueueInfo->u32AlignedMsgSize);
3205 
3206     if (0== _MsOS_QueueUsedSize(pQueueInfo))
3207     {
3208         return FALSE;
3209     }
3210     memcpy(pu8Message, pQueueInfo->pu8Read, u32IntendedSize);
3211     *pu32ActualSize = u32IntendedSize;
3212     return TRUE;
3213 }
3214 
3215 
3216 
3217 //
3218 // Interrupt management
3219 //
3220 //-------------------------------------------------------------------------------------------------
3221 /// Attach the interrupt callback function to interrupt #
3222 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3223 /// @param  pIntCb  \b IN: Interrupt callback function
3224 /// @return TRUE : succeed
3225 /// @return FALSE :  fail
3226 //-------------------------------------------------------------------------------------------------
MsOS_AttachInterrupt(InterruptNum eIntNum,InterruptCb pIntCb)3227 MS_BOOL MsOS_AttachInterrupt (InterruptNum eIntNum, InterruptCb pIntCb)
3228 {
3229     PTH_RET_CHK(pthread_mutex_lock(&_ISR_Mutex));
3230 
3231     CHIP_AttachISR(eIntNum, pIntCb);
3232 #if 0 // @fixme: move to oberon or euclid
3233     CHIP_AttachISR( (MS_U16)(eIntNum+8), (MS_U16)(eIntNum), pIntCb) ;
3234     _ISR_Info[eIntNum].pIntCb = pIntCb;
3235     _ISR_Info[eIntNum].bUsed = TRUE;
3236 #endif
3237 
3238     PTH_RET_CHK(pthread_mutex_unlock(&_ISR_Mutex));
3239 
3240     return TRUE;
3241 }
3242 
3243 //-------------------------------------------------------------------------------------------------
3244 /// Detach the interrupt callback function from interrupt #
3245 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3246 /// @return TRUE : succeed
3247 /// @return FALSE :  fail
3248 //-------------------------------------------------------------------------------------------------
MsOS_DetachInterrupt(InterruptNum eIntNum)3249 MS_BOOL MsOS_DetachInterrupt (InterruptNum eIntNum)
3250 {
3251     PTH_RET_CHK(pthread_mutex_lock(&_ISR_Mutex));
3252 
3253     CHIP_DetachISR(eIntNum);
3254 
3255     PTH_RET_CHK(pthread_mutex_unlock(&_ISR_Mutex));
3256 
3257     return TRUE;
3258 }
3259 
3260 //-------------------------------------------------------------------------------------------------
3261 /// Debug the interrupt #
3262 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3263 /// @param IrqDebugOpt \n IN: Debug option
3264 /// @return TRUE : succeed
3265 /// @return FALSE :  fail
3266 //-------------------------------------------------------------------------------------------------
MsOS_DebugInterrupt(InterruptNum eIntNum,IrqDebugOpt eIrqDebugOpt)3267 MS_BOOL MsOS_DebugInterrupt (InterruptNum eIntNum, IrqDebugOpt eIrqDebugOpt)
3268 {
3269     return CHIP_DebugIRQ(eIntNum, eIrqDebugOpt);
3270 }
3271 
3272 //-------------------------------------------------------------------------------------------------
3273 /// Enable (unmask) the interrupt #
3274 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3275 /// @return TRUE : succeed
3276 /// @return FALSE :  fail
3277 //-------------------------------------------------------------------------------------------------
MsOS_EnableInterrupt(InterruptNum eIntNum)3278 MS_BOOL MsOS_EnableInterrupt (InterruptNum eIntNum)
3279 {
3280     return CHIP_EnableIRQ(eIntNum);
3281 }
3282 
3283 //-------------------------------------------------------------------------------------------------
3284 /// Disable (mask) the interrupt #
3285 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3286 /// @return TRUE : succeed
3287 //-------------------------------------------------------------------------------------------------
MsOS_DisableInterrupt(InterruptNum eIntNum)3288 MS_BOOL MsOS_DisableInterrupt (InterruptNum eIntNum)
3289 {
3290     return CHIP_DisableIRQ(eIntNum);
3291 }
3292 
3293 //-------------------------------------------------------------------------------------------------
3294 /// Notify the interrupt complete #
3295 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3296 /// @return TRUE : succeed
3297 //-------------------------------------------------------------------------------------------------
MsOS_CompleteInterrupt(InterruptNum eIntNum)3298 MS_BOOL MsOS_CompleteInterrupt (InterruptNum eIntNum)
3299 {
3300     return CHIP_CompleteIRQ(eIntNum);
3301 }
3302 
3303 //-------------------------------------------------------------------------------------------------
3304 /// Disable all interrupts (including timer interrupt), the scheduler is disabled.
3305 /// @return Interrupt register value before all interrupts disable
3306 //-------------------------------------------------------------------------------------------------
MsOS_DisableAllInterrupts(void)3307 MS_U32 MsOS_DisableAllInterrupts(void)
3308 {
3309     return CHIP_DisableAllInterrupt() ;
3310 }
3311 
3312 //-------------------------------------------------------------------------------------------------
3313 /// Restore the interrupts from last MsOS_DisableAllInterrupts.
3314 /// @param  u32OldInterrupts \b IN: Interrupt register value from @ref MsOS_DisableAllInterrupts
3315 /// @return TRUE : succeed
3316 //-------------------------------------------------------------------------------------------------
MsOS_RestoreAllInterrupts(MS_U32 u32OldInterrupts)3317 MS_BOOL MsOS_RestoreAllInterrupts(MS_U32 u32OldInterrupts)
3318 {
3319     return TRUE;
3320 }
3321 //-------------------------------------------------------------------------------------------------
3322 /// Enable all CPU interrupts.
3323 /// @return TRUE : succeed
3324 //-------------------------------------------------------------------------------------------------
MsOS_EnableAllInterrupts(void)3325 MS_BOOL MsOS_EnableAllInterrupts(void)
3326 {
3327 
3328     return CHIP_EnableAllInterrupt() ;
3329 }
3330 
3331 //-------------------------------------------------------------------------------------------------
3332 /// In Interuupt Context or not
3333 /// @return TRUE : Yes
3334 /// @return FALSE : No
3335 //-------------------------------------------------------------------------------------------------
MsOS_In_Interrupt(void)3336 MS_BOOL MsOS_In_Interrupt (void)
3337 {
3338     return CHIP_InISRContext();
3339 }
3340 
3341 //-------------------------------------------------------------------------------------------------
3342 /// Write back if dirty & Invalidate the cache lines in the given range
3343 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
3344 /// @param  u32Size  \b IN: size (must be 16-B aligned)
3345 /// @return TRUE : succeed
3346 /// @return FALSE : fail due to invalide parameter
3347 //-------------------------------------------------------------------------------------------------
3348 #define DCACHE_LINE_SIZE 16
MsOS_Dcache_Flush(MS_VIRT ptrStart,MS_SIZE tSize)3349 MS_BOOL MsOS_Dcache_Flush( MS_VIRT ptrStart, MS_SIZE tSize )
3350 {
3351     return MsOS_MPool_Dcache_Flush(ptrStart, tSize);
3352 }
3353 
3354 //-------------------------------------------------------------------------------------------------
3355 /// Invalidate the cache lines in the given range
3356 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
3357 /// @param  u32Size  \b IN: size (must be 16-B aligned)
3358 /// @return TRUE : succeed
3359 /// @return FALSE : fail due to invalide parameter
3360 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Invalidate(MS_VIRT ptrStart,MS_SIZE tSize)3361 MS_BOOL MsOS_Dcache_Invalidate( MS_VIRT ptrStart , MS_SIZE tSize )
3362 {
3363     return FALSE;
3364 }
3365 
3366 //-------------------------------------------------------------------------------------------------
3367 /// Write back if dirty the cache lines in the given range
3368 /// @param  u32Start \b IN: start address (must be 16-B aligned and in cacheable area)
3369 /// @param  u32Size  \b IN: size (must be 16-B aligned)
3370 /// @return TRUE : succeed
3371 /// @return FALSE : fail due to invalide parameter
3372 //-------------------------------------------------------------------------------------------------
MsOS_Dcache_Writeback(MS_VIRT ptrStart,MS_SIZE tSize)3373 MS_BOOL MsOS_Dcache_Writeback( MS_VIRT ptrStart , MS_SIZE tSize )
3374 {
3375     return FALSE;
3376 }
3377 
MsOS_VA2PA(MS_VIRT addr)3378 MS_PHY MsOS_VA2PA(MS_VIRT addr)
3379 {
3380     return (MS_PHY)MsOS_MPool_VA2PA(addr);
3381 }
3382 
MsOS_PA2KSEG0(MS_PHY addr)3383 MS_VIRT MsOS_PA2KSEG0(MS_PHY addr)
3384 {
3385     return MsOS_MPool_PA2KSEG0(addr);
3386 }
3387 
MsOS_PA2KSEG1(MS_PHY addr)3388 MS_VIRT MsOS_PA2KSEG1(MS_PHY addr)
3389 {
3390     return MsOS_MPool_PA2KSEG1(addr);
3391 }
3392 
MsOS_PA2BA(MS_PHY PhyAddr)3393 MS_PHY MsOS_PA2BA(MS_PHY PhyAddr)
3394 {
3395     return HAL_MsOS_MPool_PA2BA(PhyAddr);
3396 }
3397 
MsOS_BA2PA(MS_PHY BusAddr)3398 MS_PHY MsOS_BA2PA(MS_PHY BusAddr)
3399 {
3400     return HAL_MsOS_MPool_BA2PA(BusAddr);
3401 }
3402 
3403 // Share memory operation
3404 // MS_BOOL MsOS_SHM_Init(MS_U32 u32ShmSize)
MsOS_SHM_Init(void)3405 MS_BOOL MsOS_SHM_Init(void)
3406 {
3407 #if !defined (TV_OS)
3408     key_t key = NULL;
3409 #endif
3410 
3411     MS_BOOL bInit = FALSE;
3412     MS_U32 u32ShmSize;
3413 
3414 #if defined (TV_OS)
3415     if(pMutexShmIdx < 0)
3416     {
3417         pMutexShmIdx = MsOS_CreateNamedMutex((MS_S8*)SHAREMEM_MUTEX_NAME);
3418         if(pMutexShmIdx < 0)
3419         {
3420             MSOS_ERROR("create namedmutex %td fail ", (ptrdiff_t)pMutexShmIdx);
3421             return FALSE;
3422         }
3423     }
3424     _MSOS_SHM_LOCK(pMutexShmIdx);
3425 #elif defined (MSOS_PROCESS_SAFT_MUTEX)
3426     if (SEM_FAILED == (pMutexShm = sem_open(SHM_MUTEX_NAME, O_CREAT | O_EXCL, 0666, 1)))
3427     {
3428         if (SEM_FAILED == (pMutexShm = sem_open(SHM_MUTEX_NAME, 0)))
3429         {
3430             return FALSE;
3431         }
3432     }
3433 #else
3434     _MSOS_SHM_LOCK(pMutexShm);
3435 #endif
3436 
3437     if (-1 != _shm_id)
3438     {
3439           goto SHM_INIT_AGAIN;
3440     }
3441 
3442 #if defined (TV_OS)
3443 #ifdef CONFIG_UTOPIA_SHM_EXPAND_SUPPORT
3444     u32ShmSize = SHM_SIZE;
3445 #else
3446     u32ShmSize = MsOS_GetSHMSize();
3447     if(u32ShmSize < SHM_SIZE)
3448     {
3449        MSOS_ERROR("[%s][%d] shm size too small\n", __FUNCTION__, __LINE__);
3450 	   _MSOS_SHM_UNLOCK(pMutexShmIdx);
3451 	   LINUX_ASSERT(0);
3452 	   return FALSE;
3453     }
3454 #endif
3455 #else
3456     u32ShmSize = SHM_SIZE;
3457 #endif
3458 
3459     u32ShmSize -= SHM_SIZE_RESEVED;
3460     u32ShmSize += sizeof(MsOS_SHM_Hdr);
3461     u32ShmSize += ((1<< 12)- 1);
3462     u32ShmSize = (u32ShmSize>> 12)<< 12; // make it 4KBytes alignment
3463 
3464 #if defined (TV_OS)
3465     _pu8ShareMem = (MS_U8 *)MsOS_Mapping_SharedMem(u32ShmSize,&bInit);
3466     MSOS_PRINT("~!~mappd sharemem  %s \n", _pu8ShareMem);
3467     if (_pu8ShareMem == NULL)
3468     {
3469         MSOS_ERROR("[%s][%d] fail\n", __FUNCTION__, __LINE__);
3470         _MSOS_SHM_UNLOCK(pMutexShmIdx);
3471         return FALSE;
3472     }
3473     _shm_id = (MS_VIRT)_pu8ShareMem;
3474 #else
3475     key = (key_t)7890;
3476     if (-1 == (_shm_id = shmget(key, u32ShmSize, IPC_CREAT| IPC_EXCL | 0777)))
3477     {
3478         if (-1 == (_shm_id = shmget(key, u32ShmSize, IPC_CREAT)))
3479         {
3480             MSOS_ERROR("[%s][%d] fail\n", __FUNCTION__, __LINE__);
3481             _MSOS_SHM_UNLOCK(pMutexShm);
3482             return FALSE;
3483         }
3484     }
3485     else
3486     {
3487         bInit = TRUE;
3488     }
3489     if (-1 == (int)(_pu8ShareMem = (MS_U8*)shmat(_shm_id, NULL, 0)))
3490     {
3491         MSOS_ERROR("[%s][%d] fail\n", __FUNCTION__, __LINE__);
3492         _MSOS_SHM_UNLOCK(pMutexShm);
3493         return FALSE;
3494     }
3495 #endif
3496 
3497     if (bInit)
3498     {
3499         memset(&_ShmHdr, 0, sizeof(_ShmHdr)); // dummy storage
3500         _ShmHdr.u32MaxClientNum = MAX_SHM_CLIENT_NUM;
3501         _ShmHdr.u32ClientNum = 0;
3502         _ShmHdr.u32ShmSize = u32ShmSize;
3503         _ShmHdr.u32Offset = (sizeof(MsOS_SHM_Hdr)+7)&~7;
3504         memcpy(_pu8ShareMem, &_ShmHdr, sizeof(_ShmHdr));
3505     }
3506 #if defined (TV_OS)
3507     _MSOS_SHM_UNLOCK(pMutexShmIdx);
3508 #else
3509     _MSOS_SHM_UNLOCK(pMutexShm);
3510 #endif
3511     return TRUE;
3512 
3513 SHM_INIT_AGAIN:
3514 #if defined (TV_OS)
3515     _MSOS_SHM_UNLOCK(pMutexShmIdx);
3516 #else
3517     _MSOS_SHM_UNLOCK(pMutexShm);
3518 #endif
3519     return FALSE;
3520 }
3521 
3522 #if defined(MSOS_TYPE_LINUX_KERNEL)
3523 EXPORT_SYMBOL(MsOS_SHM_Init);
3524 #endif
3525 
3526 // Share memory operation
MsOS_SHM_GetId(MS_U8 * pu8ClientName,MS_U32 u32BufSize,MS_U32 * pu32ShmId,MS_VIRT * pu32Addr,MS_U32 * pu32BufSize,MS_U32 u32Flag)3527 MS_BOOL MsOS_SHM_GetId(MS_U8* pu8ClientName, MS_U32 u32BufSize, MS_U32* pu32ShmId, MS_VIRT* pu32Addr, MS_U32* pu32BufSize, MS_U32 u32Flag)
3528 {
3529     MsOS_SHM_Context* pContext = NULL;
3530     MsOS_SHM_Context* pClient = NULL;
3531     MS_U32 i;
3532     MS_U32 u32CopyLen;
3533     MS_U8 pClientName[MAX_CLIENT_NAME_LENGTH];
3534 #ifdef CONFIG_UTOPIA_SHM_EXPAND_SUPPORT
3535     MS_U32 u32ExpandSize = SHM_EXPAND_SIZE;
3536     MS_U32 u32ShmMaxSize;
3537 #endif
3538 
3539     if (!_pu8ShareMem)
3540     {
3541         MSOS_ERROR("[%s][%d] MsOS_SHM_Init should be invoked first\n", __FUNCTION__, __LINE__);
3542         return FALSE;
3543     }
3544 
3545     if (NULL == pu8ClientName)
3546     {
3547         return FALSE;
3548     }
3549     if (0 == (u32CopyLen = MIN(strlen((const char*)pu8ClientName), (MAX_CLIENT_NAME_LENGTH-1))))
3550     {
3551         return FALSE;
3552     }
3553     strncpy((char*)pClientName, (const char*)pu8ClientName, u32CopyLen);
3554     pClientName[u32CopyLen] = '\0';
3555 
3556 #if defined (TV_OS)
3557     _MSOS_SHM_LOCK(pMutexShmIdx);
3558 #else
3559     _MSOS_SHM_LOCK(pMutexShm);
3560 #endif
3561     memcpy(&_ShmHdr, _pu8ShareMem, sizeof(_ShmHdr));
3562     pContext = (MsOS_SHM_Context*)_ShmHdr.context;
3563     for (i= 0; i< MAX_SHM_CLIENT_NUM; i++, pContext++)
3564     {
3565         if (0 == pContext->u32ClientId)
3566         {
3567             continue;
3568         }
3569         if (0== strcmp((const char*)pContext->u8ClientName, (const char*)pClientName))
3570         {
3571             pClient = pContext;
3572             if (u32BufSize != pClient->u32Size)
3573             {
3574                 MSOS_ERROR("\n[%s][%d][ClientName %s] Error: inconsistent buffer size with other process\n", __FUNCTION__, __LINE__, (const char*)pClientName);
3575                 LINUX_ASSERT(0); //assert for incompatible utopia lib with shm implement
3576                 return FALSE;
3577             }
3578             break;
3579         }
3580     }
3581     if ((NULL == pClient) && (MSOS_SHM_CREATE == u32Flag))
3582     {
3583         pContext = (MsOS_SHM_Context*)_ShmHdr.context;
3584         for (i= 0; i< MAX_SHM_CLIENT_NUM; i++, pContext++)
3585         {
3586             if (pContext->u32ClientId)
3587             {
3588                 continue;
3589             }
3590             if ((_ShmHdr.u32Offset + u32BufSize)> _ShmHdr.u32ShmSize)
3591             {
3592                 MSOS_ERROR("[%s][%d] MsOS_SHM_GetId: shared memory buffer overflow\n", __FUNCTION__, __LINE__);
3593 #if defined (TV_OS)
3594 #ifdef CONFIG_UTOPIA_SHM_EXPAND_SUPPORT
3595                 u32ShmMaxSize = MsOS_GetSHMSize();
3596                 if ((_ShmHdr.u32Offset + u32BufSize) > u32ShmMaxSize)
3597                 {
3598                     MSOS_ERROR("[%s][%d] exceed the avaiable shared memory size\n", __FUNCTION__, __LINE__);
3599                     _MSOS_SHM_UNLOCK(pMutexShmIdx);
3600                     return FALSE;
3601                 }
3602                 // expand shared mem, default add 256k
3603                 if ((_ShmHdr.u32ShmSize + u32ExpandSize) > u32ShmMaxSize)
3604                 {
3605                     u32ExpandSize = u32ShmMaxSize - (_ShmHdr.u32ShmSize);
3606                 }
3607                 if (FALSE == MsOS_SHM_Expand(_ShmHdr.u32ShmSize, u32ExpandSize))
3608                 {
3609                     MSOS_ERROR("[%s][%d] expand shared memory fail\n", __FUNCTION__, __LINE__);
3610                     _MSOS_SHM_UNLOCK(pMutexShmIdx);
3611                     return FALSE;
3612                 }
3613                 _ShmHdr.u32ShmSize += u32ExpandSize;
3614                 memcpy(_pu8ShareMem, &_ShmHdr, sizeof(_ShmHdr));
3615 #else
3616                 _MSOS_SHM_UNLOCK(pMutexShmIdx);
3617                 return FALSE;
3618 #endif
3619 #else
3620                 _MSOS_SHM_UNLOCK(pMutexShm);
3621                 return FALSE;
3622 #endif
3623             }
3624             _ShmHdr.u32ClientNum++;
3625             pClient = pContext;
3626             strncpy((char*)pClient->u8ClientName, (const char*)pClientName,MIN(strlen((const char*)pClientName),(MAX_CLIENT_NAME_LENGTH-1)));
3627             pClient->u32Size = u32BufSize;
3628             pClient->u32ClientId = i+ 1;
3629             pClient->u8RefCnt = 0;
3630             pClient->u32Offset = _ShmHdr.u32Offset;
3631             _ShmHdr.u32Offset += (u32BufSize+7)&~7;
3632             memcpy(_pu8ShareMem, &_ShmHdr, sizeof(_ShmHdr));
3633             break;
3634         }
3635     }
3636     if (NULL == pClient)
3637     {
3638         // printf("[%s][%d] MsOS_SHM_Init: Unable to get available share memeory\n", __FUNCTION__, __LINE__);
3639 #if defined (TV_OS)
3640         _MSOS_SHM_UNLOCK(pMutexShmIdx);
3641 #else
3642         _MSOS_SHM_UNLOCK(pMutexShm);
3643 #endif
3644         return FALSE;
3645     }
3646     *pu32ShmId = pClient->u32ClientId;
3647     *pu32BufSize = pClient->u32Size;
3648     *pu32Addr = (MS_VIRT)_pu8ShareMem + pClient->u32Offset;
3649 #if defined (TV_OS)
3650     _MSOS_SHM_UNLOCK(pMutexShmIdx);
3651 #else
3652     _MSOS_SHM_UNLOCK(pMutexShm);
3653 #endif
3654 
3655     return TRUE;
3656 }
3657 
_MsOS_LinuxTaskWrapper(void * argv)3658 void* _MsOS_LinuxTaskWrapper (void *argv)
3659 {
3660 
3661     char thd_name[MAX_NAME];
3662     MsOS_Task_Info * pMsOS_Task_Info= (MsOS_Task_Info *) argv;
3663 
3664     TaskEntry  pTaskEntry;
3665 
3666     MS_VIRT  TaskEntryData= pMsOS_Task_Info -> u32TaskEntryData;
3667     pTaskEntry = pMsOS_Task_Info -> pTaskEntry;
3668 
3669 
3670     //set thread name
3671     if(strlen(pMsOS_Task_Info->pTaskName) > 15 )
3672     {
3673         puts("the length of the thread name exceeds 15, it will be truncated to 15 chars");
3674     }
3675 
3676     //puts("set thread name");
3677     memset(thd_name,'\0',sizeof(thd_name));
3678     snprintf(thd_name, (MAX_NAME - 1),"%s", pMsOS_Task_Info->pTaskName);
3679     prctl(PR_SET_NAME, (unsigned long)thd_name, NULL, NULL, NULL);
3680 
3681     //get thread name
3682     memset(thd_name,'\0',sizeof(thd_name));
3683     prctl(PR_GET_NAME, (unsigned long)thd_name, NULL, NULL, NULL);
3684     //printf("%s\n",thd_name);
3685 
3686     //execute function
3687     //printf("%s.%d\n",__FUNCTION__,__LINE__);
3688     //puts("execute function ");
3689     pTaskEntry( TaskEntryData , (void *)pMsOS_Task_Info);
3690     //printf("%s.%d\n",__FUNCTION__,__LINE__);
3691 
3692     //release resource
3693     //puts("release resource");
3694     PTH_RET_CHK(pthread_mutex_lock(&_MsOS_Task_Mutex));
3695     //pStackBase is not used now
3696     //if (pMsOS_Task_Info->pStackBase)
3697     //{
3698           //free(pMsOS_Task_Info->pStackBase);
3699           //pMsOS_Task_Info->pStackBase= NULL;
3700     //}
3701     pMsOS_Task_Info->bUsed = FALSE;
3702     PTH_RET_CHK(pthread_mutex_unlock(&_MsOS_Task_Mutex));
3703 
3704     return NULL;
3705 }
3706 
3707 
3708 
3709 
MsOS_SHM_FreeId(MS_U8 * pu8ClientName,MS_U32 u32ShmId)3710 MS_BOOL MsOS_SHM_FreeId(MS_U8* pu8ClientName, MS_U32 u32ShmId)
3711 {
3712     return TRUE;
3713 }
3714 
3715 //-------------------------------------------------------------------------------------------------
3716 /// Disable the CPU interrupt
3717 /// @return Interrupt register value before all interrupts disable
3718 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DisableInterrupt(void)3719 MS_U32 MsOS_CPU_DisableInterrupt (void)
3720 {
3721     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3722     return FALSE;
3723 }
3724 
3725 //-------------------------------------------------------------------------------------------------
3726 /// Enable the CPU interrupt
3727 /// @return TRUE : succeed
3728 //-------------------------------------------------------------------------------------------------
MsOS_CPU_EnableInterrupt(void)3729 MS_BOOL MsOS_CPU_EnableInterrupt (void)
3730 {
3731     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3732     return FALSE;
3733 }
3734 
3735 //-------------------------------------------------------------------------------------------------
3736 /// Restore the CPU interrupt from last MsOS_CPU_DisableInterrupts.
3737 /// @param  u32OldInterrupts \b IN: Interrupt register value from @ref MsOS_CPU_DisableInterrupts
3738 /// @return TRUE : succeed
3739 //-------------------------------------------------------------------------------------------------
MsOS_CPU_RestoreInterrupt(MS_U32 u32OldInterrupts)3740 MS_BOOL MsOS_CPU_RestoreInterrupt (MS_U32 u32OldInterrupts)
3741 {
3742     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3743     return FALSE;
3744 }
3745 
3746 //-------------------------------------------------------------------------------------------------
3747 /// Mask all the CPU interrupt
3748 /// @return TRUE : succeed
3749 //-------------------------------------------------------------------------------------------------
MsOS_CPU_MaskAllInterrupt(void)3750 MS_BOOL MsOS_CPU_MaskAllInterrupt (void)
3751 {
3752     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3753     return FALSE;
3754 }
3755 
3756 //-------------------------------------------------------------------------------------------------
3757 /// Mask the CPU interrupt
3758 /// @param  intr_num \b IN: Interrupt number in enumerator MHAL_INTERRUPT_TYPE
3759 /// @return TRUE : succeed
3760 //-------------------------------------------------------------------------------------------------
MsOS_CPU_MaskInterrupt(MHAL_INTERRUPT_TYPE intr_num)3761 MS_BOOL MsOS_CPU_MaskInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3762 {
3763     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3764     return FALSE;
3765 }
3766 
3767 //-------------------------------------------------------------------------------------------------
3768 /// UnMask the CPU interrupt
3769 /// @param  intr_num \b IN: Interrupt number in enumerator MHAL_INTERRUPT_TYPE
3770 /// @return TRUE : succeed
3771 //-------------------------------------------------------------------------------------------------
MsOS_CPU_UnMaskInterrupt(MHAL_INTERRUPT_TYPE intr_num)3772 MS_BOOL MsOS_CPU_UnMaskInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3773 {
3774     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3775     return FALSE;
3776 }
3777 
3778 //-------------------------------------------------------------------------------------------------
3779 /// Lock the CPU interrupt
3780 /// @return TRUE : succeed
3781 //-------------------------------------------------------------------------------------------------
MsOS_CPU_LockInterrupt(void)3782 MS_BOOL MsOS_CPU_LockInterrupt (void)
3783 {
3784     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3785     return FALSE;
3786 }
3787 
3788 //-------------------------------------------------------------------------------------------------
3789 /// UnLock the CPU interrupt
3790 /// @return TRUE : succeed
3791 //-------------------------------------------------------------------------------------------------
MsOS_CPU_UnLockInterrupt(void)3792 MS_BOOL MsOS_CPU_UnLockInterrupt (void)
3793 {
3794     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3795     return FALSE;
3796 }
3797 
3798 //-------------------------------------------------------------------------------------------------
3799 /// Attach the CPU interrupt callback function to interrupt #
3800 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3801 /// @param  pIntCb  \b IN: Interrupt callback function
3802 /// @param  dat  \b IN: Data
3803 /// @return TRUE : succeed
3804 //-------------------------------------------------------------------------------------------------
MsOS_CPU_AttachInterrupt(MHAL_INTERRUPT_TYPE intr_num,mhal_isr_t isr,MS_U32 dat)3805 MS_BOOL MsOS_CPU_AttachInterrupt (MHAL_INTERRUPT_TYPE intr_num, mhal_isr_t isr, MS_U32 dat)
3806 {
3807     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3808     return FALSE;
3809 }
3810 
3811 //-------------------------------------------------------------------------------------------------
3812 /// Detach the CPU interrupt callback function to interrupt #
3813 /// @param  eIntNum \b IN: Interrupt number in enumerator InterruptNum
3814 /// @param  pIntCb  \b IN: Interrupt callback function
3815 /// @param  dat  \b IN: Data
3816 /// @return TRUE : succeed
3817 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DetachInterrupt(MHAL_INTERRUPT_TYPE intr_num)3818 MS_BOOL MsOS_CPU_DetachInterrupt (MHAL_INTERRUPT_TYPE intr_num)
3819 {
3820     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3821     return FALSE;
3822 }
3823 
3824 //-------------------------------------------------------------------------------------------------
3825 /// Attach the CPU exception callback function to interrupt #
3826 /// @param  eIntNum \b IN: Exception number in enumerator InterruptNum
3827 /// @param  pIntCb  \b IN: Exception callback function
3828 /// @param  dat  \b IN: Data
3829 /// @return TRUE : succeed
3830 //-------------------------------------------------------------------------------------------------
MsOS_CPU_AttachException(MHAL_EXCEPTION_TYPE expt_num,mhal_isr_t isr,MS_U32 dat)3831 MS_BOOL MsOS_CPU_AttachException (MHAL_EXCEPTION_TYPE expt_num, mhal_isr_t isr, MS_U32 dat)
3832 {
3833     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3834     return FALSE;
3835 }
3836 
3837 //-------------------------------------------------------------------------------------------------
3838 /// Detach the CPU exception callback function to interrupt #
3839 /// @param  eIntNum \b IN: Exception number in enumerator InterruptNum
3840 /// @param  pIntCb  \b IN: Exception callback function
3841 /// @param  dat  \b IN: Data
3842 /// @return TRUE : succeed
3843 //-------------------------------------------------------------------------------------------------
MsOS_CPU_DetachExceptiont(MHAL_EXCEPTION_TYPE expt_num)3844 MS_BOOL MsOS_CPU_DetachExceptiont (MHAL_EXCEPTION_TYPE expt_num)
3845 {
3846     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3847     return FALSE;
3848 }
3849 //-------------------------------------------------------------------------------------------------
3850 /// Set EBASE
3851 /// @param  u32Addr \b IN: MIPS Code Start Address
3852 /// @return TRUE : succeed
3853 //-------------------------------------------------------------------------------------------------
MsOS_CPU_SetEBASE(MS_U32 u32Addr)3854 MS_BOOL MsOS_CPU_SetEBASE (MS_U32 u32Addr)
3855 {
3856     MSOS_WARN("[%s][%d] %s is not supported\n", __FUNCTION__, __LINE__, __FUNCTION__);
3857     return FALSE;
3858 }
3859 //-------------------------------------------------------------------------------------------------
3860 /// Sync data in EC-Brigde
3861 /// @return TRUE : succeed
3862 /// @return FALSE : fail
3863 //-------------------------------------------------------------------------------------------------
MsOS_Sync(void)3864 void MsOS_Sync(void)
3865 {//not support in current stage.
3866 }
3867 
MsOS_FlushMemory(void)3868 void MsOS_FlushMemory(void)
3869 {
3870     if(-1==ioctl(_s32FdSYS, IOCTL_SYS_FLUSH_MEMORY, NULL))
3871     {
3872         MSOS_ERROR("%s.%d ioctl fail\n",__FUNCTION__,__LINE__);
3873     }
3874 }
3875 
MsOS_ReadMemory(void)3876 void MsOS_ReadMemory(void)
3877 {
3878     if(-1==ioctl(_s32FdSYS, IOCTL_SYS_READ_MEMORY, NULL))
3879     {
3880         MSOS_ERROR("%s.%d ioctl fail\n",__FUNCTION__,__LINE__);
3881     }
3882 }
3883 
MsOS_GetKattribute(char * pAttr)3884 MS_U32 MsOS_GetKattribute(char *pAttr)
3885 {
3886     FILE *pFile;
3887     char path[256];
3888     char str[256];
3889     MS_U32 u32val, u32Len;
3890 
3891     sprintf(path, "/proc/kattr/%s/value", pAttr);
3892 
3893     if((pFile=fopen(path, "w+"))==NULL)
3894     {
3895         MSOS_ERROR("Can not open file at: %s", path);
3896         return -1;
3897     }
3898 
3899     fscanf(pFile, "%s", str);
3900     u32Len = strlen(str);
3901     u32val = (int)strtol(str, (char **)str+u32Len, 16);
3902 
3903     fclose(pFile);
3904 
3905     return u32val;
3906 }
3907 
3908 #endif
3909