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