90#ifdef LOSCFG_BASE_IPC_SEM
92#if (LOSCFG_BASE_IPC_SEM_LIMIT <= 0)
93#error "sem maxnum cannot be zero"
112 return LOS_ERRNO_SEM_NO_MEMORY;
115 for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) {
117 semNode->
semID = SET_SEM_ID(0, index);
118 semNode->
semStat = OS_SEM_UNUSED;
123 return LOS_ERRNO_SEM_NO_MEMORY;
143 if (semHandle == NULL) {
144 return LOS_ERRNO_SEM_PTR_NULL;
147 if (count > maxCount) {
148 OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW);
151 SCHEDULER_LOCK(intSave);
154 SCHEDULER_UNLOCK(intSave);
156 OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY);
161 SCHEDULER_UNLOCK(intSave);
162 semCreated = GET_SEM_LIST(unusedSem);
164 semCreated->
semStat = OS_SEM_USED;
167 *semHandle = semCreated->
semID;
168 OsHookCall(LOS_HOOK_TYPE_SEM_CREATE, semCreated);
174 OS_RETURN_ERROR_P2(errLine, errNo);
179 return OsSemCreate(count, OS_SEM_COUNT_MAX, semHandle);
184 return OsSemCreate(count, OS_SEM_BINARY_COUNT_MAX, semHandle);
194 if (GET_SEM_INDEX(semHandle) >= (
UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) {
195 OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID);
198 semDeleted = GET_SEM(semHandle);
200 SCHEDULER_LOCK(intSave);
202 if ((semDeleted->
semStat == OS_SEM_UNUSED) || (semDeleted->
semID != semHandle)) {
203 SCHEDULER_UNLOCK(intSave);
204 OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID);
208 SCHEDULER_UNLOCK(intSave);
209 OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED);
213 semDeleted->
semStat = OS_SEM_UNUSED;
214 semDeleted->
semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->
semID) + 1, GET_SEM_INDEX(semDeleted->
semID));
216 OsHookCall(LOS_HOOK_TYPE_SEM_DELETE, semDeleted);
219 SCHEDULER_UNLOCK(intSave);
223 OS_RETURN_ERROR_P2(errLine, errNo);
229 LosSemCB *semPended = GET_SEM(semHandle);
233 if (GET_SEM_INDEX(semHandle) >= (
UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) {
234 OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID);
238 PRINT_ERR(
"!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n");
240 return LOS_ERRNO_SEM_PEND_INTERR;
244 if (runTask->
taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
246 return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK;
249 SCHEDULER_LOCK(intSave);
251 if ((semPended->
semStat == OS_SEM_UNUSED) || (semPended->
semID != semHandle)) {
252 retErr = LOS_ERRNO_SEM_INVALID;
261 OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout);
263 }
else if (!timeout) {
264 retErr = LOS_ERRNO_SEM_UNAVAILABLE;
269 PRINT_ERR(
"!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n");
271 retErr = LOS_ERRNO_SEM_PEND_IN_LOCK;
275 OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout);
277 retErr = runTask->
ops->
wait(runTask, &semPended->
semList, timeout);
278 if (retErr == LOS_ERRNO_TSK_TIMEOUT) {
279 retErr = LOS_ERRNO_SEM_TIMEOUT;
283 SCHEDULER_UNLOCK(intSave);
290 LosSemCB *semPosted = GET_SEM(semHandle);
291 if ((semPosted->
semID != semHandle) || (semPosted->
semStat == OS_SEM_UNUSED)) {
292 return LOS_ERRNO_SEM_INVALID;
298 if (semPosted->
semCount == OS_SEM_COUNT_MAX) {
299 return LOS_ERRNO_SEM_OVERFLOW;
302 resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->
semList)));
304 resumedTask->
ops->
wake(resumedTask);
305 if (needSched != NULL) {
311 OsHookCall(LOS_HOOK_TYPE_SEM_POST, semPosted, resumedTask);
319 BOOL needSched = FALSE;
321 if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) {
322 return LOS_ERRNO_SEM_INVALID;
324 SCHEDULER_LOCK(intSave);
326 SCHEDULER_UNLOCK(intSave);
VOID OsBackTrace(VOID)
Kernel backtrace function.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
对外接口 创建信号量
LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle)
对外接口 创建二值信号量,其计数值最大为1,可以当互斥锁用
LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
对外接口 释放指定的信号量
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
对外接口 申请指定的信号量,并设置超时时间
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
对外接口 删除指定的信号量,参数就是 semID
VOID LOS_Schedule(VOID)
Trigger active task scheduling.
VOID LOS_MpSchedule(UINT32 target)
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
STATIC INLINE BOOL OsPreemptableInSched(VOID)
LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
以不安全的方式释放指定的信号量,所谓不安全指的是不用自旋锁
LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle)
LITE_OS_SEC_BSS LosSemCB * g_allSem
信号池,一次分配 LOSCFG_BASE_IPC_SEM_LIMIT 个信号量
LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList
可用的信号量列表,干嘛不用freeList? 可以看出这里是另一个人写的代码
STATIC INLINE VOID OsSemDbgUpdateHook(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count)
STATIC INLINE UINT32 OsSemDbgInitHook(VOID)
STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semID)
STATIC INLINE VOID OsSemInfoGetFullDataHook(VOID)
STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 timeout)
设置事件阻塞掩码,即设置任务的等待事件.
STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask)
清除事件阻塞掩码,即任务不再等待任何事件.
UINT32(* wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout)
任务等待
VOID(* wake)(LosTaskCB *taskCB)
任务唤醒